GrTabsWithPanels
Берут, когда нужны и вкладки, и панели.
Обзор
Когда брать
- нужны и вкладки, и панели — пара описывается одним компонентом, без двух одинаковых значений в двух местах;
- связка
tab↔tabpanelдолжна быть верной по умолчанию —idBaseгенерируется внутри, забыть его нельзя; - вкладки и панели стоят рядом — горизонтально или сбоку при
orientation="vertical".
Когда взять другое
| Нужно | Берите |
|---|---|
| Только ряд вкладок, панели свои | GrTabs |
| Только панели: ряд вкладок нарисован иначе | GrTabPanels |
| Вкладки и панели стоят в разных местах раскладки | пара GrTabs + GrTabPanels |
| Разделы раскрываются, а не переключаются | GrCollapse |
| Переключается вид одного содержимого | GrSegmented |
Варианты все тона и виды — настоящим компонентом
variant
pillsline
Размеры
xssmmdlg
Матрица живая: наводите и нажимайте. Состояний наведения, фокуса и нажатия здесь нет — они за браузером, а не за пропом.
Playground контролы выводятся из API, а не пишутся руками
Загружается…
0 изменено· состояние — в адресе
<GrTabsWithPanels :tabs="tabs" v-model="value" />Примеры 2 у каждого — живое демо и его код
Редактор товара в четырёх вкладках
Ряд и его панели — один компонент: id и связка
aria-controls↔aria-labelledbyсобраны внутри, и второго значения, которое надо держать в лад, нет. Пропы ряда —variant,size,tabs— проходят насквозь, а вкладка с проблемой говорит об этом счётчиком. В каждой панели форма, поэтомуkeep-aliveсохраняет введённое при смене вкладки.Oak writing desk · draft Must be above the current price.Low stock — the shop shows «Only a few left»
shop.example/Настройки учётной записи столбцом
Настройки — столбец:
orientation="vertical"ставит ряд сбоку, а панель рядом. Алерт сверху ссылается на вкладку безопасности снаружи, поэтомуid-baseзадан явно — страница знает id вкладки и переводит на неё фокус. Счётчик у «Security» пропадает, когда включён вход в два шага.Two-factor sign-in is offAnyone with your password can sign in to the billing workspace.
API порождается из пакета · разойтись не может
Props
| Prop | Type | по умолчанию | Описание |
|---|---|---|---|
variant | "pills" | "line" | undefined | undefined | Вид ряда: обойма с таблетками или ряд с подчёркиванием. |
closable | boolean | undefined | undefined | Крестик на вкладках и закрытие по `Delete`/`Backspace`. Точечно снимается `closable: false` у самой вкладки. |
size | "xs" | "sm" | "md" | "lg" | undefined | undefined | Высота вкладок и кегль подписи по шкале контролов. По умолчанию `md`. |
orientation | GrTabsOrientation | undefined | undefined | Горизонтальный (по умолчанию) или вертикальный список вкладок. |
activationMode | GrTabsActivationMode | undefined | undefined | `automatic` (по умолчанию) — стрелка сразу переключает вкладку; `manual` — стрелка двигает только фокус, выбор подтверждается `Enter`/`Space`. Второй режим для вкладок с тяжёлой загрузкой: перебор стрелками иначе тянет каждую панель. |
emptyText | string | undefined | undefined | Текст, когда список вкладок пуст. Слот `#empty` сильнее. |
idBase | string | undefined | undefined | База id для ARIA-связки с `GrTabPanels`. Если задана, каждая вкладка получает `id="<idBase>-tab-<value>"` и `aria-controls="<idBase>-panel-<value>"`. Передайте тот же `idBase` в `GrTabPanels`, чтобы связать `tab`↔`tabpanel`. |
modelValueобязательныйv-model | string | — | `value` выбранной вкладки (`v-model`). Не совпал ни с одной — `Tab` встаёт на первую доступную. |
tabsобязательный | GrTab[] | — | Вкладки в порядке вывода: `value`, `label`, по желанию иконка, счётчик и `disabled`. |
Слоты
| Slot | Type | Описание |
|---|---|---|
default | any | Панели (`GrTabPanel`). |
tab | { tab: GrTab; active: boolean; disabled: boolean; } | Содержимое вкладки целиком — уходит в `GrTabs`. |
empty | any | Пустой ряд вкладок — уходит в `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
const grTabsWithPanelsConfig: import("@feugene/granum/contract").GranumComponentDescriptor<"GrTabsWithPanels">;Файлdist/types/components/GrTabsWithPanels/GrTabsWithPanels.vue.d.ts
interface GrTabsWithPanelsProps extends GrTabsProps {
}interface GrTabsWithPanelsEmits {
/** Выбрана другая вкладка (`v-model`); панель переключается следом. */
(e: 'update:modelValue', value: string): void;
/** Просьба закрыть вкладку — всплывает из `GrTabs` как есть. */
(e: 'close', value: string): void;
}Использование из прозы библиотеки
Зачем он есть
Пара требует двух одинаковых значений в двух местах — активной вкладки и
idBase, из которого строится связка tab ↔ tabpanel. Обе дублируются, и обе
расходятся молча.
Насколько это не теоретическое, уже измерено: GrTabs проставляет вкладкам id
только при явном idBase, поэтому в обычном случае — когда его не передают
вовсе — aria-labelledby панели указывал в несуществующий элемент. Здесь оба
значения принадлежат одному компоненту, и забыть их нельзя.
<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" ставит ряд
сбоку: вертикальные вкладки над панелями выглядели бы колонкой ссылок без связи
с содержимым.
Пропы этого примера