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

Dockable.Splitter

A splitter between two children of a row, or beside a border's panel, that resizes them by pointer or keyboard.

"A splitter between two children of a row, or between a border's panel and the layout (role="separator"). Drag it with the pointer, or focus it and use the arrow keys. While an outline (non-realtime) drag is in progress it carries data-dragging and a structural transform previewing where it will land. It has no name of its own: give it an aria-label (through renderSplitter where a Row or a border inserts it)."

Dockable.Row renders one between every two children. Render your own through renderSplitter:

function renderSplitter(props: RowSplitterProps<Types>) {
    return <Dockable.Splitter {...props} aria-label="Resize" className="splitter" />;
}

Props

SplitterProps<T> extends the common primitive props.

proptypedefaultdescription
nodeRowNode<T> | BorderNode<T>requiredthe row (or border) the splitter resizes
indexnumber0in a row, the splitter sits before child index (1-based); a border's splitter has none
childrenReactNodenonecontent such as a grip

State

SplitterState (also returned by useSplitter) extends the core's SplitterControllerState (the SplitterController state):

fieldtypedescription
orientation"horizontal" | "vertical""vertical" for a splitter between side by side children, as its aria-orientation
draggingbooleantrue while the splitter is being dragged with the pointer
previewOffsetnumber | undefinedwhile an outline (non-realtime) drag is in progress: how far, in px along the splitter's axis on screen (negative is left or up, in RTL too), the splitter would move if released now (bounded). undefined otherwise
hiddenbooleanrow splitters are hidden while a tabset is maximized (display: none)

Data attributes and ARIA

attributevalue
data-layout-path<row path>/s<index-1>: /s0 between the root row's first two children; a border's is /border/<location>/s-1 (FlexLayout's scheme)
data-orientation"vertical" (a vertical bar between side by side children) or "horizontal"
data-draggingbeing dragged with the pointer
role"separator"
aria-orientationsame as data-orientation
aria-valuenow / aria-valuemin / aria-valuemaxrow splitters: the 0–100 position within the row, as measured, to a tenth; border splitters: the border's size, minSize and maxSize in px
aria-valuetextthe formatted value, e.g. "40%", "40.5%" or "200px"
aria-labelnone of its own: pass yours (see Accessible names)
tabIndex0

Structural style

display: none while a tabset is maximized; transform: translateX(…)/translateY(…) during a non-realtime drag; pointer-events: auto on a border's splitter (an overlay border's content is pointer-events: none). Nothing else: its size is yours (and the engine measures it as the layout's splitter size, engine.get("splitter-size")).

Commands

A drag or a key press resizes through the model, so middleware sees every resize:

  • a row splitter runs row.resize ({ rowId, weights }), a border splitter border.resize ({ borderId, size });
  • a realtime drag (realtimeResize, the default) runs them with { transient: true } on every move, then one non-transient command on release. Undo and persistence usually skip transient events (event.transient);
  • an outline drag (realtimeResize={false}) previews with transform and runs one command on release.

Keyboard

The arrow keys along its axis (Left/Right for a vertical bar, Up/Down for a horizontal one) move it by 10px, the way they point on screen, in RTL too. Modified arrows are ignored. A border's splitter grows its panel towards the layout (ArrowUp grows a bottom border; ArrowRight a start one in LTR, ArrowLeft in RTL, where the start border is on the right).

Dockable.BorderContent renders a border's splitter; pass renderSplitter there to style it.

See the Splitters guide for hairline and wide styles.