Dockable.TabSet
A tabset is a flex item of its row, sized by its weight. Pressing anywhere inside it makes it the active tabset.
"A tabset: a flex item of its row, sized by its weight. Pressing inside it makes it the active
tabset. Place a Dockable.TabList and a Dockable.TabSetContent inside."
function MyTabSet({ node }: { node: TabsetNode<Types> }) {
return (
<Dockable.TabSet node={node} className="tabset">
<Dockable.TabList<Types> aria-label={node.data?.name ?? "Tabs"}>
{(tab) => <Dockable.Tab node={tab}>{tab.label}</Dockable.Tab>}
</Dockable.TabList>
<Dockable.TabSetContent />
</Dockable.TabSet>
);
}A tabset's name is not part of the model: when it has one, it is the app's text, kept in the
tabset's typed data (Types["tabset"]) as above.
The tabset is a structural flex column, so child order is visual order: put TabSetContent
first for a strip at the bottom.
Props
TabSetProps<T> extends the common primitive props.
| prop | type | default | description |
|---|---|---|---|
node | TabsetNode<T> | required | the tabset to render |
children | ReactNode | none | the tab strip, the content area, and anything else (a header, buttons) |
State
TabSetState (shared with useTabSet):
| field | type | description |
|---|---|---|
active | boolean | the tabset is its layout's active tabset (model.is("tabset-active", { tabsetId })) |
maximized | boolean | the tabset is maximized (model.is("tabset-maximized", { tabsetId })) |
hidden | boolean | another tabset of the layout is maximized, so this one is hidden (model.is("node-hidden-by-maximize", { nodeId })) |
empty | boolean | the tabset has no tabs |
dropTarget | boolean | the current drag would drop into or beside this tabset (its content or its strip) |
dropLocation | DropLocation | undefined: "center" | "top" | "bottom" | "start" | "end" | while it is the drop target: where the drag would dock relative to it |
dropRefused | boolean | the current drag is over this tabset, but a drop rule (or a middleware veto) refuses it |
dropIndex | number | undefined | while the drag aims at this tabset's strip: the index among its tabs the tab would be inserted at (its length for the end), else undefined |
Data attributes
| attribute | when |
|---|---|
data-layout-path | the tabset's path: /ts0, /r1/ts0, … |
data-active | its layout's active tabset |
data-maximized | maximized |
data-empty | no tabs |
data-drop-target | the current drag would drop into or beside this tabset |
data-drop-location | while it is the drop target: "center", "top", "bottom", "start" or "end" |
data-drop-refused | the current drag is over this tabset, but a drop rule refuses it |
Structural style
display: flex (or none while hidden), flex-direction: column, flex-basis: 0,
flex-grow from the weight and min-*/max-*, both from the engine (engine.get("flex-by", { nodeId })),
overflow: hidden.
Behaviour
A primary-button press anywhere inside it (without modifiers) runs
tabset.activate when it is not already active, through the model's middleware.
Children context
TabList and TabSetContent must be rendered inside a TabSet: they read their tabset from
it.