A lightweight, headless dock layout library for React.
npm install react-headless-dock-layoutA lightweight, headless dock layout library for React.
- Headless - You control all rendering and styling. This library only provides state and behavior.
- Lightweight - Implements only core dock layout features. No tabs, floating windows, or complex UI.
- Panel Management - Add, remove, drag-and-drop, and resize panels through split bars.
Use this library if:
- You need full control over UI design and styling
- You want a simple, focused dock layout solution
- Your requirements are basic panel operations (add/remove/move/resize)
Don't use this library if:
- You need pre-styled components ready to use
- You require tabs, floating windows, or complex docking features
- You want a complete IDE-like layout system
- React >= 18.0.0
``bash`
npm install react-headless-dock-layoutor
yarn add react-headless-dock-layoutor
pnpm add react-headless-dock-layout
`tsx
import { useDockLayout } from 'react-headless-dock-layout';
function App() {
const {
addPanel,
removePanel,
containerRef,
layoutRects,
draggingRect,
getRectProps,
getDropIndicatorProps,
getDragHandleProps,
} = useDockLayout
return (
if (rect.type === "panel") {
const { style, ...props } = getRectProps(rect);
const dropIndicatorProps = getDropIndicatorProps(rect);
return (
{rect.id === "explorer" &&
return null;
})}
Advanced
$3
A placement strategy determines where new panels are placed when added. The default strategy is
equalWidthRightStrategy, which adds panels to the right with equal widths.To use a custom strategy, pass it in the options. Here's an example that adds panels to the rightmost panel, alternating split directions:
`tsx
import { useDockLayout, type PlacementStrategy, type LayoutNode, type PanelNode, type SplitNode } from 'react-headless-dock-layout';function findRightMostPanel(node: LayoutNode): PanelNode {
if (node.type === "panel") return node;
if (node.type === "split") return findRightMostPanel(node.right);
throw new Error("Unexpected node type");
}
function findParentNode(root: LayoutNode, id: string): SplitNode | null {
function find(node: LayoutNode): SplitNode | null {
if (node.type === "panel") return null;
if (node.left.id === id || node.right.id === id) return node;
return find(node.left) ?? find(node.right);
}
return find(root);
}
const myStrategy: PlacementStrategy = {
getPlacementOnAdd(root) {
const rightMostPanel = findRightMostPanel(root);
const parentNode = findParentNode(root, rightMostPanel.id);
return {
targetId: rightMostPanel.id,
direction: parentNode?.orientation === "horizontal" ? "bottom" : "right",
ratio: 0.5,
};
},
};
const { addPanel } = useDockLayout(null, {
placementStrategy: myStrategy,
});
``