Компонент Slider библиотеки Radix UI построен по композиционной архитектуре. Вместо одного монолитного компонента используются несколько низкоуровневых примитивов, каждый из которых отвечает за отдельную часть интерфейса и поведения.
Базовыми элементами структуры являются:
Такая архитектура обеспечивает:
Типичная структура выглядит следующим образом:
import * as Slider from '@radix-ui/react-slider';
<Slider.Root defaultValue={[50]} max={100} step={1}>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb />
</Slider.Root>
Каждый примитив играет собственную роль в построении интерфейса.
Root — основной контейнер компонента слайдера. В нем сосредоточена вся логика управления значением, обработка пользовательских событий, а также взаимодействие между внутренними элементами.
Root:
Фактически Root выступает контроллером всей системы Slider.
<Slider.Root defaultValue={[30]} max={100} step={1}>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb />
</Slider.Root>
Root принимает массив значений, поскольку компонент поддерживает несколько ползунков.
Пример диапазонного слайдера:
<Slider.Root defaultValue={[20, 80]} max={100}>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb />
<Slider.Thumb />
</Slider.Root>
Начальное значение слайдера.
defaultValue={[50]}
Для диапазонного слайдера:
defaultValue={[25, 75]}
Это неконтролируемое состояние.
Контролируемое значение.
const [value, setValue] = useState([40]);
<Slider.Root value={value} onValueCha nge={setValue}>
Теперь управление полностью осуществляется через состояние React.
Минимальное значение шкалы.
min={0}
Максимальное значение шкалы.
max={100}
Шаг изменения значения.
step={5}
Это означает:
0 → 5 → 10 → 15 → 20
Ориентация слайдера.
orientation="horizontal"
или
orientation="vertical"
Вертикальный вариант часто используется для:
Отключает взаимодействие.
disabled
Срабатывает при каждом изменении значения.
onValueCha nge={(value) => console.log(value)}
Вызывается после завершения взаимодействия (например, после отпускания мыши).
onValueCom mit={(value) => save(value)}
Это удобно для:
Root автоматически обеспечивает управление клавиатурой:
| Клавиша | Действие |
|---|---|
| ArrowRight / ArrowUp | увеличить значение |
| ArrowLeft / ArrowDown | уменьшить |
| PageUp | большой шаг вверх |
| PageDown | большой шаг вниз |
| Home | минимальное значение |
| End | максимальное значение |
Это важная часть доступности интерфейса.
Track представляет собой визуальную шкалу, по которой перемещается ползунок.
Он выполняет роль:
Track не управляет логикой, а лишь отображает структуру.
<Slider.Track>
<Slider.Range />
</Slider.Track>
Track всегда содержит Range.
.sliderTrack {
position: relative;
height: 4px;
background: #ddd;
border-radius: 2px;
}
Использование:
<Slider.Track className="sliderTrack">
<Slider.Range />
</Slider.Track>
.sliderTrackVertical {
width: 4px;
height: 200px;
}
Track автоматически меняет направление в зависимости от
orientation.
Track реагирует на клик.
Когда пользователь кликает на трек:
Это поведение реализовано внутри Root.
Range отображает активную часть шкалы.
В одноползунковом слайдере Range показывает участок:
[начало шкалы → значение]
В диапазонном:
[value1 → value2]
Range всегда располагается внутри Track.
<Slider.Track>
<Slider.Range />
</Slider.Track>
.sliderRange {
position: absolute;
height: 100%;
background: #3b82f6;
border-radius: 999px;
}
Использование:
<Slider.Range className="sliderRange" />
Range не требует ручного управления стилями left/right.
Radix автоматически вычисляет:
На основе:
Если используется два ползунка:
Thumb 1 -------- Thumb 2
Range будет отображать участок между ними.
Это удобно для:
Thumb — интерактивный элемент, который пользователь перемещает для изменения значения.
Он отвечает за:
<Slider.Thumb />
В диапазонном слайдере:
<Slider.Thumb />
<Slider.Thumb />
Количество Thumb должно соответствовать количеству значений.
Пример:
.sliderThumb {
width: 20px;
height: 20px;
background: white;
border: 2px solid #3b82f6;
border-radius: 50%;
}
Использование:
<Slider.Thumb className="sliderThumb" />
Radix добавляет состояния через атрибуты:
[data-state]
Возможные значения:
activeinactiveТакже используется:
:focus-visible
Пример:
.sliderThumb:focus-visible {
outline: 3px solid #93c5fd;
}
Thumb реагирует на:
Radix автоматически:
Для диапазонных слайдеров существует правило:
Thumb1 ≤ Thumb2
Radix предотвращает пересечение ползунков.
Это особенно важно для:
import * as Slider from '@radix-ui/react-slider';
export default function PriceSlider() {
return (
<Slider.Root
className="sliderRoot"
defaultValue={[20, 80]}
min={0}
max={100}
step={1}
>
<Slider.Track className="sliderTrack">
<Slider.Range className="sliderRange" />
</Slider.Track>
<Slider.Thumb className="sliderThumb" />
<Slider.Thumb className="sliderThumb" />
</Slider.Root>
);
}
.sliderRoot {
position: relative;
display: flex;
align-items: center;
width: 300px;
}
.sliderTrack {
position: relative;
flex-grow: 1;
height: 4px;
background: #e5e7eb;
}
.sliderRange {
position: absolute;
height: 100%;
background: #2563eb;
}
.sliderThumb {
width: 18px;
height: 18px;
background: white;
border: 2px solid #2563eb;
border-radius: 50%;
}
Работа компонентов Slider строится на внутреннем контексте.
Связь выглядит следующим образом:
Root
├── Track
│ └── Range
└── Thumb
Root передает:
Track и Range используют данные для отображения, а Thumb — для взаимодействия.
Для диапазонных слайдеров можно задать:
minStepsBetweenThumbs
<Slider.Root
defaultValue={[20, 40]}
minStepsBetweenThumbs={5}
>
Это предотвращает слишком близкое расположение ползунков.
<Slider.Root orientation="vertical">
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb />
</Slider.Root>
CSS:
.sliderRoot {
height: 200px;
width: 20px;
}
Slider можно связать с формами:
const [value, setValue] = useState([50]);
<input type="hidden" value={value[0]} name="volume" />
Это позволяет отправлять данные через HTML-формы.
Компонент Slider в Radix UI соответствует стандартам ARIA.
Thumb автоматически получает:
role="slider"
Также устанавливаются:
aria-valuemin
aria-valuemax
aria-valuenow
aria-orientation
Это обеспечивает корректную работу:
Использование примитивов Root, Track, Range и Thumb обеспечивает:
Гибкость
Можно построить любой дизайн.
Контроль
Каждый элемент полностью управляется разработчиком.
Доступность
ARIA реализована по умолчанию.
Масштабируемость
Поддержка:
Такой подход делает Slider одним из самых гибких компонентов в экосистеме Radix UI.