useColumnResize
A resizable column or row: a handle that drags the size its owner keeps. SlidingColumn is built on it, and ColumnResizeHandle is the handle.
import { clampColumnSize, useColumnResize } from '@basmilius/react-ui';import { useRef, useState } from 'react';
import { ColumnResizeHandle, useColumnResize } from '@basmilius/react-ui';
export default function ColumnResizeHandleDemo() {
const column = useRef<HTMLElement>(null);
const [width, setWidth] = useState(220);
const { startResize } = useColumnResize(column, { size: width, min: 160, max: () => 400, from: 'left', onSize: setWidth });
return (
<div className="flex h-56 w-full overflow-hidden rounded-lg border border-border bg-bg">
<aside ref={column} className="relative shrink-0 border-r border-border bg-surface p-3 text-xs text-text-muted" style={{ width }}>
Drag my right edge: {width} pixels.
<ColumnResizeHandle from="left" onPointerDown={startResize} />
</aside>
<div className="grow p-3 text-xs text-text-faint">The rest of the view.</div>
</div>
);
}const column = useRef<HTMLElement>(null);
const { startResize } = useColumnResize(column, {
size: width,
min: 160,
max: () => window.innerWidth - 400,
from: 'left',
onSize: setWidth
});from is the edge the column hangs from, and with it the axis of the drag. A column pinned to the right edge of the window grows as the pointer moves left; one that starts at its own left edge grows as it moves right. top and bottom do the same for a row.
startResize goes on the handle's onPointerDown. The handle takes the pointer capture, so the drag keeps going when the pointer leaves the few pixels it is wide. While it lasts the column carries data-resizing, so a transition on its size can turn off. Every move calls onSize with a whole number held between min and max(); max is read at drag time, so a window resize between two drags counts.
clampColumnSize
clampColumnSize({ min, max }, size) holds a size between the two and rounds it. Run a stored width through it before the first render, since the window may be smaller than it was when the width was saved.
Options
| Option | Type | |
|---|---|---|
size | number | Required. The size now, in whole pixels. |
min | number | Required. |
from | ColumnEdge | Required. 'left' | 'right' | 'top' | 'bottom' |
onSize | (size: number) => void | Required. |
max | () => number |
ColumnResizeOptions, ColumnResize and ColumnEdge are exported types.