FieldSlider
Поле для непрерывной/дискретной шкалы. Связывает текстовый input (наверху) и slider (@cloud-ru/ds-slider) — изменение в любом синхронизирует второй. По умолчанию ввод в input снэпит к ближайшей точке шкалы; режим unbindInputFromMarks отключает это.
Когда использовать
- Громкость, яркость, прозрачность — диапазоны без жёстких меток.
- Качество сжатия, уровень детализации — снэп к набору меток (
marks+step={null}). - Read-only прогресс/использование (
readonly) — отображает значение без интеракции.
Анатомия
Size (default m)
| Значение | Когда |
|---|---|
s | Inline-формы и таблицы |
m | Стандартные формы (по умолчанию) |
l | Лендинги, primary-формы |
ValidationState (default default)
Тонирует фон поля (acrylic) по Figma-модели и управляет иконкой подсказки. Проп error форсит error поверх любого значения. Иконка слева от подсказки появляется при showHintIcon.
default— нейтральный фон, нет валидации: без цвета и иконки (textTertiary).error— красная тонировка фона, поле не прошло валидацию.warning— жёлтая тонировка фона, предупреждение (ввод допустим).success— зелёная тонировка фона, подтверждение успешного ввода.
Поведение
| Проп | Поведение |
|---|---|
min / max / step | Обязательны. step={null} снэпит только к меткам |
marks | Метки на шкале: { 0: '0%', 50: '50%', 100: '100%' } или { 50: { label: 'half' } } |
showScaleBar | Скрывает метки на шкале без потери snap-логики (default true) |
unbindInputFromMarks | true — текстовый input принимает любые числа в min..max, не снэпя к меткам |
textInputFormatter | Форматирование значения в input’е (v => v + '%') |
prefix / postfix / postfixIcon | Дополнения справа/слева от значения |
Controlled vs uncontrolled
- Controlled — передаются
valueиonChange; значением владеет родитель. Ползунок и input синхронизируются через ваш state. - Uncontrolled — передаётся
defaultValue(начальное значение, по умолчаниюmin, либо[min, max]приrange). Компонент держит значение сам;onChangeостаётся доступным для наблюдения за изменениями.
Текстовый input принимает только числовой ввод: нечисловой keystroke отклоняется и не попадает в поле. Значение фиксируется (снэп к шкале/меткам и onChange) при потере фокуса (blur) или нажатии Enter.
Установка
pnpm add @cloud-ru/ds-fields
import { FieldSlider } from '@cloud-ru/ds-fields'
Примеры использования
С метками
tsx
import { FieldSlider } from '@cloud-ru/ds-fields';
import { useState } from 'react';
export function SliderWithMarks() {
const [value, setValue] = useState(25);
return (
<FieldSlider
label='Качество сжатия'
hint='Снэпит к ближайшей метке'
min={0}
max={100}
step={null}
marks={{ 0: '0', 25: '25', 50: '50', 75: '75', 100: '100' }}
value={value}
onChange={v => setValue(v as number)}
/>
);
}Кастомный formatter
tsx
import { FieldSlider } from '@cloud-ru/ds-fields';
import { useState } from 'react';
export function SliderWithFormatter() {
const [value, setValue] = useState(75);
return (
<FieldSlider
label='Громкость'
min={0}
max={100}
step={5}
postfix='%'
textInputFormatter={v => `${v} %`}
value={value}
onChange={v => setValue(v as number)}
/>
);
}Range (диапазон)
tsx
import { FieldSlider } from '@cloud-ru/ds-fields';
import { useState } from 'react';
export function SliderRange() {
const [value, setValue] = useState<number[]>([20, 80]);
return (
<FieldSlider
label='Диапазон цены'
hint='₽/мес. Текстовое поле в range-режиме только для чтения'
range
min={0}
max={100}
step={1}
postfix='₽'
value={value}
onChange={v => setValue(v as number[])}
/>
);
}Props
Types
Props
FieldSliderProps| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
autoFocus | boolean | — | no | Автофокус. На mobile выключается адаптивно (см. `layoutPresets`) |
background | boolean | true | no | Фон поля (acrylic) |
caption | string | — | no | Вторичная подпись справа |
className | string | — | no | CSS-класс CSS-класс корня `FieldDecorator` |
data-test-id | string | — | no | |
defaultValue | SliderValue | — | no | Начальное значение (uncontrolled-режим). По умолчанию `min` (или `[min, max]` при `range`). |
disabled | boolean | — | no | Поле выключено |
error | string | — | no | Ошибка (приоритетнее `hint`; форсит `validationState=error`) |
fieldClassName | string | — | no | CSS-класс оболочки поля |
hint | string | — | no | Подсказка |
id | string | — | no | HTML id |
innerRef | Ref<HTMLDivElement> | — | no | Ref на корневой DOM-элемент |
label | string | | no | Заголовок |
labelFor | string | — | no | HTML-атрибут `for` для `<label>` |
labelTooltip | QuestionTooltipProps | — | no | Подсказка (question-tooltip) у заголовка |
layoutPresets | Partial<Record<LayoutType, Partial<{ autoFocus: boolean; }>>> | — | no | Переопределение адаптивных дефолтов по раскладке. Участвует `autoFocus`: на mobile он выключен (открывает клавиатуру без действия). Вернуть на mobile — `layoutPresets={{ mobile: { autoFocus: true } }}`. |
length | FieldLength | — | no | Счётчик длины `current/max` |
marks | Record<string | number, ReactNode | MarkObj> | — | no | Метки на шкале |
marksEqualSpacing | boolean | false | no | Равномерно распределять метки по шкале при нелинейных значениях (например `1 2 4 8 16 32` — равные промежутки вместо логарифмических). |
max | number | — | yes | Максимум |
min | number | — | yes | Минимум |
name | string | — | no | HTML name |
onBlur | ((event: FocusEvent<HTMLInputElement, Element>) => void) | — | no | Колбек блюра |
onChange | ((value: SliderValue) => void) | — | no | Колбек смены значения |
onCopyButtonClick | (() => void) | — | no | Колбек после успешного копирования значения. |
onFocus | ((event: FocusEvent<HTMLInputElement, Element>) => void) | — | no | Колбек фокуса |
postfix | ReactNode | — | no | Произвольный постфикс |
postfixIcon | ReactElement<any, string | JSXElementConstructor<any>> | — | no | Иконка-постфикс справа от текстового поля |
prefix | ReactNode | — | no | Произвольный префикс |
range | boolean | false | no | Диапазон с двумя ручками. Текстовое поле в этом режиме `readonly` и показывает значение как `min – max`. |
readonly | boolean | — | no | Только для чтения |
required | boolean | — | no | Показать знак обязательности `*` |
showCopyButton | boolean | true | no | Показывать кнопку копирования значения (видна в readonly, при `!disabled`). |
showHintIcon | boolean | — | no | Отображение статус-иконки у подсказки (по умолчанию `true`) |
showScaleBar | boolean | true | no | Показывать линейку с метками |
size | "l" | "m" | "s" | m | no | Размер |
step | number | null | — | yes | Шаг приращения. `null` — снэп только к меткам. |
textInputFormatter | TextInputFormatter | — | no | Форматирование значения в текстовом поле |
unbindInputFromMarks | boolean | false | no | Если `true` — текстовое поле принимает любые числа в диапазоне `min..max`, не снэпя к меткам. |
validationState | "default" | "error" | "success" | "warning" | default | no | Состояние валидации |
value | SliderValue | — | no | Значение (число или диапазон при `range`; controlled-режим) |