GrTabsWithPanels

  • ядро
  • Навигация
  • API · 9 props

Берут, когда нужны и вкладки, и панели.

import { GrTabsWithPanels } from '@feugene/granularity/components/GrTabsWithPanels'

Обзор

Когда брать

  • нужны и вкладки, и панели — пара описывается одним компонентом, без двух одинаковых значений в двух местах;
  • связка tab ↔ tabpanel должна быть верной по умолчанию — idBase генерируется внутри, забыть его нельзя;
  • вкладки и панели стоят рядом — горизонтально или сбоку при orientation="vertical".

Когда взять другое

НужноБерите
Только ряд вкладок, панели своиGrTabs
Только панели: ряд вкладок нарисован иначеGrTabPanels
Вкладки и панели стоят в разных местах раскладкипара GrTabs + GrTabPanels
Разделы раскрываются, а не переключаютсяGrCollapse
Переключается вид одного содержимогоGrSegmented

Варианты все тона и виды — настоящим компонентом

variant

  • pills
  • line

Размеры

  • xs
  • sm
  • md
  • lg

Матрица живая: наводите и нажимайте. Состояний наведения, фокуса и нажатия здесь нет — они за браузером, а не за пропом.

Playground контролы выводятся из API, а не пишутся руками

Сцена

Загружается…

0 изменено· состояние — в адресе

Примеры 2 у каждого — живое демо и его код

  • Редактор товара в четырёх вкладках

    Ряд и его панели — один компонент: id и связка aria-controls ↔ aria-labelledby собраны внутри, и второго значения, которое надо держать в лад, нет. Пропы ряда — variant, size, tabs — проходят насквозь, а вкладка с проблемой говорит об этом счётчиком. В каждой панели форма, поэтому keep-alive сохраняет введённое при смене вкладки.

    Oak writing desk · draft
  • Настройки учётной записи столбцом

    Настройки — столбец: orientation="vertical" ставит ряд сбоку, а панель рядом. Алерт сверху ссылается на вкладку безопасности снаружи, поэтому id-base задан явно — страница знает id вкладки и переводит на неё фокус. Счётчик у «Security» пропадает, когда включён вход в два шага.

    Mina Ortiz[email protected]Finance lead

API порождается из пакета · разойтись не может

Props

PropTypeпо умолчаниюОписание
variant"pills" | "line" | undefinedundefinedВид ряда: обойма с таблетками или ряд с подчёркиванием.
closableboolean | undefinedundefinedКрестик на вкладках и закрытие по `Delete`/`Backspace`. Точечно снимается `closable: false` у самой вкладки.
size"xs" | "sm" | "md" | "lg" | undefinedundefinedВысота вкладок и кегль подписи по шкале контролов. По умолчанию `md`.
orientationGrTabsOrientation | undefinedundefinedГоризонтальный (по умолчанию) или вертикальный список вкладок.
activationModeGrTabsActivationMode | undefinedundefined`automatic` (по умолчанию) — стрелка сразу переключает вкладку; `manual` — стрелка двигает только фокус, выбор подтверждается `Enter`/`Space`. Второй режим для вкладок с тяжёлой загрузкой: перебор стрелками иначе тянет каждую панель.
emptyTextstring | undefinedundefinedТекст, когда список вкладок пуст. Слот `#empty` сильнее.
idBasestring | undefinedundefinedБаза id для ARIA-связки с `GrTabPanels`. Если задана, каждая вкладка получает `id="<idBase>-tab-<value>"` и `aria-controls="<idBase>-panel-<value>"`. Передайте тот же `idBase` в `GrTabPanels`, чтобы связать `tab`↔`tabpanel`.
modelValueобязательныйv-modelstring—`value` выбранной вкладки (`v-model`). Не совпал ни с одной — `Tab` встаёт на первую доступную.
tabsобязательныйGrTab[]—Вкладки в порядке вывода: `value`, `label`, по желанию иконка, счётчик и `disabled`.

Слоты

SlotTypeОписание
defaultanyПанели (`GrTabPanel`).
tab{ tab: GrTab; active: boolean; disabled: boolean; }Содержимое вкладки целиком — уходит в `GrTabs`.
emptyanyПустой ряд вкладок — уходит в `GrTabs`.

События

EventСигнатураОписание
close(event: "close", value: string): void—
update:modelValue(event: "update:modelValue", value: string): void—

Типы

Все экспортируемые типы подпути, по файлам, где они объявлены. Имена, дженерики и тела читаются из файлов деклараций пакета и разойтись не могут.

Импорт
import type { GrTabsWithPanelsProps, GrTabsWithPanelsEmits } from '@feugene/granularity/components/GrTabsWithPanels'

Файлdist/types/components/GrTabsWithPanels/config.d.ts

grTabsWithPanelsConfigconst
const grTabsWithPanelsConfig: import("@feugene/granum/contract").GranumComponentDescriptor<"GrTabsWithPanels">;

Файлdist/types/components/GrTabsWithPanels/GrTabsWithPanels.vue.d.ts

GrTabsWithPanelsPropsinterface
interface GrTabsWithPanelsProps extends GrTabsProps {
}
GrTabsWithPanelsEmitsinterface
interface GrTabsWithPanelsEmits {
    /** Выбрана другая вкладка (`v-model`); панель переключается следом. */
    (e: 'update:modelValue', value: string): void;
    /** Просьба закрыть вкладку — всплывает из `GrTabs` как есть. */
    (e: 'close', value: string): void;
}

Использование из прозы библиотеки

Зачем он есть

Пара требует двух одинаковых значений в двух местах — активной вкладки и idBase, из которого строится связка tab ↔ tabpanel. Обе дублируются, и обе расходятся молча.

Насколько это не теоретическое, уже измерено: GrTabs проставляет вкладкам id только при явном idBase, поэтому в обычном случае — когда его не передают вовсе — aria-labelledby панели указывал в несуществующий элемент. Здесь оба значения принадлежат одному компоненту, и забыть их нельзя.

vue
<GrTabsWithPanels v-model="tab" :tabs="tabs">
  <GrTabPanel value="profile">…</GrTabPanel>
  <GrTabPanel value="billing">…</GrTabPanel>
</GrTabsWithPanels>

idBase принимается пропом, но не обязателен: без него генерируется свой. Явный нужен там, где на эти id ссылаются снаружи.

Пропы ряда пробрасываются как есть

size, variant, activationMode, orientation, closable, emptyText и tabs уходят в GrTabs; слоты #tab и #empty — туда же, а #default — в панели. Событие close всплывает наружу.

Проброшенный проп, который не задали, приезжает в GrTabs отсутствующим, а не со значением обёртки. Для size и variant это принципиально: их дефолт живёт в резолвере GrConfigProvider, и подставленное значение перекрыло бы провайдера — панель перестала бы слушать глобальную настройку.

Поверхность пропов держит гейт: она обязана совпадать с GrTabs минус то, чем владеет сама обёртка. Иначе у ряда появился бы проп, о котором обёртка не знает, — то самое молчаливое расхождение, ради которого компонент и заведён.

Раскладка

По умолчанию ряд сверху, панели под ним. orientation="vertical" ставит ряд сбоку: вертикальные вкладки над панелями выглядели бы колонкой ссылок без связи с содержимым.