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

Dockable.Border

A border's strip is the bar on one side of the layout that holds its tabs and opens or closes its panel.

"A border's strip: the bar on one side of the layout that holds its tabs. Place a Dockable.TabList inside (it runs vertically in a start or end border). Clicking a tab opens the border's panel; clicking the selected tab closes it. Render it from Dockable.Borders's renderBar."

<Dockable.Border
    node={border}
    tabDirection="down"
    className="flex bg-palette-surface data-[orientation=vertical]:w-8 data-[orientation=horizontal]:h-8"
>
    <Dockable.TabList<Types> className="data-[orientation=vertical]:[writing-mode:vertical-rl]">
        {(tab) => <Dockable.Tab node={tab}>{tab.label}</Dockable.Tab>}
    </Dockable.TabList>
</Dockable.Border>

The strip is only structural flex. Turning the labels of a side border (writing-mode, a rotate transform) is styling, and yours: data-tab-direction on the start border says which way you want them to read (the tabDirection prop, a view option the model does not store). Drops into the strip are hit-tested against the tab buttons' measured boxes, so any styling works.

Props

BorderProps<T> extends the common primitive props.

proptypedefaultdescription
nodeBorderNode<T>requiredthe border
tabDirection"up" | "down""up"the start border's tab direction, exposed as data-tab-direction for your styles (rotating the labels is yours); ignored on the other sides. The page's direction does not change it: pass "down" in RTL, where the start border is on the right
childrenReactNodenonethe strip's content: a Dockable.TabList, and any buttons

State

BorderState: the border's BorderContentState (also returned by useBorder), plus its tab direction:

fieldtypedescription
location"top" | "bottom" | "start" | "end"the side of the layout the border is on
orientation"horizontal" | "vertical"the direction its tabs run: "vertical" for a start or end border
openbooleana tab is selected, so the border's panel is open (model.is("border-open", { borderId }))
overlaybooleanthe panel opens over the layout (model.is("border-overlay", { borderId })) instead of beside it
emptybooleanthe border has no tabs
dropTargetbooleanthe current drag would drop into this border (its strip or its open panel)
dropRefusedbooleanthe current drag is over this border, but a drop rule refuses it
tabDirection"up" | "down" | undefinedthe start border's tab direction (the tabDirection prop): "up" (default) or "down"; undefined on the other sides. Only the strip has it

Data attributes and ARIA

attributevalue
data-layout-path/border/<location>, e.g. /border/start; its tabs are /border/start/tb0, its tab strip /border/start/tabstrip
data-location"top", "bottom", "start" or "end"
data-orientation"vertical" for a start or end border, else "horizontal"
data-opena tab is selected (the panel is open)
data-overlay / data-dockedthe border's resolved mode is "overlay" / "docked"
data-emptythe border has no tabs
data-tab-directionon the start border: "up" or "down" (the tabDirection prop)
data-drop-targetthe current drag would drop into the border
data-drop-refuseda drop rule refuses the current drag here

The tabs are role="tab" in a role="tablist" (from Dockable.TabList), as in a tabset.

Structural style

display: flex, flex-direction: column for a start or end border, row otherwise. The strip's size is yours.

Notes

  • The engine measures the strip as the border's tab header: drops into it insert at a tab position, and a drop onto the open panel appends.
  • A click on a tab runs tab.select, which opens the border's panel; a click on the selected tab runs border.configure with open: false, which closes it (FlexLayout's toggle). Enter or Space on the selected tab moves focus into its panel instead.
  • An overlay or docked border is the border's mode: switch it with model.run("border.configure", { borderId: border.id, mode: "overlay" }).