Dockable.TabList
The tabset's tab strip (role="tablist") - calls the child function per tab, with arrow-key navigation.
"The tabset's tab strip (role="tablist"). Calls the child function per tab. Arrow keys along
the orientation, Home and End move focus between tabs; Enter or Space selects."
<Dockable.TabList aria-label={tabset.getName() ?? "Tabs"} className="flex min-h-8 ps-1">
{(tab) => (
<Dockable.Tab node={tab} className="tab">
{tab.getName()}
</Dockable.Tab>
)}
</Dockable.TabList>Render it inside a Dockable.TabSet (or a Dockable.Border). The engine measures it: the strip's
rect is used for drop hit-testing, and the tabs that do not fit in it are hidden (tab overflow),
for a Dockable.TabOverflowTrigger to list.
Props
TabListProps extends the common primitive props.
| prop | type | default | description |
|---|---|---|---|
children | (tab: TabNode) => ReactNode | required | renders a tab button (a Dockable.Tab) |
orientation | "horizontal" | "vertical" | "horizontal" ("vertical" in a left or right border) | the direction the tabs are laid out in, for arrow key navigation; default horizontal (vertical in a left or right border) |
overflow | boolean | true | tab overflow: the tabs that do not fit are hidden (the selected one stays), for a Dockable.TabOverflowTrigger to list; false keeps every tab, for a strip that wraps or scrolls |
State
TabListState:
| field | type | description |
|---|---|---|
orientation | "horizontal" | "vertical" | the orientation prop |
dropTarget | boolean | the current drag would drop into this tab strip |
dropIndex | number | undefined | while it is the drop target: the insertion index in the strip |
overflowing | boolean | some tabs do not fit, so they are hidden (list them with Dockable.TabOverflowTrigger) |
hiddenCount | number | how many tabs are hidden |
Data attributes and ARIA
| attribute | value |
|---|---|
data-layout-path | <tabset path>/tabstrip, e.g. /ts0/tabstrip |
data-orientation | "horizontal" or "vertical" |
data-drop-target | the current drag would drop into this tab strip |
data-drop-index | while it is the drop target: the insertion index among the tabset's children |
data-overflowing | some tabs do not fit, so they are hidden |
role | "tablist" |
aria-orientation | the orientation |
aria-keyshortcuts | the focusNextTabset/focusPreviousTabset bindings, when set |
Name it with aria-label (the tabset's name attribute is meant for it).
Styling notes
- Keep some start padding: a drop before the first tab is refused when that tab is flush with the tabset's edge (gap 10).
- Keep it at least ~30px tall at the top of the layout, or lower the global
edgeDockMargin: the layout's top-edge docking band is 10px (gap 11). - No structural style: layout and wrapping are yours. Give the list a size the tabs can overflow
(
flex: 1; min-width: 0in a header row,overflow: hidden): tab overflow compares the tabs' sizes, plus the list'sgap, with the list's inner size (Tab overflow).
In a border
Dockable.TabList works the same inside Dockable.Border: its path is
/border/<location>/tabstrip, and it runs vertically in a left or right border. The border's strip
(Dockable.Border) is what the engine measures there, not the tab list.