Dockable
Guides

Maximize

Let a tabset fill the layout, and style the maximized state.

Maximizing a tabset makes it fill its layout: every other tabset, every row that does not contain it and every row splitter is hidden (structurally, display: none), so the maximized tabset takes the whole root row, however deeply it is nested.

This differs from FlexLayout, which moves (portals) the maximized tabset over the layout. Dockable hides what is off the maximized tabset's path instead: nothing remounts, and the content keeps its moveable element. The rule is the core's model.isHiddenByMaximize(node), which TabSet and Row read (TabSetState.hidden, RowState.hidden).

Intermediate exampleMaximizeMaximize a tabset with its header button or a double-click on the empty strip, restore it with Escape, and style it through data-maximized.Open the live example

The action

Actions.maximizeToggle(tabsetId) maximizes a tabset, or restores it when it is the maximized one:

import { Actions, DockableLabel, type TabSetNode } from "@fragiola/dockable";
import { useDockable } from "@fragiola/dockable-react";

function MaximizeButton({ tabset }: { tabset: TabSetNode }) {
    const { engine, model, getLabel } = useDockable();
    const maximized = tabset.isMaximized();
    // a lone tabset has nothing to hide
    const alone = model.getRootRow(tabset.getLayoutId())?.getChildren().length === 1;
    if (!tabset.isEnableMaximize() || (alone && !maximized)) return null;
    return (
        <button
            type="button"
            aria-pressed={maximized}
            aria-label={getLabel?.(maximized ? DockableLabel.Restore : DockableLabel.Maximize)}
            onClick={() => engine.doAction(Actions.maximizeToggle(tabset.getId(), tabset.getLayoutId()))}
        >
            {maximized ? <MinimizeIcon aria-hidden="true" /> : <MaximizeIcon aria-hidden="true" />}
        </button>
    );
}

Pass the tabset's layout id: in a popout window, maximize applies to that window's layout.

A double click on the tab strip is a common shortcut; attach it to your header element:

<div className="header" onDoubleClick={() => engine.doAction(Actions.maximizeToggle(node.getId(), node.getLayoutId()))}>

Maximizing is allowed unless enableMaximize: false (per tabset, or tabSetEnableMaximize globally).

Styling the state

attributeonmeaning
data-maximizedDockable.Roota tabset of the main layout is maximized
data-maximizedDockable.TabSetthis tabset is maximized
<Dockable.TabSet node={node} className="border border-palette-line data-maximized:border-palette-ring" />

The hidden tabsets and splitters need no styling: the primitives hide them. Their tabs' panels are hidden too (Panel's data-visible is absent), and their content stays mounted.

Reading it

model.getMaximizedTabset(layoutId?) returns the maximized tabset, or undefined. The maximized state is saved by toJson() (maximized: true on the tabset) and restored by fromJson.

Keyboard

There is no default key binding for maximize. Add one in your own key handler, and dispatch the same action (see Keyboard and accessibility).

On this page