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.
| prop | type | default | description |
|---|---|---|---|
node | RowNode<T> | the layout's root row | the 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>) => ReactNode | required | renders 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 />) |
splitter | boolean | true | false 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:
| field | type | description |
|---|---|---|
node | RowNode<T> | the row the splitter resizes |
index | number | the 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:
| field | type | description |
|---|---|---|
orientation | "horizontal" | "vertical" | "horizontal": children side by side; "vertical": stacked |
root | boolean | the layout's root row |
hidden | boolean | a tabset of the layout is maximized outside this row, so the row is hidden (model.is("node-hidden-by-maximize", { nodeId })) |
Data attributes
| attribute | value |
|---|---|
data-layout-path | "/row" for the root row, else the row's path (/r1, /r0/r1, …) |
data-orientation | "horizontal" or "vertical" |
data-root | present 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 withlayout.configure) and a row nested in a row takes the opposite orientation. - A
Rowwith nonodeinsideDockable.Popoutrenders the window layout's root row. - A splitter drag runs
row.resize(see Dockable.Splitter). renderSplitterapplies to this row only: pass it to every row (Limitations, gap 6).