Documentation
API: primitives (@fragiola/dockable-react)

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.

proptypedefaultdescription
nodeTabsetNode<T>requiredthe tabset to render
childrenReactNodenonethe tab strip, the content area, and anything else (a header, buttons)

State

TabSetState (shared with useTabSet):

fieldtypedescription
activebooleanthe tabset is its layout's active tabset (model.is("tabset-active", { tabsetId }))
maximizedbooleanthe tabset is maximized (model.is("tabset-maximized", { tabsetId }))
hiddenbooleananother tabset of the layout is maximized, so this one is hidden (model.is("node-hidden-by-maximize", { nodeId }))
emptybooleanthe tabset has no tabs
dropTargetbooleanthe current drag would drop into or beside this tabset (its content or its strip)
dropLocationDropLocation | undefined: "center" | "top" | "bottom" | "start" | "end"while it is the drop target: where the drag would dock relative to it
dropRefusedbooleanthe current drag is over this tabset, but a drop rule (or a middleware veto) refuses it
dropIndexnumber | undefinedwhile 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

attributewhen
data-layout-paththe tabset's path: /ts0, /r1/ts0, …
data-activeits layout's active tabset
data-maximizedmaximized
data-emptyno tabs
data-drop-targetthe current drag would drop into or beside this tabset
data-drop-locationwhile it is the drop target: "center", "top", "bottom", "start" or "end"
data-drop-refusedthe 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.