Для последовательного процесса с шагами и прогрессом подойдёт CdsSteps, а для выбора одного значения в форме — CdsButtonToggle.
Анатомия
Табы состоят из панели и контентной части: при табах из items контентная часть рендерится автоматически, при ручной разметке CdsTabsView компонуется рядом. Панель — это контейнер с табами-кнопками; выбранный таб подсвечивает подвижная подложка-слайдер.
Вариации
Табы и контент
Разделы объявляются компонентами CdsTab в слоте по умолчанию, контент — компонентами CdsTabsViewItem внутри CdsTabsView. Пропы value связывают таб с его контентом, а общий v-model синхронизирует панель и контентную часть.
Табы из массива
Передайте в items массив строк или объектов { text, value } — табы и контентная часть отрендерятся автоматически. Контент раздела задают слоты item.{value}, подпись таба — слоты tab.{value}.
Выравнивание
Проп align прижимает табы к началу панели (по умолчанию), центру или концу.
Компоновка
Проп grow растягивает табы на всю ширину панели — каждый забирает равную долю свободного места.
Проп fixed-tabs тоже выравнивает ширину табов, но ограничивает её 300px и центрирует группу.
Проп direction="vertical" разворачивает панель в столбец — удобно для настроек и разделов с длинным списком. Контентная часть ставится рядом обычным flex-рядом.
Иконки
Таб принимает те же пропы контента, что и кнопка: prepend-icon и append-icon добавляют иконку рядом с текстом, icon оставляет только её. У таба-иконки не забудьте aria-label — без текста он остаётся единственным названием раздела.
Проп stacked ставит иконку над текстом — таб становится выше и заметнее. Такая компоновка хорошо работает с align="center" в мобильных сценариях.
Состояния
Проп disabled выключает таб, loading показывает индикатор загрузки вместо контента.
Цвета
Табы принимают цветовые алиасы палитры (neutral, red, green, cyan, purple…) или любой CSS-цвет. Проп color красит текст табов, active-color — подложку выбранного таба, bg-color — фон всей панели, base-color — фон невыбранных табов.
Прокрутка
Когда табы не помещаются в панель, она прокручивается. Проп show-arrows добавляет стрелки прокрутки, center-active держит выбранный таб по центру панели.
Слайдер
Проп slider-transition выбирает анимацию подложки под выбранным табом: shift (по умолчанию) сдвигает её к новому табу, grow выращивает на месте, fade плавно проявляет. Длительность настраивается через slider-transition-duration, а hide-slider убирает подложку совсем.
Слоты
Слоты заменяют автоматический рендер из items, когда нужна своя разметка:
| Слот | Описание |
|---|---|
default | Свои CdsTab, когда items не задан |
tab, tab.{value} | Таб для элемента items: общий и для конкретного значения |
item, item.{value} | Контент раздела: общий и для конкретного значения |
view | Дополнительный контент внутри CdsTabsView |
prev, next | Свои стрелки прокрутки |
Слоты tab и item получают элемент массива и заменяют компонент целиком — верните из них CdsTab и CdsTabsViewItem со своим value. Слоты tab.{value} и item.{value} заменяют только контент.
Рекомендации
Сценарии использования
Разделы карточки
Классические табы: карточка товара с разделами и общим v-model. Счётчик отзывов — CdsBadge с пропом inline прямо в слоте таба.
Фильтр списка
Табы работают и без контентной части: v-model хранит выбранный статус, а список фильтруется по нему через computed. Контент один — меняется только выборка.
Ленивая загрузка разделов
Тяжёлый раздел загружается при первом открытии: watch по v-model запускает запрос, на время загрузки контент подменяет CdsSkeletonLoader, а уже загруженные разделы открываются мгновенно.
Разделы в меню «Ещё»
Когда разделов больше, чем помещается в панель, редкие прячутся в CdsMenu, а его активатор — обычный таб «Ещё» в той же панели. Клик по «Ещё» сразу показывает первый раздел из меню, выбранный пункт занимает место первого видимого таба (вытесненный уходит в меню), а если закрыть меню без выбора — панель и контент вернутся к текущему разделу.
API
CdsTabs
Пропсы
| Имя | Тип | По умолчанию | Описание |
|---|---|---|---|
activeColor | string | undefined | — | Цвет компонента, когда он находится в активном состоянии |
align | "title" | "start" | "end" | "center" | undefined | 'start' | Выравнивание вкладок внутри полосы |
baseColor | string | undefined | — | Цвет неактивного компонента |
bgColor | string | undefined | — | Цвет фона компонента |
centerActive | boolean | undefined | — | Принудительно выравнивает активный компонент по центру. |
color | string | undefined | — | Цвет компонента |
contentClass | any | — | Добавляет классы к контейнеру slide group |
contentStyle | any | — | Добавляет inline-стили к контейнеру slide group |
direction | "horizontal" | "vertical" | undefined | 'horizontal' | Переключение между горизонтальным или вертикальным отображением. |
disabled | boolean | null | undefined | null | Заблокированное состояние |
fixedTabs | boolean | undefined | — | Делает все вкладки одинаковой ширины независимо от длины заголовка |
grow | boolean | undefined | — | Растягивает вкладки на всю доступную ширину контейнера |
height | string | number | undefined | — | Высота полосы вкладок. Число — в пикселях, строка — с любой CSS-единицей |
hideSlider | boolean | undefined | — | Скрывает подчёркивающий индикатор активной вкладки |
inset | boolean | undefined | — | Вариант оформления с подложкой: активная вкладка выделяется залитой «таблеткой», а не подчёркиванием |
insetPadding | string | number | undefined | — | Внутренний отступ подложки в режиме inset. Число — в пикселях, строка — с любой CSS-единицей |
insetRadius | string | number | undefined | — | Радиус скругления подложки в режиме inset. Число — в пикселях, строка — с любой CSS-единицей |
items | readonly TabItem[] | undefined | [] | Список вкладок. Строка или число — заголовок, объект — вкладка с произвольными пропсами CdsTab |
mandatory | boolean | "force" | undefined | 'force' | Обязательный выбор хотя бы одного элемента |
max | number | undefined | — | Максимальное количество выбираемых элементов |
mobile | boolean | null | undefined | null | Определяет режим отображения компонента: Если значение равно true, компонент будет отображаться в режиме для Mobile. Если значение равно false, компонент будет отображаться в режиме для Desktop. Если значение равно null, режим будет зависеть от текущего Breakpoint. |
mobileBreakpoint | number | "xs" | "sm" | "md" | "lg" | "xl" | undefined | — | Указывает точку преломления, при которой отображение будет переключаться в мобильный режим. Может быть числом (например, 600) или строкой, соответствующей одному из предопределенных Breakpoint (например, 'xs', 'sm', 'md', 'lg', 'xl'). |
modelValue | any | — | Значение выбранных элементов группы |
multiple | boolean | undefined | — | Разрешить множественный выбор |
nextIcon | IconValue | undefined | 'chevron-right' | Иконка для кнопки "следующий". |
prevIcon | IconValue | undefined | 'chevron-left' | Иконка для кнопки "предыдущий". |
required | boolean | "force" | undefined | 'force' | Обязательный выбор хотя бы одного элемента |
scrollToActive | boolean | undefined | true | Если true, то при изменении активного компонента, контейнер будет прокручиваться так, чтобы он был виден. |
selectedClass | string | undefined | 'cds-tabs--selected' | CSS класс для выбранного состояния |
showArrows | string | boolean | undefined | — | Изменяет настройки отображения стрелок: По умолчанию стрелки всегда отображаются на Desktop устройствах при переполнении контейнера.<br /> При переполнении контейнера на мобильных устройствах стрелки по умолчанию не отображаются.<br /> Значение «true» для параметра «show-arrows» позволяет отображать эти стрелки на мобильных устройствах при переполнении контейнера.<br /> Значение «desktop» всегда отображает стрелки на настольных устройствах, а значение «mobile» — на мобильных устройствах.<br /> Значение «always» всегда отображает стрелки как на настольных, так и на мобильных устройствах.<br /> Используйте значение «never», чтобы отключить отображение стрелок. |
sliderTransition | "shift" | "grow" | "fade" | undefined | — | Анимация подчёркивающего индикатора активной вкладки |
sliderTransitionDuration | string | number | undefined | — | Длительность анимации индикатора в миллисекундах. 0 выключает перелёт; по умолчанию — по шкале движения |
spaced | "both" | "start" | "end" | undefined | — | Разводит слоты prepend и append к краям кнопки. |
stacked | boolean | undefined | — | Располагает иконку и заголовок вкладки вертикально — иконка над текстом |
tag | string | JSXComponent<any> | undefined | 'div' | Пользовательский HTML-тег для отображения |
textColor | string | undefined | — | Цвет текста компонента |
События
| Имя | Тип | Описание |
|---|---|---|
update:modelValue | [value: unknown] | Сработало при переключении вкладки. Передаёт значение новой активной вкладки |
Слоты
| Имя | Тип | Описание |
|---|---|---|
default | any | Вкладки и содержимое, если они объявляются вручную вместо пропа items |
item | CdsTabsSlot<any> | Шаблон содержимого вкладки. В параметрах — элемент из items |
next | any | Кнопка прокрутки полосы вкладок вперёд |
prev | any | Кнопка прокрутки полосы вкладок назад |
tab | CdsTabsSlot<any> | Шаблон заголовка вкладки. В параметрах — элемент из items |
view | any | Область содержимого вкладок целиком — заменяет автоматический CdsTabsView |
CdsTab
Пропсы
| Имя | Тип | По умолчанию | Описание |
|---|---|---|---|
activeColor | string | undefined | — | Цвет компонента, когда он находится в активном состоянии |
appearancedeprecated | "inverse" | "primary" | "secondary" | "tertiary" | "transparent" | undefined | — | Внешний вид компонента. Устарел: используйте variant и color |
appendIcon | IconValue | undefined | — | Иконка в слоте append после контента |
baseColor | string | undefined | — | Цвет неактивного компонента |
block | boolean | undefined | — | Растягивает кнопку на всю доступную ширину контейнера |
color | (string & {}) | "neutral" | "brand" | "accent" | "danger" | "inverse" | undefined | 'brand' | Цвет компонента: роль, алиас палитры, токен темы или CSS-цвет |
content | string | number | undefined | — | Контент, отображаемый в компоненте. |
direction | "horizontal" | "vertical" | undefined | 'horizontal' | Переключение между горизонтальным или вертикальным отображением. |
disabled | boolean | null | undefined | null | Заблокированное состояние |
exact | boolean | undefined | — | Если true, активное состояние будет применяться только при точном совпадении маршрута |
fixed | boolean | undefined | — | Фиксирует ширину вкладки, не давая ей растягиваться по длине заголовка |
height | string | number | undefined | — | Высота компонента |
hideSlider | boolean | undefined | — | Скрывает подчёркивающий индикатор активной вкладки |
href | string | undefined | — | Атрибут href для ссылки. Если указан, компонент будет вести себя как обычная ссылка |
icon | boolean | IconValue | undefined | — | Иконка, компонент будет отображаться в состоянии только иконки |
loading | string | boolean | undefined | — | Индикатор загрузки для компонента |
maxHeight | string | number | undefined | — | Максимальная высота компонента |
maxWidth | string | number | undefined | — | Максимальная ширина компонента |
minHeight | string | number | undefined | — | Минимальная высота компонента |
minWidth | string | number | undefined | — | Минимальная ширина компонента |
prependIcon | IconValue | undefined | — | Иконка в слоте prepend перед контентом |
readonly | boolean | null | undefined | null | Только для чтения |
replace | boolean | undefined | — | Если true, навигация по маршруту будет заменять текущую запись в истории вместо добавления новой |
selectedClass | string | undefined | 'cds-tab--selected' | CSS класс для выбранного состояния |
size | number | "xs" | "sm" | "md" | "lg" | "xl" | undefined | 'md' | Размер компонента |
sliderTransition | "shift" | "grow" | "fade" | undefined | — | Анимация подчёркивающего индикатора активной вкладки |
sliderTransitionDuration | string | number | undefined | — | Длительность анимации индикатора в миллисекундах. 0 выключает перелёт; по умолчанию — по шкале движения |
spaced | "both" | "start" | "end" | undefined | — | Разводит слоты prepend и append к краям кнопки. |
stacked | boolean | undefined | — | Располагает иконки и контент вертикально — иконка над текстом |
tag | string | JSXComponent<any> | undefined | 'button' | Пользовательский HTML-тег для отображения |
text | string | number | undefined | — | Текст, отображаемый в компоненте. |
theme | string | undefined | — | Тема компонента |
to | LinkTo | undefined | — | Маршрут назначения или объект для RouterLink. Если указан, компонент будет вести себя как RouterLink |
value | any | — | Значение компонента в группе |
variant | "solid" | "soft" | "outline" | "surface" | "ghost" | undefined | 'solid' | Вид компонента: solid, soft, outline, surface, ghost |
width | string | number | undefined | — | Ширина компонента |
Слоты
| Имя | Тип | Описание |
|---|---|---|
append | any | Контент после текста |
default | any | Контент внутри кнопки |
loader | any | Загрузочный индикатор |
prepend | any | Контент перед текстом |
CdsTabsView
Пропсы
| Имя | Тип | По умолчанию | Описание |
|---|---|---|---|
crossfade | boolean | undefined | — | Слайды сменяются плавным перекрестным затуханием вместо сдвига |
direction | "horizontal" | "vertical" | undefined | 'horizontal' | Переключение между горизонтальным или вертикальным отображением. |
disabled | boolean | null | undefined | null | Заблокированное состояние |
max | number | undefined | — | Максимальное количество выбираемых элементов |
modelValue | any | — | Значение выбранных элементов группы |
multiple | boolean | undefined | — | Разрешить множественный выбор |
reverse | boolean | undefined | — | Инвертирует направление анимации перехода между слайдами |
selectedClass | string | undefined | — | CSS класс для выбранного состояния |
tag | string | JSXComponent<any> | undefined | 'div' | Пользовательский HTML-тег для отображения |
theme | string | undefined | — | Тема компонента |
transitionDuration | number | undefined | — | Длительность анимации перехода между слайдами в миллисекундах |
verticalArrows | boolean | "left" | "right" | undefined | — | Размещает стрелки навигации вертикально: 'left' или 'right' — сторона, true — сторона по умолчанию |
События
| Имя | Тип | Описание |
|---|---|---|
update:modelValue | [value: any] | Сработало при смене показанного содержимого. Передаёт значение новой активной вкладки |
Слоты
| Имя | Тип | Описание |
|---|---|---|
additional | { group: GroupProvide; } | Дополнительный контент поверх слайдов — например точки-индикаторы или собственная навигация |
default | { group: GroupProvide; } | Слайды. В параметрах — состояние группы для управления активным слайдом |
next | { props: ControlProps; } | Кнопка перехода к следующему слайду. В параметрах — готовые пропсы для своей кнопки |
prev | { props: ControlProps; } | Кнопка перехода к предыдущему слайду. В параметрах — готовые пропсы для своей кнопки |
CdsTabsViewItem
Пропсы
| Имя | Тип | По умолчанию | Описание |
|---|---|---|---|
disabled | boolean | null | undefined | null | Заблокированное состояние |
eager | boolean | undefined | — | Принудительно рендерит содержимое компонента при его использовании. Это полезно, если у вас есть контент, который не отображается в DOM, но который необходимо проиндексировать для SEO. |
reverseTransition | string | boolean | undefined | — | Переход при показе слайда в обратном направлении. Имя transition-компонента или false, чтобы отключить анимацию |
selectedClass | string | undefined | — | CSS класс для выбранного состояния |
transition | string | boolean | undefined | — | Переход при показе слайда в прямом направлении. Имя transition-компонента или false, чтобы отключить анимацию |
value | any | — | Значение компонента в группе |
Слоты
| Имя | Тип | Описание |
|---|---|---|
default | any | Контент слайда |