MCPcopy Create free account
hub / github.com/Openpanel-dev/openpanel / useResizableDrawer

Function useResizableDrawer

apps/start/src/hooks/use-resizable-drawer.ts:32–104  ·  view source on GitHub ↗
({
  defaultWidth,
  minWidth,
  maxWidth,
  storageKey,
  edge = 'left',
}: Options)

Source from the content-addressed store, hash-verified

30 * cursor/userSelect tweaks in the consumer.
31 */
32export function useResizableDrawer({
33 defaultWidth,
34 minWidth,
35 maxWidth,
36 storageKey,
37 edge = 'left',
38}: Options): Result {
39 const [width, setWidth] = useState(defaultWidth);
40
41 // Hydrate from localStorage on mount (avoids SSR mismatch).
42 useEffect(() => {
43 if (typeof window === 'undefined') return;
44 const raw = window.localStorage.getItem(storageKey);
45 if (!raw) return;
46 const n = Number(raw);
47 if (Number.isNaN(n)) return;
48 setWidth(Math.min(maxWidth, Math.max(minWidth, n)));
49 }, [storageKey, minWidth, maxWidth]);
50
51 // Persist on idle (debounced).
52 useEffect(() => {
53 if (typeof window === 'undefined') return;
54 const t = window.setTimeout(() => {
55 window.localStorage.setItem(storageKey, String(width));
56 }, 300);
57 return () => window.clearTimeout(t);
58 }, [width, storageKey]);
59
60 const dragRef = useRef<{ startX: number; startWidth: number } | null>(null);
61
62 const onMouseDown = useCallback(
63 (e: React.MouseEvent) => {
64 e.preventDefault();
65 dragRef.current = { startX: e.clientX, startWidth: width };
66
67 const onMove = (ev: MouseEvent) => {
68 if (!dragRef.current) return;
69 const dx =
70 edge === 'left'
71 ? dragRef.current.startX - ev.clientX
72 : ev.clientX - dragRef.current.startX;
73 const next = Math.min(
74 maxWidth,
75 Math.max(minWidth, dragRef.current.startWidth + dx),
76 );
77 setWidth(next);
78 };
79
80 const onUp = () => {
81 dragRef.current = null;
82 document.body.style.cursor = '';
83 document.body.style.userSelect = '';
84 window.removeEventListener('mousemove', onMove);
85 window.removeEventListener('mouseup', onUp);
86 };
87
88 document.body.style.cursor = 'ew-resize';
89 document.body.style.userSelect = 'none';

Callers 1

ChatDrawerFunction · 0.90

Calls 3

getItemMethod · 0.80
setItemMethod · 0.80
addEventListenerMethod · 0.80

Tested by

no test coverage detected