Vesture

Layout

DashboardGridNew in 0.8.0

A tile grid for dashboards. Tiles drag and resize, push each other out of the way, and float back up to close gaps.

DashboardGridmoveItemresizeItemnormalizeLayout

Preview

Gap 12px
revenue6×3 at (0, 0)
users3×2 at (6, 0)
churn3×2 at (9, 0)
activity6×2 at (6, 2)
pinned12×1 at (0, 4) · pinned

Drag a tile, drag its bottom-right corner, or focus a tile and use the arrow keys (Shift to resize).

Usage

tsx
import { useState } from "react";
import { DashboardGrid, type GridItem } from "@vesture/react";

function Example() {
  const [layout, setLayout] = useState<GridItem[]>([
    { id: "revenue", x: 0, y: 0, w: 6, h: 3 },
    { id: "users", x: 6, y: 0, w: 6, h: 3 },
  ]);
  return <DashboardGrid layout={layout} onLayoutChange={setLayout} editable renderItem={(i) => <Tile id={i.id} />} />;
}

Behavior

  • Editing is off until editable is set. Then drag a tile, drag its bottom-right handle, or focus it and use the arrow keys (Shift+arrows resize).
  • Mark inner controls with data-no-drag (buttons, inputs and links are excluded automatically).
  • Layout helpers are exported as pure functions for server-side or custom persistence logic.

Props

PropTypeDefaultDescription
layout / defaultLayout / onLayoutChangeGridItem[]—GridItem: { id; x; y; w; h; minW?; minH?; maxW?; maxH?; static? } in grid cells.
renderItem(item) => ReactNode—Required. Renders one tile's content.
cols / rowHeight / gapnumber12 / 80 / 12Grid geometry in cells / px.
editable / draggable / resizablebooleanfalse / true / trueInteraction switches.
compactVerticallybooleantrueFloat tiles up after every change.
widthnumber—Fixed width. Default: measure the container.
onInteractionStart / onInteractionEndfunction—Drag lifecycle hooks.