Resizable Panels
patchui/resizable-panelsFreeComponent
patchui publishes no description for this item.
Install it
npx shadcn@latest add https://ui.hotfix.jobs/r/resizable-panels.jsonSource
1"use client";23import {4 Children,5 createContext,6 isValidElement,7 useCallback,8 useContext,9 useEffect,10 useLayoutEffect,11 useRef,12 useState,13} from "react";14import { mergeProps } from "@base-ui/react/merge-props";15import { useRender } from "@base-ui/react/use-render";16import type * as React from "react";17import { cn } from "@/lib/utils";1819type PanelSide = "left" | "right";2021interface PanelLayout {22 width: number;23 min: number;24 max: number;25 open: boolean;26 onResize: (width: number) => void;27}2829interface ResizablePanelsContextValue {30 left?: PanelLayout;31 right?: PanelLayout;32}3334const ResizablePanelsContext =35 createContext<ResizablePanelsContextValue | null>(null);3637function clamp(value: number, min: number, max: number): number {38 return Math.min(Math.max(value, min), max);39}4041export function usePanelWidth(42 key: string,43 defaultWidth: number,44 min: number,45 max: number,46): readonly [number, (width: number) => void] {47 const [width, setWidth] = useState(() => clamp(defaultWidth, min, max));48 useEffect(() => {49 const stored = Number.parseFloat(window.localStorage.getItem(key) ?? "");50 const initialWidth = Number.isFinite(stored)51 ? clamp(stored, min, max)52 : clamp(defaultWidth, min, max);53 setWidth(initialWidth);54 window.localStorage.setItem(key, String(initialWidth));55 }, [defaultWidth, key, max, min]);56 const updateWidth = useCallback(57 (nextWidth: number) => {58 const clampedWidth = clamp(nextWidth, min, max);59 setWidth(clampedWidth);60 window.localStorage.setItem(key, String(clampedWidth));61 },62 [key, max, min],63 );6465 return [width, updateWidth] as const;66}6768export interface SidePanelProps extends useRender.ComponentProps<"div"> {69 side: PanelSide;70 open: boolean;71 width: number;72 min: number;73 max: number;74 onResize: (width: number) => void;75}7677export function SidePanel({78 side,79 open: _open,80 width: _width,81 min: _min,82 max: _max,83 onResize: _onResize,84 children,85 className,86 style,87 render,88 ...props89}: SidePanelProps): React.ReactElement {90 const layout = useContext(ResizablePanelsContext)?.[side];91 const width = layout?.width ?? 0;92 const defaultProps = {93 "data-slot": "resizable-side-panel-content",94 "aria-hidden": !layout?.open || undefined,95 inert: !layout?.open,96 className: cn(97 "absolute inset-y-0",98 side === "left" ? "left-0" : "right-0",99 className,100 ),101 style: { ...style, width },102 children,103 };104// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from patchui
All 51 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Accordionaccordion | patchui | Components | Free | 2 deps | |
| Avataravatar | patchui | Components | Free | 3 deps | |
| Badgebadge | patchui | Components | Free | 2 deps | |
| Breadcrumbbreadcrumb | patchui | Components | Free | 1 dep | |
| Buttonbutton | patchui | Components | Free | 2 deps | |
| Calendarcalendar | patchui | Components | Free | 1 dep | |
| Cardcard | patchui | Components | Free | 1 dep | |
| Checkboxcheckbox | patchui | Components | Free | 2 deps |
