SegmentControl
Радио-группа с единственным выбором, оформленная как сегментированный контрол. Подходит для переключения режимов отображения, фильтров с малым числом значений и компактных табов на плотных поверхностях. Поддерживает controlled и uncontrolled режим, клавиатурную навигацию (Arrow/Home/End с пропуском disabled), иконки, счётчики и режим полной ширины.
Когда использовать
- Когда вариантов от 2 до 5 и все они одновременно видимы на экране.
- Для переключения режимов отображения (list/grid/kanban, day/week/month).
- Для компактных фильтров с взаимоисключающим выбором.
Когда не нужен SegmentControl:
- Вариантов больше 5:
- используйте
TabsилиSelect.
- используйте
- Допускается множественный выбор:
- используйте чекбоксы или
ToggleGroup.
- используйте чекбоксы или
- Выбор приводит к загрузке тяжёлого контента и нужны отдельные урлы:
- используйте
Tabs.
- используйте
Анатомия
Size (default m)
Размерный ряд: s / m / l — стандартные плотности.
Width (default auto)
auto— ширина по контенту.full— растягивает контейнер на всю ширину родителя, сегменты делят ширину поровну. Уместен в формах и фильтрах с фиксированной шириной поля.
Outline (default false)
Булевый флаг — добавляет обводку контейнеру. Используется на «лёгких» поверхностях, где контрол должен явно отделяться от фона.
Segment slots
Каждый элемент items[i] собирается из:
label— текст сегмента.icon— иконка сiconPosition: 'before' | 'after'.counter— счётчик послеlabel.
Дополнительно:
- Сегмент может быть icon-only (без
label). - Отдельный сегмент можно сделать
disabled— клавиатурная навигация его пропускает.
Установка
pnpm add @cloud-ru/ds-segment-control
import { SegmentControl } from '@cloud-ru/ds-segment-control'
Примеры использования
1. Базовый сценарий
tsx
import { SegmentControl } from '@cloud-ru/ds-segment-control';
export function Basic() {
return (
<SegmentControl
defaultValue='overview'
items={[
{ value: 'overview', label: 'Overview' },
{ value: 'analytics', label: 'Analytics' },
{ value: 'reports', label: 'Reports' },
]}
/>
);
}2. Все размеры
tsx
import { SegmentControl } from '@cloud-ru/ds-segment-control';
const items = [
{ value: 'one', label: 'One' },
{ value: 'two', label: 'Two' },
{ value: 'three', label: 'Three' },
];
export function Sizes() {
return (
<div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'center' }}>
<SegmentControl size='s' defaultValue='one' items={items} />
<SegmentControl size='m' defaultValue='one' items={items} />
<SegmentControl size='l' defaultValue='one' items={items} />
</div>
);
}3. С иконками и icon-only
tsx
import { HomeSVG, PlusSVG, SettingsSVG } from '@cloud-ru/ds-icons/interface/system';
import { SegmentControl } from '@cloud-ru/ds-segment-control';
export function WithIcons() {
return (
<div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'center' }}>
<SegmentControl
defaultValue='home'
items={[
{ value: 'home', label: 'Home', icon: <HomeSVG /> },
{ value: 'settings', label: 'Settings', icon: <SettingsSVG /> },
{ value: 'add', label: 'Add', icon: <PlusSVG /> },
]}
/>
<SegmentControl
defaultValue='home'
items={[
{ value: 'home', icon: <HomeSVG /> },
{ value: 'settings', icon: <SettingsSVG /> },
{ value: 'add', icon: <PlusSVG /> },
]}
/>
</div>
);
}4. Со счётчиком
tsx
import { SegmentControl } from '@cloud-ru/ds-segment-control';
export function WithCounter() {
return (
<SegmentControl
defaultValue='inbox'
items={[
{ value: 'inbox', label: 'Inbox', counter: 12 },
{ value: 'drafts', label: 'Drafts', counter: 3 },
{ value: 'archive', label: 'Archive' },
]}
/>
);
}5. Полная ширина и outline
tsx
import { SegmentControl } from '@cloud-ru/ds-segment-control';
export function FullWidth() {
return (
<div style={{ width: 480, maxWidth: '100%' }}>
<SegmentControl
width='full'
outline
defaultValue='day'
items={[
{ value: 'day', label: 'Day' },
{ value: 'week', label: 'Week' },
{ value: 'month', label: 'Month' },
{ value: 'year', label: 'Year' },
]}
/>
</div>
);
}6. Disabled сегмент
tsx
import { SegmentControl } from '@cloud-ru/ds-segment-control';
export function DisabledSegment() {
return (
<SegmentControl
defaultValue='one'
items={[
{ value: 'one', label: 'One' },
{ value: 'two', label: 'Two', disabled: true },
{ value: 'three', label: 'Three' },
]}
/>
);
}7. Controlled с useState
Selected: list
tsx
import { SegmentControl } from '@cloud-ru/ds-segment-control';
import { useState } from 'react';
export function Controlled() {
const [view, setView] = useState<'list' | 'grid' | 'kanban'>('list');
return (
<div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'center' }}>
<SegmentControl
value={view}
onChange={setView}
items={[
{ value: 'list', label: 'List' },
{ value: 'grid', label: 'Grid' },
{ value: 'kanban', label: 'Kanban' },
]}
/>
<span>Selected: {view}</span>
</div>
);
}Props
Types
Props
SegmentControlProps| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
className | string | — | no | CSS-класс контейнера. |
data-test-id | string | — | no | |
defaultValue | IdType | — | no | ID выбранного по умолчанию сегмента (uncontrolled). |
items | Segment<Value>[] | — | yes | Набор сегментов. |
name | string | — | no | Имя поля (hidden input для формы). |
onChange | ((value: Value) => void) | — | no | Колбек смены выбранного сегмента. |
outline | boolean | — | no | Обводка. |
size | "l" | "m" | "s" | m | no | Размер компонента. |
value | IdType | — | no | Value выбранного сегмента. |
width | "auto" | "full" | auto | no | Управление шириной компонента. |