Concepts & terminology
The names dashfoo uses for tabs, panes, rows, splitters, and floating panels, with one annotated figure, the vocabulary, and the same layout as data.
dashfoo describes every layout with a small, fixed vocabulary. The same words
appear in the model's node types, in the data-dashfoo="…" attributes you
style, and in the reducer's action names. This page introduces them once, in
one picture, before the deeper guides.
Anatomy of a layout
- 1Tab: one document: a
componentregistry key plus anamelabel (TabNode). Tabs are the leaves of the tree. - 2Tab strip: the row of tab buttons on a tabset; renderer chrome (
data-dashfoo="tabstrip"), not a node. - 3Tabset / pane: a tab strip plus one visible body;
selectedpicks the visible tab (TabsetNode). - 4Splitter / gutter: the draggable resize handle between the children of a row.
- 5Root row: the whole tiled area;
orientation: "row"lays its children left-to-right (RowNode). - 6Nested row: a row inside a row;
orientation: "column"stacks its two tabsets top-to-bottom. - 7Floating panel: a window-like panel above the grid with its own layout subtree and pixel
geometry(FloatNode). - 8Minimized chip: a floating panel collapsed to a pill docked at the layout edge (
minimized: true).
Three of the labeled parts are node types in the model (RowNode,
TabsetNode, TabNode), and floating panels are a fourth, FloatNode, which
lives in Dashfoo.floats beside the tiled tree. The tab strip and the splitters are
renderer chrome: they exist in the markup (data-dashfoo="tabstrip",
data-dashfoo="splitter") but not in the model, which is why resizing a pane
changes weight rather than storing pixel widths.
The vocabulary
| Term | In the model | Meaning |
|---|---|---|
| Tab | TabNode | One document: a component registry key plus a name label. Content never lives in the model. Your factory resolves the key at render. |
| Tab strip | renderer chrome | The row of tab buttons on a tabset. global.tabLocation puts it at the "top" (default) or "bottom". |
| Tabset / pane | TabsetNode | A tab strip plus one visible body; selected picks the visible tab. |
| Active tabset | activeTabsetId | The focused pane: the last one interacted with, tracked so chrome and themes can highlight it. |
| Maximized tabset | maximizedTabsetId | One tabset in the main layout rendered full-area, hiding its siblings until restored. Floats opt out of maximize. |
| Row | RowNode | The recursive container: lays children (tabsets or nested rows) along one axis. |
| Orientation | orientation: "row" | "column" | The row's axis: left-to-right or top-to-bottom. |
| Weight | weight | A child's share of its parent row's space, relative to its siblings. |
| Splitter / gutter | renderer chrome | The draggable resize handle between a row's children; global.splitterSize sets its thickness. |
| Dock location | "center" | "split-left" | "split-right" | "split-top" | "split-bottom" | Where a drop lands: stack into the tab strip, or split the pane toward an edge. |
| Floating panel | FloatNode | A window-like panel above the grid with its own layout subtree and pixel geometry. |
| Minimized chip | minimized: true | A floating panel collapsed to a small pill docked at the layout edge. |
The floating panel is as close as dashfoo gets to a window. It renders in the same React tree, never in a separate browser window, so context, events, and styling stay connected. See Floating panels.
Row versus column
Rows are the only recursive container. The anatomy figure's right-hand column
is a row with orientation: "column" nested inside the root row:
orientation: "row"
children flow left-to-right; the splitter is vertical
orientation: "column"
children stack top-to-bottom; the splitter is horizontal
The same layout, as data
Everything above is one plain, serializable object: the Dashfoo model. Here
is the anatomy figure again, as the tree the renderer reads. The ids match the
grey badges in the figure:
- Dashfooversion: 1 · activeTabsetId: "ts-main"
- layout:rowrootorientation: "row"
- tabsetts-mainweight: 2 · selected: 0
- tabname: "Canvas" · component: "canvas"
- tabname: "Detail" · component: "detail"
- rowrightorientation: "column" · weight: 1
- tabsetts-side-topweight: 1
- tabname: "Activity"
- tabname: "Tasks"
- tabsetts-side-bottomweight: 1
- tabname: "Metrics"
- tabname: "History"
- tabname: "Reports"
- floats[0]:floatname: "Notes" · geometry: { left, top, width, height }
- layout:roworientation: "row"
- tabsetselected: 0
- tabname: "Scratch"
The layout model walks this shape field by field, including the
builders that write it tersely and the normalize() pass that keeps it
canonical.
Where next
- The layout model: the full node schema, builders, and self-healing invariants.
- Drag and dock: how pointer position becomes a dock location.
- Floating panels: floating, minimizing, and docking back.
- Theming: styling the
data-dashfoo="…"markup you saw above.