FieldSlider

Поле для непрерывной/дискретной шкалы. Связывает текстовый input (наверху) и slider (@cloud-ru/ds-slider) — изменение в любом синхронизирует второй. По умолчанию ввод в input снэпит к ближайшей точке шкалы; режим unbindInputFromMarks отключает это.

Когда использовать

  • Громкость, яркость, прозрачность — диапазоны без жёстких меток.
  • Качество сжатия, уровень детализации — снэп к набору меток (marks + step={null}).
  • Read-only прогресс/использование (readonly) — отображает значение без интеракции.

Анатомия

Size (default m)

ЗначениеКогда
sInline-формы и таблицы
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)
unbindInputFromMarkstrue — текстовый 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'

Примеры использования

С метками

С меткамиstep=null + marks — ввод снэпит к ближайшей метке.
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

Кастомный formattertextInputFormatter форматирует значение в input.
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 (диапазон)

Range (диапазон)range={true} даёт две ручки. Текстовое поле в этом режиме readonly и показывает min – max.
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

PropsFieldSliderProps
PropTypeDefaultRequiredDescription
autoFocusbooleannoАвтофокус. На mobile выключается адаптивно (см. `layoutPresets`)
backgroundbooleantruenoФон поля (acrylic)
captionstringnoВторичная подпись справа
classNamestringnoCSS-класс CSS-класс корня `FieldDecorator`
data-test-idstringno
defaultValueSliderValuenoНачальное значение (uncontrolled-режим). По умолчанию `min` (или `[min, max]` при `range`).
disabledbooleannoПоле выключено
errorstringnoОшибка (приоритетнее `hint`; форсит `validationState=error`)
fieldClassNamestringnoCSS-класс оболочки поля
hintstringnoПодсказка
idstringnoHTML id
innerRefRef<HTMLDivElement>noRef на корневой DOM-элемент
labelstringnoЗаголовок
labelForstringnoHTML-атрибут `for` для `<label>`
labelTooltipQuestionTooltipPropsnoПодсказка (question-tooltip) у заголовка
layoutPresetsPartial<Record<LayoutType, Partial<{ autoFocus: boolean; }>>>noПереопределение адаптивных дефолтов по раскладке. Участвует `autoFocus`: на mobile он выключен (открывает клавиатуру без действия). Вернуть на mobile — `layoutPresets={{ mobile: { autoFocus: true } }}`.
lengthFieldLengthnoСчётчик длины `current/max`
marksRecord<string | number, ReactNode | MarkObj>noМетки на шкале
marksEqualSpacingbooleanfalsenoРавномерно распределять метки по шкале при нелинейных значениях (например `1 2 4 8 16 32` — равные промежутки вместо логарифмических).
maxnumberyesМаксимум
minnumberyesМинимум
namestringnoHTML name
onBlur((event: FocusEvent<HTMLInputElement, Element>) => void)noКолбек блюра
onChange((value: SliderValue) => void)noКолбек смены значения
onCopyButtonClick(() => void)noКолбек после успешного копирования значения.
onFocus((event: FocusEvent<HTMLInputElement, Element>) => void)noКолбек фокуса
postfixReactNodenoПроизвольный постфикс
postfixIconReactElement<any, string | JSXElementConstructor<any>>noИконка-постфикс справа от текстового поля
prefixReactNodenoПроизвольный префикс
rangebooleanfalsenoДиапазон с двумя ручками. Текстовое поле в этом режиме `readonly` и показывает значение как `min – max`.
readonlybooleannoТолько для чтения
requiredbooleannoПоказать знак обязательности `*`
showCopyButtonbooleantruenoПоказывать кнопку копирования значения (видна в readonly, при `!disabled`).
showHintIconbooleannoОтображение статус-иконки у подсказки (по умолчанию `true`)
showScaleBarbooleantruenoПоказывать линейку с метками
size"l" | "m" | "s"mnoРазмер
stepnumber | nullyesШаг приращения. `null` — снэп только к меткам.
textInputFormatterTextInputFormatternoФорматирование значения в текстовом поле
unbindInputFromMarksbooleanfalsenoЕсли `true` — текстовое поле принимает любые числа в диапазоне `min..max`, не снэпя к меткам.
validationState"default" | "error" | "success" | "warning"defaultnoСостояние валидации
valueSliderValuenoЗначение (число или диапазон при `range`; controlled-режим)

Types

FieldSliderProps

Storybook

Figma