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

Dockable.Row

A row (or column) of the layout, flex sized by the weights of its children, with a splitter between each pair.

"A row (or column) of the layout. Lays its children out with flex, sized by their weights, calls the child function per child and inserts a splitter between children."

function renderNode(child: TabsetNode<Types> | RowNode<Types>): ReactNode {
    if (child.type === "tabset") return <MyTabSet node={child} />;
    return (
        <Dockable.Row node={child} renderSplitter={renderSplitter}>
            {renderNode}
        </Dockable.Row>
    );
}

// the root row: no `node`, so pass the registry as the type argument
<Dockable.Row<Types> renderSplitter={renderSplitter}>{renderNode}</Dockable.Row>

Nodes are plain objects: a child is told apart by its type ("tabset" or "row"), and TypeScript narrows on it.

Props

RowProps<T> extends the common primitive props.

proptypedefaultdescription
nodeRowNode<T>the layout's root rowthe row to render; defaults to the root row of the enclosing layout (then pass the model's registry as the type argument: <Dockable.Row<Types>>)
children(child: TabsetNode<T> | RowNode<T>) => ReactNoderequiredrenders a child: a tabset or a nested row
renderSplitter(props: RowSplitterProps<T>) => ReactNode<Dockable.Splitter />renders the splitter between two children (defaults to <Dockable.Splitter />)
splitterbooleantruefalse renders no splitters

With a node, T is inferred from it. With none, the row reads the root row from the model in context, which a child cannot type: <Dockable.Row<Types>> gives children typed nodes.

RowSplitterProps<T>, the argument of renderSplitter:

fieldtypedescription
nodeRowNode<T>the row the splitter resizes
indexnumberthe splitter sits before child index (1-based)

Spread it on a Dockable.Splitter: (props) => <Dockable.Splitter {...props} aria-label="Resize" className="…" />. The default splitter has no name: renderSplitter is where you give it one.

State

RowState:

fieldtypedescription
orientation"horizontal" | "vertical""horizontal": children side by side; "vertical": stacked
rootbooleanthe layout's root row
hiddenbooleana tabset of the layout is maximized outside this row, so the row is hidden (model.is("node-hidden-by-maximize", { nodeId }))

Data attributes

attributevalue
data-layout-path"/row" for the root row, else the row's path (/r1, /r0/r1, …)
data-orientation"horizontal" or "vertical"
data-rootpresent on the root row

Structural style

display: flex (none while a tabset maximized outside the row fills the layout), flex-direction (row or column), flex-basis: 0, flex-grow from the weight (at least 1) and min-width/min-height/max-width/max-height (aggregated from the tabsets inside), both from the engine (engine.get("flex-by", { nodeId })), overflow: hidden. The root row adds position: absolute; inset: 0 to fill the root.

Notes

  • A row's orientation is not stored in the model. The root row takes defaults.layout.rootOrientation ("horizontal" by default; set it with layout.configure) and a row nested in a row takes the opposite orientation.
  • A Row with no node inside Dockable.Popout renders the window layout's root row.
  • A splitter drag runs row.resize (see Dockable.Splitter).
  • renderSplitter applies to this row only: pass it to every row (Limitations, gap 6).