@orsetra/shared-ui 1.0.37 → 1.0.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/ui/side-panel.tsx +90 -30
- package/package.json +1 -1
|
@@ -5,7 +5,7 @@ import * as DialogPrimitive from "@radix-ui/react-dialog"
|
|
|
5
5
|
import { X } from "lucide-react"
|
|
6
6
|
import { cn } from "../../lib/utils"
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const SidePanelRoot = DialogPrimitive.Root
|
|
9
9
|
|
|
10
10
|
const SidePanelTrigger = DialogPrimitive.Trigger
|
|
11
11
|
|
|
@@ -28,6 +28,80 @@ const SidePanelOverlay = React.forwardRef<
|
|
|
28
28
|
))
|
|
29
29
|
SidePanelOverlay.displayName = DialogPrimitive.Overlay.displayName
|
|
30
30
|
|
|
31
|
+
interface SidePanelProps {
|
|
32
|
+
open: boolean
|
|
33
|
+
onOpenChange: (open: boolean) => void
|
|
34
|
+
title: string
|
|
35
|
+
description?: string
|
|
36
|
+
children: React.ReactNode
|
|
37
|
+
actions: React.ReactNode
|
|
38
|
+
side?: "left" | "right"
|
|
39
|
+
width?: string
|
|
40
|
+
onClose?: () => void
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const SidePanel = ({
|
|
44
|
+
open,
|
|
45
|
+
onOpenChange,
|
|
46
|
+
title,
|
|
47
|
+
description,
|
|
48
|
+
children,
|
|
49
|
+
actions,
|
|
50
|
+
side = "right",
|
|
51
|
+
width = "max-w-lg",
|
|
52
|
+
onClose,
|
|
53
|
+
}: SidePanelProps) => {
|
|
54
|
+
return (
|
|
55
|
+
<SidePanelRoot open={open} onOpenChange={onOpenChange}>
|
|
56
|
+
<SidePanelPortal>
|
|
57
|
+
<SidePanelOverlay />
|
|
58
|
+
<DialogPrimitive.Content
|
|
59
|
+
className={cn(
|
|
60
|
+
"fixed z-50 bg-white shadow-lg transition ease-in-out data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:duration-300 data-[state=open]:duration-500 flex flex-col",
|
|
61
|
+
side === "right" &&
|
|
62
|
+
"inset-y-0 right-0 h-full w-full border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right",
|
|
63
|
+
side === "left" &&
|
|
64
|
+
"inset-y-0 left-0 h-full w-full border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left",
|
|
65
|
+
width
|
|
66
|
+
)}
|
|
67
|
+
>
|
|
68
|
+
{/* Header fixe */}
|
|
69
|
+
<div className="flex items-center justify-between border-b border-ibm-gray-20 px-6 py-4 flex-shrink-0">
|
|
70
|
+
<div className="flex-1">
|
|
71
|
+
<DialogPrimitive.Title className="text-lg font-semibold text-ibm-gray-100">
|
|
72
|
+
{title}
|
|
73
|
+
</DialogPrimitive.Title>
|
|
74
|
+
{description && (
|
|
75
|
+
<DialogPrimitive.Description className="text-sm text-ibm-gray-60">
|
|
76
|
+
{description}
|
|
77
|
+
</DialogPrimitive.Description>
|
|
78
|
+
)}
|
|
79
|
+
</div>
|
|
80
|
+
<DialogPrimitive.Close
|
|
81
|
+
className="rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ibm-blue-60 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-ibm-gray-10"
|
|
82
|
+
onClick={onClose}
|
|
83
|
+
>
|
|
84
|
+
<X className="h-5 w-5 text-ibm-gray-70" />
|
|
85
|
+
<span className="sr-only">Close</span>
|
|
86
|
+
</DialogPrimitive.Close>
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
{/* Body scrollable */}
|
|
90
|
+
<div className="flex-1 overflow-y-auto px-6 py-6">
|
|
91
|
+
{children}
|
|
92
|
+
</div>
|
|
93
|
+
|
|
94
|
+
{/* Footer fixe */}
|
|
95
|
+
<div className="flex items-center justify-end gap-3 border-t border-ibm-gray-20 px-6 py-4 flex-shrink-0">
|
|
96
|
+
{actions}
|
|
97
|
+
</div>
|
|
98
|
+
</DialogPrimitive.Content>
|
|
99
|
+
</SidePanelPortal>
|
|
100
|
+
</SidePanelRoot>
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Composants legacy pour compatibilité ascendante
|
|
31
105
|
interface SidePanelContentProps
|
|
32
106
|
extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {
|
|
33
107
|
side?: "left" | "right"
|
|
@@ -59,34 +133,19 @@ const SidePanelContent = React.forwardRef<
|
|
|
59
133
|
))
|
|
60
134
|
SidePanelContent.displayName = DialogPrimitive.Content.displayName
|
|
61
135
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
{...props}
|
|
76
|
-
>
|
|
77
|
-
<div className="flex-1">{children}</div>
|
|
78
|
-
{showCloseButton && (
|
|
79
|
-
<DialogPrimitive.Close
|
|
80
|
-
className="rounded-sm opacity-70 ring-offset-white transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ibm-blue-60 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-ibm-gray-10"
|
|
81
|
-
onClick={onClose}
|
|
82
|
-
>
|
|
83
|
-
<X className="h-5 w-5 text-ibm-gray-70" />
|
|
84
|
-
<span className="sr-only">Close</span>
|
|
85
|
-
</DialogPrimitive.Close>
|
|
86
|
-
)}
|
|
87
|
-
</div>
|
|
88
|
-
)
|
|
89
|
-
)
|
|
136
|
+
const SidePanelHeader = React.forwardRef<
|
|
137
|
+
HTMLDivElement,
|
|
138
|
+
React.HTMLAttributes<HTMLDivElement>
|
|
139
|
+
>(({ className, ...props }, ref) => (
|
|
140
|
+
<div
|
|
141
|
+
ref={ref}
|
|
142
|
+
className={cn(
|
|
143
|
+
"flex items-center justify-between border-b border-ibm-gray-20 px-6 py-4 flex-shrink-0",
|
|
144
|
+
className
|
|
145
|
+
)}
|
|
146
|
+
{...props}
|
|
147
|
+
/>
|
|
148
|
+
))
|
|
90
149
|
SidePanelHeader.displayName = "SidePanelHeader"
|
|
91
150
|
|
|
92
151
|
const SidePanelTitle = React.forwardRef<
|
|
@@ -132,7 +191,7 @@ const SidePanelFooter = React.forwardRef<
|
|
|
132
191
|
<div
|
|
133
192
|
ref={ref}
|
|
134
193
|
className={cn(
|
|
135
|
-
"flex items-center justify-end gap-3 border-t border-ibm-gray-20 px-6 py-4",
|
|
194
|
+
"flex items-center justify-end gap-3 border-t border-ibm-gray-20 px-6 py-4 flex-shrink-0",
|
|
136
195
|
className
|
|
137
196
|
)}
|
|
138
197
|
{...props}
|
|
@@ -150,4 +209,5 @@ export {
|
|
|
150
209
|
SidePanelDescription,
|
|
151
210
|
SidePanelBody,
|
|
152
211
|
SidePanelFooter,
|
|
212
|
+
SidePanelRoot,
|
|
153
213
|
}
|