ns-ui

Split Pane Weighted

Split-pane divider that carries real weight: drag it and the boundary trails the pointer like a counterweighted window sash, release with speed and it coasts into the nearest detent on a critically-damped spring; released slow and far from a stop, it just stays put.

Use when a resizable split where the divider should carry weight, trailing the pointer like a counterweighted sash and coasting into the nearest detent when released with speed but staying put when released slow and far from a stop; pick drawer-counterweight instead when the panel is an overlay drawer rather than a pane in the layout, or view-toggle-rails when the layout should switch between arrangements rather than be resized.

Install

npx shadcn add https://design.helpmarq.com/r/split-pane-weighted.json
  • divider
  • split-pane
  • resize
  • layout
  • drag
  • spring
  • separator
  • keyboard

ns-ui / split-pane-weighted — drag has weight, release finds a rail

Explorer

  • src/
  • app/
  • layout.tsx
  • page.tsx
  • components/
  • split-pane-weighted.tsx
  • toolbar.tsx
  • lib/
  • spring.ts
  • package.json
1export function SashWeight({
2 orientation = "vertical",
3 detents = [25, 50, 75],
4 ...props
5}: SashWeightProps) {
6 const live = useSpring(pos, {
7 k: dragging ? 90 : 170,
8 zeta: dragging ? 1.15 : 1,
9 });
10 
11 return <Divider {...live} />;
12}

Preview

drag either rail fast, or nudge it with Arrow keys — Enter jumps to 50/50

Props

PropTypeDefaultDescription
orientation?Orientation"vertical" = a vertical divider splitting left/right panes (default). "horizontal" = a horizontal divider splitting top/bottom panes.
startReact.ReactNodethe leading (left / top) pane's content
endReact.ReactNodethe trailing (right / bottom) pane's content
value?numbercontrolled: the start pane's share of the container, as a percentage
defaultValue?number
onValueChange?(percent: number) => void
min?numberpercentage clamp for the divider's travel
max?number
detents?number[]percentages the divider settles toward on a decisive release, Shift+Arrow, or Enter/double-click's 50/50 fallback
ariaLabel?stringaccessible name for the divider
className?string