@@ -36,28 +36,80 @@ function SheetOverlay({ className, ...props }: SheetPrimitive.Backdrop.Props) {
3636 )
3737}
3838
39+ function ResizeHandle ( {
40+ side,
41+ onResize,
42+ } : {
43+ side : "left" | "right"
44+ onResize : ( delta : number ) => void
45+ } ) {
46+ const handlePointerDown = ( e : React . PointerEvent ) => {
47+ e . preventDefault ( )
48+ const startX = e . clientX
49+ const onMove = ( ev : PointerEvent ) => {
50+ const delta = side === "right" ? startX - ev . clientX : ev . clientX - startX
51+ onResize ( delta )
52+ }
53+ const onUp = ( ) => {
54+ document . removeEventListener ( "pointermove" , onMove )
55+ document . removeEventListener ( "pointerup" , onUp )
56+ }
57+ document . addEventListener ( "pointermove" , onMove )
58+ document . addEventListener ( "pointerup" , onUp )
59+ }
60+
61+ return (
62+ < div
63+ className = { cn (
64+ "absolute inset-y-0 z-50 w-1 cursor-col-resize hover:bg-primary/20 active:bg-primary/30" ,
65+ side === "right" ? "left-0" : "right-0"
66+ ) }
67+ onPointerDown = { handlePointerDown }
68+ />
69+ )
70+ }
71+
3972function SheetContent ( {
4073 className,
4174 children,
4275 side = "right" ,
4376 showCloseButton = true ,
77+ resizable = false ,
78+ defaultWidth = 384 ,
79+ minWidth = 280 ,
80+ maxWidth = 800 ,
4481 ...props
4582} : SheetPrimitive . Popup . Props & {
4683 side ?: "top" | "right" | "bottom" | "left"
4784 showCloseButton ?: boolean
85+ resizable ?: boolean
86+ defaultWidth ?: number
87+ minWidth ?: number
88+ maxWidth ?: number
4889} ) {
90+ const [ width , setWidth ] = React . useState ( defaultWidth )
91+ const canResize = resizable && ( side === "left" || side === "right" )
92+
4993 return (
5094 < SheetPortal >
5195 < SheetOverlay />
5296 < SheetPrimitive . Popup
5397 data-slot = "sheet-content"
5498 data-side = { side }
99+ style = { canResize ? { width : `${ width } px` , maxWidth : "none" } : undefined }
55100 className = { cn (
56- "fixed z-50 flex flex-col gap-4 bg-background bg-clip-padding text-sm shadow-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem] data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm" ,
101+ "fixed z-50 flex flex-col gap-4 bg-background bg-clip-padding text-sm shadow-lg transition duration-200 ease-in-out data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem]" ,
102+ ! canResize && "data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm" ,
57103 className
58104 ) }
59105 { ...props }
60106 >
107+ { canResize && (
108+ < ResizeHandle
109+ side = { side }
110+ onResize = { ( delta ) => setWidth ( ( w ) => Math . min ( maxWidth , Math . max ( minWidth , w + delta ) ) ) }
111+ />
112+ ) }
61113 { children }
62114 { showCloseButton && (
63115 < SheetPrimitive . Close
0 commit comments