Skip to content

Commit b2f3a6a

Browse files
committed
refactor
1 parent 6a507d2 commit b2f3a6a

File tree

13 files changed

+421
-401
lines changed

13 files changed

+421
-401
lines changed

packages/slider/src/Component.tsx

Lines changed: 3 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -1,152 +1,13 @@
11
import React, { type FC, useEffect, useMemo, useRef } from 'react';
22
import cn from 'classnames';
3-
import noUiSlider, { API } from 'nouislider';
3+
import noUiSlider, { type API } from 'nouislider';
44

55
import { useSliderMarkers } from './hooks';
6+
import { type SliderProps } from './types';
67
import { createPipsConfig } from './utils';
78

89
import styles from './index.module.css';
910

10-
type SubRange = number | [number] | [number, number];
11-
type RangeOptions = {
12-
min: SubRange;
13-
max: SubRange;
14-
[key: string]: SubRange;
15-
};
16-
17-
type PipsType = -1 | 0 | 1 | 2;
18-
19-
export type Pips = {
20-
mode: 'range' | 'steps' | 'positions' | 'count' | 'values';
21-
values: number | number[];
22-
filter?: (value: number, type: PipsType) => PipsType;
23-
format?: {
24-
to: (value: number) => string | number;
25-
from?: (value: string) => number | false;
26-
};
27-
stepped?: boolean;
28-
};
29-
30-
export type SliderProps = {
31-
/**
32-
* Мин. допустимое число
33-
*/
34-
min?: number;
35-
36-
/**
37-
* Макс. допустимое число
38-
*/
39-
max?: number;
40-
41-
/**
42-
* Шаг (должен нацело делить отрезок между мин и макс)
43-
*/
44-
step?: number;
45-
46-
/**
47-
* Отображение подписей
48-
* https://refreshless.com/nouislider/pips/
49-
*/
50-
pips?: Pips;
51-
52-
/**
53-
* Настройка шагов
54-
* https://refreshless.com/nouislider/pips/#section-range
55-
*/
56-
range?: RangeOptions;
57-
58-
/**
59-
* Флаг точной привязки к range
60-
* https://refreshless.com/nouislider/examples/#section-skipping
61-
*/
62-
snap?: boolean;
63-
64-
/**
65-
* Значение слайдера
66-
*/
67-
value?: number;
68-
69-
/**
70-
* Второе значение слайдера (значение второго ползунка)
71-
* если передать ValueTo, то слайдер будет работать как range
72-
*/
73-
valueTo?: number;
74-
75-
/**
76-
* Заблокированное состояние
77-
*/
78-
disabled?: boolean;
79-
80-
/**
81-
* Дополнительный класс
82-
*/
83-
className?: string;
84-
85-
/**
86-
* Поведение ползунка
87-
*/
88-
behaviour?: 'unconstrained-tap' | 'tap';
89-
90-
/**
91-
* Размер
92-
* @description s, m deprecated, используйте вместо них 2, 4 соответственно
93-
*/
94-
size?: 's' | 'm' | 2 | 4;
95-
96-
/**
97-
* Включение/отключение отображения точек на слайдере
98-
* @default false
99-
*/
100-
dots?: boolean;
101-
102-
/**
103-
* Тип отображения точек на слайдере: 'step' - по шагу, 'custom' - произвольные
104-
* @default 'step'
105-
*/
106-
dotsSlider?: 'step' | 'custom';
107-
108-
/**
109-
* Массив значений для произвольного размещения точек
110-
*/
111-
customDots?: number[];
112-
113-
/**
114-
* Включение/отключение отображения чисел под точками
115-
* Действует на все точки кроме dotsSlider
116-
* @default true
117-
*/
118-
showNumbers?: boolean;
119-
120-
/**
121-
* Скрытие чисел только для кастомных точек
122-
* При hideCustomDotsNumbers=true числа скрываются только у customDots, остальные числа остаются видимыми
123-
* @default false
124-
*/
125-
hideCustomDotsNumbers?: boolean;
126-
127-
/**
128-
* Обработчик поля ввода
129-
*/
130-
onChange?: (payload: { value: number; valueTo?: number }) => void;
131-
132-
/**
133-
* @deprecated
134-
* Обработчик начала перетаскивания ползунка
135-
*/
136-
onStart?: () => void;
137-
138-
/**
139-
* Обработчик окончания перетаскивания ползунка
140-
* @description https://refreshless.com/nouislider/events-callbacks/#section-change
141-
*/
142-
onEnd?: () => void;
143-
144-
/**
145-
* Идентификатор для систем автоматизированного тестирования
146-
*/
147-
dataTestId?: string;
148-
};
149-
15011
export const SIZE_TO_CLASSNAME_MAP = {
15112
s: 'size-2',
15213
m: 'size-4',
@@ -311,12 +172,11 @@ export const Slider: FC<SliderProps> = ({
311172
}
312173
}, [onChange, hasValueTo, value, valueTo, createSlideHandler, updateMarkersState]);
313174

314-
// todo: переделать логику отображения цифр и точек
315175
return (
316176
<div
317177
className={cn(styles.component, className, styles[SIZE_TO_CLASSNAME_MAP[size]], {
318178
[styles.dotsDisabled]: !dots,
319-
// [styles.numbersDisabled]: dots && dotsSlider === 'custom' && !customDots?.length,
179+
[styles.numbersDisabled]: dots && dotsSlider === 'custom' && !customDots?.length,
320180
})}
321181
ref={sliderRef}
322182
data-test-id={dataTestId}

packages/slider/src/docs/description.mdx

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -220,41 +220,57 @@ render(() => {
220220
});
221221
```
222222

223-
### Кастомные точки и управление отображением
223+
### Точки
224224

225-
#### Типы отображения точек
226-
227-
Слайдер поддерживает два типа отображения точек:
228-
229-
- **`'step'`** - точки отображаются по шагу слайдера (по умолчанию)
230-
- **`'custom'`** - произвольное расположение точек
231-
232-
#### Произвольные точки
233-
234-
Можно задать произвольное расположение точек с помощью `dotsSlider='custom'` и `customDots`. В этом случае отображаются только точки в указанных позициях без чисел.
225+
Точки могут использоваться только с с высотой желоба равной 4рх. Точки могут несовпадать с подписями и шагом слайдера.
235226

236227
```jsx live
237228
render(() => {
238-
const [value, setValue] = React.useState(4);
229+
const [value1, setValue1] = React.useState(2.5);
230+
const [value2, setValue2] = React.useState(2.5);
239231

240-
const handleChange = ({ value }) => setValue(value);
232+
const handleChange1 = ({ value }) => setValue1(value);
233+
const handleChange2 = ({ value }) => setValue2(value);
241234

242235
return (
243236
<>
244-
<div>Value: {value}</div>
237+
<div>Value: {value1}</div>
245238
<br />
246239
<Slider
247240
min={1}
248-
max={8}
241+
max={10}
249242
step={0.5}
250-
value={value}
251-
onChange={handleChange}
243+
value={value1}
244+
onChange={handleChange1}
245+
size={4}
246+
dots
247+
dotsSlider='steps'
248+
showNumbers={false}
249+
pips={{
250+
mode: 'values',
251+
values: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
252+
}}
253+
/>
254+
<br />
255+
<br />
256+
<div>Value: {value2}</div>
257+
<br />
258+
<Slider
259+
min={1}
260+
max={7}
261+
step={0.5}
262+
value={value2}
263+
onChange={handleChange2}
252264
size={4}
253265
dots
254266
dotsSlider='custom'
255267
showNumbers={true}
268+
hideCustomDotsNumbers={true}
256269
customDots={[4, 5.5, 7]}
257-
pips={{ mode: 'values', values: [1, 2, 3, 5, 6] }}
270+
pips={{
271+
mode: 'values',
272+
values: [1, 2, 3, 4, 5, 6, 7]
273+
}}
258274
/>
259275
</>
260276
);

packages/slider/src/hooks/useSliderMarkers.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { MutableRefObject, useCallback, useEffect } from 'react';
2-
import { API } from 'nouislider';
1+
import { type MutableRefObject, useCallback, useEffect } from 'react';
2+
import { type API } from 'nouislider';
33

4-
import { SliderProps } from '../Component';
4+
import { type SliderProps } from '../types';
55
import { getMarkerValue, isMarkerCurrent, isMarkerPassed, updateMarkerAttributes } from '../utils';
66

77
export type SliderRef = MutableRefObject<(HTMLDivElement & { noUiSlider: API }) | null>;

packages/slider/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './Component';
2+
export * from './types';

packages/slider/src/types.ts

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
type SubRange = number | [number] | [number, number];
2+
type PipsType = -1 | 0 | 1 | 2;
3+
4+
interface RangeOptions {
5+
min: SubRange;
6+
max: SubRange;
7+
[key: string]: SubRange;
8+
};
9+
10+
export interface Pips {
11+
mode: 'range' | 'steps' | 'positions' | 'count' | 'values';
12+
values: number | number[];
13+
filter?: (value: number, type: PipsType) => PipsType;
14+
format?: {
15+
to: (value: number) => string | number;
16+
from?: (value: string) => number | false;
17+
};
18+
stepped?: boolean;
19+
};
20+
21+
export interface SliderProps {
22+
/**
23+
* Мин. допустимое число
24+
*/
25+
min?: number;
26+
27+
/**
28+
* Макс. допустимое число
29+
*/
30+
max?: number;
31+
32+
/**
33+
* Шаг (должен нацело делить отрезок между мин и макс)
34+
*/
35+
step?: number;
36+
37+
/**
38+
* Отображение подписей
39+
* https://refreshless.com/nouislider/pips/
40+
*/
41+
pips?: Pips;
42+
43+
/**
44+
* Настройка шагов
45+
* https://refreshless.com/nouislider/pips/#section-range
46+
*/
47+
range?: RangeOptions;
48+
49+
/**
50+
* Флаг точной привязки к range
51+
* https://refreshless.com/nouislider/examples/#section-skipping
52+
*/
53+
snap?: boolean;
54+
55+
/**
56+
* Значение слайдера
57+
*/
58+
value?: number;
59+
60+
/**
61+
* Второе значение слайдера (значение второго ползунка)
62+
* если передать ValueTo, то слайдер будет работать как range
63+
*/
64+
valueTo?: number;
65+
66+
/**
67+
* Заблокированное состояние
68+
*/
69+
disabled?: boolean;
70+
71+
/**
72+
* Дополнительный класс
73+
*/
74+
className?: string;
75+
76+
/**
77+
* Поведение ползунка
78+
*/
79+
behaviour?: 'unconstrained-tap' | 'tap';
80+
81+
/**
82+
* Размер
83+
* @description s, m deprecated, используйте вместо них 2, 4 соответственно
84+
*/
85+
size?: 's' | 'm' | 2 | 4;
86+
87+
/**
88+
* Включение/отключение отображения точек на слайдере
89+
* @default false
90+
*/
91+
dots?: boolean;
92+
93+
/**
94+
* Тип отображения точек на слайдере: 'step' - по шагу, 'custom' - произвольные
95+
* @default 'step'
96+
*/
97+
dotsSlider?: 'step' | 'custom';
98+
99+
/**
100+
* Массив значений для произвольного размещения точек
101+
*/
102+
customDots?: number[];
103+
104+
/**
105+
* Включение/отключение отображения чисел под точками
106+
* Действует на все точки кроме dotsSlider
107+
* @default true
108+
*/
109+
showNumbers?: boolean;
110+
111+
/**
112+
* Скрытие чисел только для кастомных точек
113+
* При hideCustomDotsNumbers=true числа скрываются только у customDots, остальные числа остаются видимыми
114+
* @default false
115+
*/
116+
hideCustomDotsNumbers?: boolean;
117+
118+
/**
119+
* Обработчик поля ввода
120+
*/
121+
onChange?: (payload: { value: number; valueTo?: number }) => void;
122+
123+
/**
124+
* @deprecated
125+
* Обработчик начала перетаскивания ползунка
126+
*/
127+
onStart?: () => void;
128+
129+
/**
130+
* Обработчик окончания перетаскивания ползунка
131+
* @description https://refreshless.com/nouislider/events-callbacks/#section-change
132+
*/
133+
onEnd?: () => void;
134+
135+
/**
136+
* Идентификатор для систем автоматизированного тестирования
137+
*/
138+
dataTestId?: string;
139+
};

0 commit comments

Comments
 (0)