Tabs
Вкладки з клавіатурною навігацією, слотами панелей і опційною синхронізацією з URL.
Дві форми: underline для розділення вмісту на сторінці та pills для
перемикача вигляду. Успадковану реалізацію переписано на токени: іконки
там були рядками-класами Font Awesome, тут — слоти tab-<id>.
Проп size додає компактні вкладки (sm) для панелей інструментів і
вкладок усередині картки — на дотику зону 45×45 добудовує невидимий
::after, тож кнопки вкладок лишилися щільними навіть на телефоні.
Приклад
Загальні показники об'єкта.
Щільний список.
Метадані запису.
Остання зміна: —
Синхронізація з URL
Передайте queryParam="tab" — активна вкладка читається з ?tab= і
пишеться туди через router.replace. Для вкладки за замовчуванням
параметр НЕ пишеться: URL залишається чистим. Кнопки «Назад/Вперед»
перемикають вкладки, як сторінки.
Усі шляхи зміни вкладки проходять через одне місце, тож стан не розходиться:
- вкладка з URL доходить до
v-model(update:modelValue), але не викликаєchange— це не дія користувача; - «Назад/Вперед» дає і
update:modelValue, іchange; - зміна
v-modelзгори (кнопка «Далі», перехід до поля з помилкою) теж пише параметр у URL — перезавантаження не поверне стару вкладку.
Параметр читається після монтування, а не під час рендеру.
Прередерена сторінка не знає про ?tab=, і читання до гідрації давало
розбіжність: стара вкладка лишалась з активними класами поруч із новою.
Роутер компонент бере з застосунку, а не імпортом vue-router: без
встановленого роутера queryParam просто нічого не синхронізує.
Вертикальні вкладки
orientation="vertical" ставить список стовпчиком ліворуч від панелі —
для сторінок налаштувань із багатьма розділами. Індикатор ковзає по
вертикалі, клавіатура перемикає ↑/↓. На вузькому екрані поверніть
горизонтальні вкладки прив'язкою пропа.
Ім'я, фото й контактна пошта.
API
Props
| Назва | Тип | Типово | Опис |
|---|---|---|---|
tabs* | TabItem[] | — | Панелі вкладок. |
modelValue | string | undefined | Активна вкладка. Використовуйте через `v-model`. |
variant | underlinepills | "underline" | Вигляд. `underline` — класичні вкладки з лінією, `pills` — сегментний перемикач (фонова підкладка, активна сегмента «піднята»). |
size | smmd | "md" | Висота кнопок вкладок. `sm` — для вкладок усередині панелі інструментів чи картки; на дотику зону 45×45 дає невидимий ::after. |
orientation | horizontalvertical | "horizontal" | Розташування списку. `vertical` ставить вкладки стовпчиком ліворуч від панелі — для сторінок налаштувань із багатьма розділами; клавіатура тоді перемикає стрілками ↑/↓, а не ←/→. |
queryParam | string | undefined | Назва query-параметра, з яким синхронізується активна вкладка. Напр. `"tab"` — стан читається з `?tab=` після монтування і пишеться туди через `router.replace`. Потрібен лише для вкладок, що мають переживати перезавантаження сторінки. Без встановленого роутера нічого не синхронізує. |
ariaLabel | string | "Вкладки" | Доступна назва для `role="tablist"`. |
Події
| Назва | Payload | Опис |
|---|---|---|
update:modelValue | [value: string] | Новий активний id — зокрема відновлений з URL чи виправлений замість вимкненої вкладки. Використовуйте через `v-model`. |
change | [id: string] | Користувач перемкнув вкладку — клік, клавіатура або «Назад/Вперед» у браузері. Відновлення з URL і зміна v-model згори його не викликають. |
Слоти
| Назва | Опис |
|---|---|
default | Вміст активної панелі, якщо не задано слот `panel-<id>`. |
Коли використовувати
Коли вміст не вміщується без втрати контексту: налаштування об'єкта, вкладки «Огляд / Журнал», перемикач щільності списку.
Коли НЕ використовувати
Якщо панелі — кроки однієї форми, потрібен Stepper, а не вкладки: вкладки нічого не говорять про порядок і прогрес.
Не ховайте за вкладками те, що користувач має порівнювати одночасно.
Доступність
role="tablist" → role="tab" → role="tabpanel" з aria-selected,
aria-controls і aria-labelledby. Roving tabindex: в обході Tab — лише
активна вкладка, стрілки (←/→, у вертикальних — ↑/↓) перемикають і
одразу активують панель; деактивовані вкладки пропускаються, а не
зупиняють обхід. Список оголошує aria-orientation.
Панель має tabindex="0": без жодного фокусованого елемента (лише текст)
вона інакше недосяжна з клавіатури — Tab з вкладки перестрибував би її.
Коли вкладки не вміщуються, список гортається вбік, і фокус — стрілками чи Tab — сам докручує вкладку в поле зору цілою. Браузер докручує лише вкладку, сховану повністю; частково видиму він лишав обрізаною разом із кільцем фокуса. Клік і тап список не зсувають: вкладка не тікає з-під пальця.
Ні кільце фокуса крайньої вкладки, ні невидима зона дотику кнопки (45×45) не обрізаються контейнером прокрутки: він має внутрішні відступи під них (на coarse-вказівнику — вищі), а від'ємний марджин лишає розкладку як була. Індикатор стежить за розміром кожної кнопки, тож довантажений веб-шрифт чи лічильник у слоті не лишають його під старою шириною.
Слот tab-<id> налаштовує вміст кнопки — наприклад, додає іконку або
лічильник. Саму кнопку, id, ролі та keyboard handlers завжди рендерить
UiTabs. Якщо старий слот повертав власний <button>, залиште тільки його
внутрішню розмітку.