@catalystsoftware/ui 1.0.4 → 1.0.5

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.
Files changed (157) hide show
  1. package/data/tailwind.config.js +261 -3821
  2. package/dist/components/catalyst-ui/buttons/burger.tsx +207 -0
  3. package/dist/components/catalyst-ui/core/data-display/timeline.tsx +210 -0
  4. package/dist/components/catalyst-ui/core/feedback/alert.tsx +491 -0
  5. package/dist/components/catalyst-ui/core/feedback/spinner-1.tsx +65 -0
  6. package/dist/components/catalyst-ui/core/feedback/toast.tsx +1857 -0
  7. package/dist/components/catalyst-ui/core/navigation/menu.tsx +164 -0
  8. package/dist/components/catalyst-ui/forms/toggle-class.tsx +176 -0
  9. package/dist/components/catalyst-ui/hooks/use-copy-to-clipboard.tsx +419 -0
  10. package/dist/components/catalyst-ui/hooks/use-counter.tsx +13 -0
  11. package/dist/components/catalyst-ui/hooks/use-event-listener.tsx +23 -0
  12. package/dist/components/catalyst-ui/hooks/use-export-markdown.tsx +47 -0
  13. package/dist/components/catalyst-ui/hooks/use-focus.tsx +17 -0
  14. package/dist/components/catalyst-ui/hooks/use-interval.tsx +23 -0
  15. package/dist/components/catalyst-ui/hooks/use-is-client.tsx +16 -0
  16. package/dist/components/catalyst-ui/hooks/use-media-query.tsx +19 -0
  17. package/dist/components/catalyst-ui/hooks/use-mobile.tsx +19 -0
  18. package/dist/components/catalyst-ui/hooks/use-resize-observer.tsx +81 -0
  19. package/dist/components/catalyst-ui/hooks/use-timeout.tsx +21 -0
  20. package/dist/components/catalyst-ui/hooks/use-timer.tsx +209 -0
  21. package/dist/components/catalyst-ui/hooks/use-toggle.tsx +12 -0
  22. package/dist/components/catalyst-ui/media/image.tsx +13 -0
  23. package/dist/components/catalyst-ui/overlays/dual-sidebar.tsx +4142 -0
  24. package/dist/components/catalyst-ui/overlays/sidebar-original.tsx +726 -0
  25. package/dist/components/catalyst-ui/primitives/accordion.tsx +250 -0
  26. package/dist/components/catalyst-ui/primitives/alert-dialog.tsx +126 -0
  27. package/dist/components/catalyst-ui/primitives/aspect-ratio.tsx +9 -0
  28. package/dist/components/catalyst-ui/primitives/avatar.tsx +296 -0
  29. package/dist/components/catalyst-ui/primitives/badge.tsx +57 -0
  30. package/dist/components/catalyst-ui/primitives/breadcrumb.tsx +101 -0
  31. package/dist/components/catalyst-ui/primitives/button.tsx +265 -0
  32. package/dist/components/catalyst-ui/primitives/calendar-v4.tsx +208 -0
  33. package/dist/components/catalyst-ui/primitives/calendar.tsx +295 -0
  34. package/dist/components/catalyst-ui/primitives/card.tsx +618 -0
  35. package/dist/components/catalyst-ui/primitives/carousel.tsx +238 -0
  36. package/dist/components/catalyst-ui/primitives/chart.tsx +347 -0
  37. package/dist/components/catalyst-ui/primitives/checkbox.tsx +225 -0
  38. package/dist/components/catalyst-ui/primitives/collapsible.tsx +212 -0
  39. package/dist/components/catalyst-ui/primitives/command.tsx +393 -0
  40. package/dist/components/catalyst-ui/primitives/context-menu.tsx +236 -0
  41. package/dist/components/catalyst-ui/primitives/dialog.tsx +471 -0
  42. package/dist/components/catalyst-ui/primitives/drawer.tsx +761 -0
  43. package/dist/components/catalyst-ui/primitives/dropdown-menu.tsx +290 -0
  44. package/dist/components/catalyst-ui/primitives/empty.tsx +104 -0
  45. package/dist/components/catalyst-ui/primitives/field.tsx +244 -0
  46. package/dist/components/catalyst-ui/primitives/hover-card.tsx +124 -0
  47. package/dist/components/catalyst-ui/primitives/input-otp.tsx +76 -0
  48. package/dist/components/catalyst-ui/primitives/input.tsx +64 -0
  49. package/dist/components/catalyst-ui/primitives/item.tsx +196 -0
  50. package/dist/components/catalyst-ui/primitives/kbd.tsx +75 -0
  51. package/dist/components/catalyst-ui/primitives/label.tsx +24 -0
  52. package/dist/components/catalyst-ui/primitives/navigation-menu.tsx +150 -0
  53. package/dist/components/catalyst-ui/primitives/pagination.tsx +198 -0
  54. package/dist/components/catalyst-ui/primitives/popover.tsx +232 -0
  55. package/dist/components/catalyst-ui/primitives/progress.tsx +34 -0
  56. package/dist/components/catalyst-ui/primitives/radio-group.tsx +43 -0
  57. package/dist/components/catalyst-ui/primitives/resizable.tsx +56 -0
  58. package/dist/components/catalyst-ui/primitives/select.tsx +155 -0
  59. package/dist/components/catalyst-ui/primitives/separator.tsx +74 -0
  60. package/dist/components/catalyst-ui/primitives/sheet.tsx +126 -0
  61. package/dist/components/catalyst-ui/primitives/skeleton.tsx +15 -0
  62. package/dist/components/catalyst-ui/primitives/slider.tsx +27 -0
  63. package/dist/components/catalyst-ui/primitives/switch.tsx +187 -0
  64. package/dist/components/catalyst-ui/primitives/tabs.tsx +335 -0
  65. package/dist/components/catalyst-ui/primitives/textarea.tsx +24 -0
  66. package/dist/components/catalyst-ui/primitives/toggle-group.tsx +55 -0
  67. package/dist/components/catalyst-ui/primitives/toggle.tsx +42 -0
  68. package/dist/components/catalyst-ui/primitives/tooltip.tsx +116 -0
  69. package/dist/components/catalyst-ui/utils/basic-auth.tsx +40 -0
  70. package/dist/components/catalyst-ui/utils/context-storage.tsx +19 -0
  71. package/dist/components/catalyst-ui/utils/cors-middleware.tsx +71 -0
  72. package/dist/components/catalyst-ui/utils/deferred-content.tsx +595 -0
  73. package/dist/components/catalyst-ui/utils/honeypot-middleware.tsx +38 -0
  74. package/dist/components/catalyst-ui/utils/incId.tsx +75 -0
  75. package/dist/components/catalyst-ui/utils/jwk-auth.tsx +36 -0
  76. package/dist/components/catalyst-ui/utils/request-id.tsx +14 -0
  77. package/dist/components/catalyst-ui/utils/secure-headers.tsx +37 -0
  78. package/dist/components/catalyst-ui/utils/server-timing.tsx +23 -0
  79. package/dist/components/catalyst-ui/utils/utils.ts +43 -0
  80. package/dist/components/catalyst-ui/utils/with-cookie.tsx +43 -0
  81. package/dist/components/catalyst-ui/x/accordian-x.tsx +428 -0
  82. package/dist/components/catalyst-ui/x/alert-x.tsx +413 -0
  83. package/dist/components/catalyst-ui/x/animated-text-x.tsx +2242 -0
  84. package/dist/components/catalyst-ui/x/avatar-x.tsx +515 -0
  85. package/dist/components/catalyst-ui/x/badge-x.tsx +670 -0
  86. package/dist/components/catalyst-ui/x/button-X.tsx +2857 -0
  87. package/dist/components/catalyst-ui/x/button-group-x.tsx +847 -0
  88. package/dist/components/catalyst-ui/x/calendar-x.tsx +1910 -0
  89. package/dist/components/catalyst-ui/x/card-x.tsx +2597 -0
  90. package/dist/components/catalyst-ui/x/checkbox-x.tsx +656 -0
  91. package/dist/components/catalyst-ui/x/collapsible-x.tsx +1360 -0
  92. package/dist/components/catalyst-ui/x/combobox-x.tsx +911 -0
  93. package/dist/components/catalyst-ui/x/data-table-x.tsx +1753 -0
  94. package/dist/components/catalyst-ui/x/date-picker-x.tsx +648 -0
  95. package/dist/components/catalyst-ui/x/dialog-x.tsx +659 -0
  96. package/dist/components/catalyst-ui/x/dropdown-menu-x.tsx +612 -0
  97. package/dist/components/catalyst-ui/x/hover-card-x.tsx +375 -0
  98. package/dist/components/catalyst-ui/x/icon-x.tsx +840 -0
  99. package/dist/components/catalyst-ui/x/input-mask-x.tsx +981 -0
  100. package/dist/components/catalyst-ui/x/input-otp-x.tsx +659 -0
  101. package/dist/components/catalyst-ui/x/loader-x.tsx +1757 -0
  102. package/dist/components/catalyst-ui/x/pagination-x.tsx +622 -0
  103. package/dist/components/catalyst-ui/x/popover-x.tsx +744 -0
  104. package/dist/components/catalyst-ui/x/radio-group-x.tsx +499 -0
  105. package/dist/components/catalyst-ui/x/select-x.tsx +1127 -0
  106. package/dist/components/catalyst-ui/x/sheet-x.tsx +668 -0
  107. package/dist/components/catalyst-ui/x/switch-x.tsx +681 -0
  108. package/dist/components/catalyst-ui/x/table-x.tsx +574 -0
  109. package/dist/components/catalyst-ui/x/tabs-x.tsx +839 -0
  110. package/dist/components/catalyst-ui/x/textarea-x.tsx +1263 -0
  111. package/dist/components/catalyst-ui/x/tooltip-x.tsx +396 -0
  112. package/dist/components/catalyst-ui/x/tracker-x.tsx +560 -0
  113. package/dist/data/bg-data.tsx +901 -0
  114. package/dist/data/buttons-data.tsx +2327 -0
  115. package/dist/data/charts-data.tsx +102 -0
  116. package/dist/data/chat-data.tsx +83 -0
  117. package/dist/data/code-data.tsx +1040 -0
  118. package/dist/data/comboboxes-data.tsx +1843 -0
  119. package/dist/data/command-data.tsx +1381 -0
  120. package/dist/data/core-data.tsx +15953 -0
  121. package/dist/data/crm-data.tsx +47 -0
  122. package/dist/data/data.tsx +159 -0
  123. package/dist/data/date-and-time-data.tsx +554 -0
  124. package/dist/data/dependencies.tsx +7 -0
  125. package/dist/data/ecommerce-data.tsx +1387 -0
  126. package/dist/data/forms-data.tsx +7890 -0
  127. package/dist/data/hooks-data.tsx +5487 -0
  128. package/dist/data/index.ts +34 -0
  129. package/dist/data/inputs-data.tsx +557 -0
  130. package/dist/data/interactive-data.tsx +5394 -0
  131. package/dist/data/lofi-data.tsx +18295 -0
  132. package/dist/data/marketing-data.tsx +2546 -0
  133. package/dist/data/media-data.tsx +1510 -0
  134. package/dist/data/motion-data.tsx +5801 -0
  135. package/dist/data/overlay-data.tsx +4136 -0
  136. package/dist/data/pdf-data.tsx +124 -0
  137. package/dist/data/pos-data.tsx +213 -0
  138. package/dist/data/postcss.config.js +6 -0
  139. package/dist/data/primitive-data.tsx +5170 -0
  140. package/dist/data/prompt-data.tsx +1226 -0
  141. package/dist/data/requiredLibs.ts +4 -0
  142. package/dist/data/sandbox-data.tsx +1 -0
  143. package/dist/data/sidebars-data.tsx +5421 -0
  144. package/dist/data/stacks-data.tsx +32 -0
  145. package/dist/data/table-data.tsx +706 -0
  146. package/dist/data/tailwind.config.js +270 -0
  147. package/dist/data/tailwind.config.ngin.js +3830 -0
  148. package/dist/data/tailwind.css +431 -0
  149. package/dist/data/tools-data.tsx +6910 -0
  150. package/dist/data/typography-data.tsx +2050 -0
  151. package/dist/data/utils-data.tsx +6500 -0
  152. package/dist/data/x-data.tsx +1171 -0
  153. package/dist/data.tsx +159 -0
  154. package/package.json +1 -1
  155. package/dist/index.d.ts +0 -3
  156. package/dist/index.d.ts.map +0 -1
  157. package/dist/index.js.map +0 -362
@@ -0,0 +1,4136 @@
1
+ // @dev app/components/catalyst-ui/overlays/expandable-screen.tsx:6
2
+ export const OverlayData = [
3
+ {
4
+ name: "Animated Modal",
5
+ value: "animated-modal",
6
+ importPath: "~/components/catalyst-ui/overlays/animated-modal",
7
+ multiImport: "AnimatedModal, AnimatedModalBody, AnimatedModalContent, AnimatedModalFooter, AnimatedModalTrigger, AnimatedModalCloseButton, AnimatedModalSuccessButton, useModal",
8
+ basicusage: `
9
+ <AnimatedModal>
10
+ <AnimatedModalTrigger>
11
+ Open Modal
12
+ </AnimatedModalTrigger>
13
+ <AnimatedModalBody>
14
+ <AnimatedModalContent>
15
+ Modal content here
16
+ </AnimatedModalContent>
17
+ <AnimatedModalFooter>
18
+ <AnimatedModalCloseButton>
19
+ Cancel
20
+ </AnimatedModalCloseButton>
21
+ </AnimatedModalFooter>
22
+ </AnimatedModalBody>
23
+ </AnimatedModal>
24
+
25
+ <AnimatedModal>
26
+ <AnimatedModalTrigger className="custom-class">
27
+ Open Modal
28
+ </AnimatedModalTrigger>
29
+ <AnimatedModalBody className="custom-body-class">
30
+ <AnimatedModalContent className="custom-content-class">
31
+ <h3>Modal Title</h3>
32
+ <p>Modal content goes here.</p>
33
+ </AnimatedModalContent>
34
+ <AnimatedModalFooter className="custom-footer-class">
35
+ <AnimatedModalCloseButton className="custom-close-class">
36
+ Cancel
37
+ </AnimatedModalCloseButton>
38
+ <AnimatedModalSuccessButton
39
+ onClick={() => console.log('Success')}
40
+ className="custom-success-class"
41
+ >
42
+ Confirm
43
+ </AnimatedModalSuccessButton>
44
+ </AnimatedModalFooter>
45
+ </AnimatedModalBody>
46
+ </AnimatedModal>`,
47
+ path: "/components/catalyst-ui/overlays/animated-modal.tsx",
48
+ source: null,
49
+ usagePath: null,
50
+ usage: `
51
+ export function AnimatedModalDemo() {
52
+ const handleSuccess = () => {
53
+ console.log("Success action performed!");
54
+ };
55
+
56
+ return (
57
+ <div className="space-y-8 p-6 max-w-2xl mx-auto">
58
+ <div>
59
+ <h2 className="text-2xl font-bold mb-4">Basic Animated Modal</h2>
60
+ <AnimatedModal>
61
+ <AnimatedModalTrigger>
62
+ Open Basic Modal
63
+ </AnimatedModalTrigger>
64
+ <AnimatedModalBody>
65
+ <AnimatedModalContent>
66
+ <h3 className="text-lg font-semibold mb-2">Basic Modal Title</h3>
67
+ <p className="text-muted-foreground">
68
+ This is a basic animated modal with smooth transitions.
69
+ </p>
70
+ </AnimatedModalContent>
71
+ <AnimatedModalFooter>
72
+ <AnimatedModalCloseButton>
73
+ Cancel
74
+ </AnimatedModalCloseButton>
75
+ </AnimatedModalFooter>
76
+ </AnimatedModalBody>
77
+ </AnimatedModal>
78
+ </div>
79
+
80
+ <div>
81
+ <h2 className="text-2xl font-bold mb-4">Modal with Success Action</h2>
82
+ <AnimatedModal>
83
+ <AnimatedModalTrigger>
84
+ Open Action Modal
85
+ </AnimatedModalTrigger>
86
+ <AnimatedModalBody>
87
+ <AnimatedModalContent>
88
+ <h3 className="text-lg font-semibold mb-2">Confirm Action</h3>
89
+ <p className="text-muted-foreground">
90
+ Are you sure you want to proceed with this action?
91
+ </p>
92
+ </AnimatedModalContent>
93
+ <AnimatedModalFooter className="gap-2">
94
+ <AnimatedModalCloseButton>
95
+ Cancel
96
+ </AnimatedModalCloseButton>
97
+ <AnimatedModalSuccessButton onClick={handleSuccess}>
98
+ Confirm
99
+ </AnimatedModalSuccessButton>
100
+ </AnimatedModalFooter>
101
+ </AnimatedModalBody>
102
+ </AnimatedModal>
103
+ </div>
104
+ </div>
105
+ );
106
+ }
107
+ `,
108
+ premium: true,
109
+ category: "Overlay",
110
+ tags: ["modal", "animated", "dialog", "overlay"],
111
+ features: ["Animated", "Accessible", "TypeScript", "Smooth Transitions"],
112
+ dependencies: ["framer-motion", "react", "@catalystsoftware/icons"],
113
+ props: {
114
+ "AnimatedModal": [
115
+ { name: "children", type: "ReactNode", default: "null" },
116
+ ],
117
+ "AnimatedModalTrigger": [
118
+ { name: "children", type: "ReactNode", default: "null" },
119
+ { name: "className", type: "string", default: "null" },
120
+ ],
121
+ "AnimatedModalCloseButton": [
122
+ { name: "children", type: "ReactNode", default: "null" },
123
+ { name: "className", type: "string", default: "null" },
124
+ ],
125
+ "AnimatedModalSuccessButton": [
126
+ { name: "children", type: "ReactNode", default: "null" },
127
+ { name: "className", type: "string", default: "null" },
128
+ { name: "onClick", type: "() => void", default: "null" },
129
+ ],
130
+ "AnimatedModalBody": [
131
+ { name: "children", type: "ReactNode", default: "null" },
132
+ { name: "className", type: "string", default: "null" },
133
+ ],
134
+ "AnimatedModalContent": [
135
+ { name: "children", type: "ReactNode", default: "null" },
136
+ { name: "className", type: "string", default: "null" },
137
+ ],
138
+ "AnimatedModalFooter": [
139
+ { name: "children", type: "ReactNode", default: "null" },
140
+ { name: "className", type: "string", default: "null" },
141
+ ],
142
+ },
143
+ desc: null,
144
+ status: null,
145
+ lastUpdated: null
146
+ },
147
+ {
148
+ name: "Dialog Stack",
149
+ value: "dialog-stack",
150
+ importPath: "~/components/catalyst-ui/overlays/dialog-stack",
151
+ multiImport: "DialogStack, DialogStackTrigger, DialogStackOverlay, DialogStackBody, DialogStackContent, DialogStackHeader, DialogStackTitle, DialogStackDescription, DialogStackFooter, DialogStackNext, DialogStackPrevious",
152
+ basicusage: null,
153
+ path: "/components/catalyst-ui/overlays/dialog-stack.tsx",
154
+ source: null,
155
+ usagePath: "/components/catalyst-ui/overlays/dialog-stack.tsx",
156
+ usage: null,
157
+ premium: true,
158
+ category: "Overlays",
159
+ tags: ["dialog", "modal", "stack", "navigation", "interactive"],
160
+ features: ["Stack Navigation", "Clickable Overlay", "Portal Rendering", "Controllable State"],
161
+ dependencies: ["@radix-ui/react-use-controllable-state", "@radix-ui/react-portal", "react"],
162
+ props: {
163
+ "DialogStack": [
164
+ { name: "open", type: "boolean", default: "null" },
165
+ { name: "defaultOpen", type: "boolean", default: "false" },
166
+ { name: "onOpenChange", type: "(open: boolean) => void", default: "null" },
167
+ { name: "clickable", type: "boolean", default: "false" },
168
+ { name: "className", type: "string", default: "null" }
169
+ ],
170
+ "DialogStackTrigger": [
171
+ { name: "asChild", type: "boolean", default: "false" },
172
+ { name: "className", type: "string", default: "null" },
173
+ { name: "onClick", type: "MouseEventHandler<HTMLButtonElement>", default: "null" }
174
+ ],
175
+ "DialogStackOverlay": [
176
+ { name: "className", type: "string", default: "null" }
177
+ ],
178
+ "DialogStackBody": [
179
+ { name: "className", type: "string", default: "null" },
180
+ { name: "children", type: "ReactElement<DialogStackChildProps>[] | ReactElement<DialogStackChildProps>", default: "null" }
181
+ ],
182
+ "DialogStackContent": [
183
+ { name: "index", type: "number", default: "0" },
184
+ { name: "offset", type: "number", default: "10" },
185
+ { name: "className", type: "string", default: "null" }
186
+ ],
187
+ "DialogStackHeader": [
188
+ { name: "className", type: "string", default: "null" }
189
+ ],
190
+ "DialogStackTitle": [
191
+ { name: "className", type: "string", default: "null" }
192
+ ],
193
+ "DialogStackDescription": [
194
+ { name: "className", type: "string", default: "null" }
195
+ ],
196
+ "DialogStackFooter": [
197
+ { name: "className", type: "string", default: "null" }
198
+ ],
199
+ "DialogStackNext": [
200
+ { name: "asChild", type: "boolean", default: "false" },
201
+ { name: "className", type: "string", default: "null" }
202
+ ],
203
+ "DialogStackPrevious": [
204
+ { name: "asChild", type: "boolean", default: "false" },
205
+ { name: "className", type: "string", default: "null" }
206
+ ]
207
+ },
208
+ desc: null,
209
+ status: null,
210
+ lastUpdated: null
211
+ },
212
+ {
213
+ name: "Animated Tooltip",
214
+ value: "animated-tooltip",
215
+ importPath: "~/components/catalyst-ui/overlays/animated-tooltip",
216
+ multiImport: null,
217
+ basicusage: null,
218
+ path: "/components/catalyst-ui/overlays/animated-tooltip.tsx",
219
+ source: null,
220
+ usagePath: "/components/catalyst-ui/overlays/animated-tooltip.tsx",
221
+ usage: null,
222
+ premium: true,
223
+ category: "Overlays",
224
+ tags: ["tooltip", "hover", "animation", "images", "interactive"],
225
+ features: ["Motion Tracking", "Spring Animations", "Gradient Effects", "Responsive"],
226
+ dependencies: ["motion/react", "react"],
227
+ props: {
228
+ "AnimatedTooltip": [
229
+ { name: "items", type: "AnimatedTooltipItem[]", default: "null" }
230
+ ]
231
+ },
232
+ desc: null,
233
+ status: null,
234
+ lastUpdated: null
235
+ },
236
+ {
237
+ name: "Dual Sidebar",
238
+ value: "dual-sidebar",
239
+ importPath: "~/components/catalyst-ui/overlays/dual-sidebar",
240
+ multiImport: "useDS, DSLeftRail, DSRightRail, DSHeader, DSContent, DSFooter, DSAvatar, DSAvatarImage, DSAvatarFallback, DSGroup, DSGroupAction, DSGroupContent, DSGroupLabel, DSInput, DSMenu, DSMenuAction, DSMenuBadge, DSMenuButton, DSMenuItem, DSMenuSkeleton, DSMenuSub, DSMenuSubButton, DSMenuSubItem, DSSeparator, DSMenuAnchor, DSMenuLink, DSLoading, useDSTheme, DSThemeSelector, type DSTheme, DSThemeProvider, DSProvider, DSInset, DSTrigger, DSLeft, DSLeftIcon, DSRight, DSRightIcon, DSD, DSDBottom, DSDTrigger, DSDPortal, DSDClose, DSDOverlay, DSDContent, DSDHeader, DSDFooter, DSDTitle, DSDDescription, DSDM, DSDMPortal, DSDMTrigger, DSDMContent, DSDMGroup, DSDMLabel, DSDMItem, DSDMCheckboxItem, DSDMRadioGroup, DSDMRadioItem, DSDMSeparator, DSDMShortcut, DSDMSub, DSDMSubTrigger, DSDMSubContent, DSDMAnchor, DSC, DSCTrigger, DSCContent",
241
+ basicusage: `
242
+ <DSProvider defaultOpenLeft={true} defaultOpenRight={false}>
243
+ <DSLeft variant="sidebar" collapsible="offcanvas">
244
+ <DSHeader>
245
+ <DSTrigger side="left" />
246
+ </DSHeader>
247
+ <DSContent>
248
+ <DSMenu>
249
+ <DSMenuItem>
250
+ <DSMenuButton side="left">
251
+ Menu Item 1
252
+ </DSMenuButton>
253
+ </DSMenuItem>
254
+ </DSMenu>
255
+ </DSContent>
256
+ </DSLeft>
257
+
258
+ <DSInset>
259
+ <div className="p-4">
260
+ Main content area
261
+ </div>
262
+ </DSInset>
263
+
264
+ <DSRight variant="sidebar" collapsible="offcanvas">
265
+ <DSHeader>
266
+ <DSTrigger side="right" />
267
+ </DSHeader>
268
+ <DSContent>
269
+ <DSMenu>
270
+ <DSMenuItem>
271
+ <DSMenuButton side="right">
272
+ Menu Item 1
273
+ </DSMenuButton>
274
+ </DSMenuItem>
275
+ </DSMenu>
276
+ </DSContent>
277
+ </DSRight>
278
+ </DSProvider>`,
279
+ path: "/components/catalyst-ui/overlays/dual-sidebar.tsx",
280
+ source: null,
281
+ usagePath: null,
282
+ usage: `
283
+ export default function DSExample() {
284
+ const [activePage, setActivePage] = React.useState('home');
285
+ const data = {
286
+ user: {
287
+ name: "shadcn",
288
+ email: "m@example.com",
289
+ avatar: "/avatars/shadcn.jpg",
290
+ },
291
+ navMain: [
292
+ {
293
+ title: "Inbox",
294
+ url: "#",
295
+ icon: Inbox,
296
+ isActive: true,
297
+ },
298
+ {
299
+ title: "Drafts",
300
+ url: "#",
301
+ icon: File,
302
+ isActive: false,
303
+ },
304
+ {
305
+ title: "Sent",
306
+ url: "#",
307
+ icon: Send,
308
+ isActive: false,
309
+ },
310
+ {
311
+ title: "Junk",
312
+ url: "#",
313
+ icon: ArchiveX,
314
+ isActive: false,
315
+ },
316
+ {
317
+ title: "Trash",
318
+ url: "#",
319
+ icon: Trash2,
320
+ isActive: false,
321
+ },
322
+ ],
323
+ }
324
+ const [activeItem, setActiveItem] = React.useState(data.navMain[0])
325
+ const [mails, setMails] = React.useState(data.mails)
326
+ return (
327
+ <div className="bg-[#111827] w-[100vw] h-[100vh] overflow-hidden">
328
+ {/* Left Sidebar */}
329
+ <DSProvider>
330
+ <DSLeft variant="inset">
331
+ <DSHeader>
332
+ <h2 className="text-xl font-bold">My App</h2>
333
+ <p className="text-sm text-gray-400">Navigation</p>
334
+ </DSHeader>
335
+
336
+ <DSContent>
337
+ <DSGroup>
338
+ <DSGroupLabel>Main Menu</DSGroupLabel>
339
+ <DSGroupContent>
340
+ <DSMenu>
341
+ <DSMenuItem>
342
+ <DSMenuButton
343
+ icon={<Home size={20} />}
344
+ isActive={activePage === 'home'}
345
+ onClick={() => setActivePage('home')}
346
+ >
347
+ Home
348
+ </DSMenuButton>
349
+ </DSMenuItem>
350
+
351
+ </DSMenu>
352
+ </DSGroupContent>
353
+ </DSGroup>
354
+
355
+ <DSGroup>
356
+ <DSGroupLabel>Settings</DSGroupLabel>
357
+ <DSGroupContent>
358
+ <DSMenu>
359
+ <DSMenuItem>
360
+ <DSMenuButton
361
+ icon={<Settings size={20} />}
362
+ isActive={activePage === 'settings'}
363
+ onClick={() => setActivePage('settings')}
364
+ >
365
+ Settings
366
+ </DSMenuButton>
367
+ </DSMenuItem>
368
+ </DSMenu>
369
+ </DSGroupContent>
370
+ </DSGroup>
371
+ </DSContent>
372
+
373
+ <DSFooter>
374
+ <div className="flex items-center gap-3">
375
+ <div className="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center">
376
+ JD
377
+ </div>
378
+ <div className="flex-1">
379
+ <p className="text-sm font-medium">John Doe</p>
380
+ <p className="text-xs text-gray-400">john@example.com</p>
381
+ </div>
382
+ </div>
383
+ </DSFooter>
384
+ </DSLeft>
385
+
386
+ <DSLeftIcon>
387
+ <DSHeader>
388
+ <DSMenu>
389
+ <DSMenuItem>
390
+ <DSMenuButton size="lg" asChild className="md:h-8 md:p-0" >
391
+ <a href="#">
392
+ <div className="bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg">
393
+ <Command className="size-4" />
394
+ </div>
395
+ </a>
396
+ </DSMenuButton>
397
+ </DSMenuItem>
398
+ </DSMenu>
399
+ </DSHeader>
400
+
401
+ <DSContent>
402
+ <DSGroup>
403
+ <DSGroupContent>
404
+ <DSMenu>
405
+ {data.navMain.map((item) => (
406
+ <DSMenuItem key={item.title}>
407
+ <DSMenuButton
408
+ tooltip={{
409
+ children: item.title,
410
+ hidden: false,
411
+ }}
412
+ onClick={() => {
413
+ setActiveItem(item)
414
+ const mail = data.mails.sort(() => Math.random() - 0.5)
415
+ setMails(
416
+ mail.slice(
417
+ 0,
418
+ Math.max(5, Math.floor(Math.random() * 10) + 1)
419
+ )
420
+ )
421
+ setOpen(true)
422
+ }}
423
+ isActive={activeItem?.title === item.title}
424
+ className="px-2.5 md:px-2"
425
+ >
426
+ <item.icon />
427
+ <span>{item.title}</span>
428
+ </DSMenuButton>
429
+ </DSMenuItem>
430
+ ))}
431
+ <DSMenuItem>
432
+ <DSMenuButton>
433
+ <DSD>
434
+ <DSDTrigger>
435
+ <Button variant="ghost" size='icon'><Ghost /></Button>
436
+ </DSDTrigger>
437
+ <DSDContent>
438
+
439
+ </DSDContent>
440
+ </DSD>
441
+ </DSMenuButton>
442
+ </DSMenuItem>
443
+ </DSMenu>
444
+ </DSGroupContent>
445
+ </DSGroup>
446
+ </DSContent>
447
+
448
+ <DSFooter>
449
+ <NavUser user={data.user} />
450
+ </DSFooter>
451
+ </DSLeftIcon>
452
+
453
+ <DSInset>
454
+ <div className="items-center justify-center">
455
+ <div className="flex items-center justify-between p-4 border-b mx-auto">
456
+ <DSTrigger />
457
+ <DSThemeSelector >
458
+ <Zap className="text-primary" />
459
+ </DSThemeSelector>
460
+ <DSTrigger side='right' />
461
+ </div>
462
+ <div className="flex-1 p-4 overflow-y-auto">
463
+ <OutletContent />
464
+ </div>
465
+ </div>
466
+ </DSInset>
467
+
468
+ <DSRightIcon>
469
+ <DSHeader>
470
+ <DSMenu>
471
+ <DSMenuItem>
472
+ <DSMenuButton size="lg" asChild className="md:h-8 md:p-0" >
473
+ <a href="#">
474
+ <div className="bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg">
475
+ <Command className="size-4" />
476
+ </div>
477
+ </a>
478
+ </DSMenuButton>
479
+ </DSMenuItem>
480
+ </DSMenu>
481
+ </DSHeader>
482
+
483
+ <DSContent>
484
+ <DSGroup>
485
+ <DSGroupContent>
486
+ <DSMenu>
487
+ {data.navMain.map((item) => (
488
+ <DSMenuItem key={item.title}>
489
+ <DSMenuButton
490
+ tooltip={{
491
+ children: item.title,
492
+ hidden: false,
493
+ }}
494
+ onClick={() => {
495
+ setActiveItem(item)
496
+ const mail = data.mails.sort(() => Math.random() - 0.5)
497
+ setMails(
498
+ mail.slice(
499
+ 0,
500
+ Math.max(5, Math.floor(Math.random() * 10) + 1)
501
+ )
502
+ )
503
+ setOpen(true)
504
+ }}
505
+ isActive={activeItem?.title === item.title}
506
+ className="px-2.5 md:px-2"
507
+ >
508
+ <item.icon />
509
+ <span>{item.title}</span>
510
+ </DSMenuButton>
511
+ </DSMenuItem>
512
+ ))}
513
+ <DSMenuItem>
514
+ <DSMenuButton>
515
+ <DSDBottom>
516
+ <DSDTrigger>
517
+ <Button variant="ghost" size='icon'><Ghost /></Button>
518
+ </DSDTrigger>
519
+ <DSDContent>
520
+
521
+ </DSDContent>
522
+ </DSDBottom>
523
+ </DSMenuButton>
524
+ </DSMenuItem>
525
+
526
+ </DSMenu>
527
+ </DSGroupContent>
528
+ </DSGroup>
529
+ </DSContent>
530
+
531
+ <DSFooter>
532
+ <NavUser user={data.user} />
533
+ </DSFooter>
534
+ </DSRightIcon>
535
+
536
+ <DSRight variant="inset">
537
+ <DSHeader>
538
+ <div className="flex items-center gap-2">
539
+ <Bell size={20} />
540
+ <h2 className="text-lg font-bold">Activity</h2>
541
+ </div>
542
+ </DSHeader>
543
+
544
+ <DSContent>
545
+ <DSGroup>
546
+ <DSGroupLabel>Recent Notifications</DSGroupLabel>
547
+ <DSGroupContent>
548
+ <div className="space-y-3">
549
+ <div className="p-3 bg-gray-800 rounded-lg">
550
+ <p className="text-sm font-medium">New message</p>
551
+ <p className="text-xs text-gray-400">5 minutes ago</p>
552
+ </div>
553
+ </div>
554
+ </DSGroupContent>
555
+ </DSGroup>
556
+
557
+ <DSGroup>
558
+ <DSGroupLabel>Quick Actions</DSGroupLabel>
559
+ <DSGroupContent>
560
+ <div className="space-y-2">
561
+ <Button>New Project</Button>
562
+ <Button>Invite User</Button>
563
+ </div>
564
+ </DSGroupContent>
565
+ </DSGroup>
566
+ </DSContent>
567
+
568
+ <DSFooter>
569
+ <Input placeholder="Search..." />
570
+ </DSFooter>
571
+ </DSRight>
572
+ </DSProvider>
573
+ </div>
574
+ );
575
+ }`,
576
+ premium: false,
577
+ category: "Overlay",
578
+ tags: ["layout", "sidebar", "navigation", "dual", "responsive", "collapsible"],
579
+ features: [
580
+ "Dual Sidebar Layout",
581
+ "Left & Right Sidebars",
582
+ "Responsive Mobile Views",
583
+ "Collapsible Variants",
584
+ "Icon Sidebars",
585
+ "Keyboard Shortcuts (⌘B, ⌘G)",
586
+ "Theme System",
587
+ "Floating & Inset Variants",
588
+ "Top & Bottom Drawers",
589
+ "TypeScript",
590
+ "Accessible"
591
+ ],
592
+ dependencies: [
593
+ "lucide-react",
594
+ "react",
595
+ "@radix-ui/react-slot",
596
+ "class-variance-authority",
597
+ "@remix-run/react",
598
+ "vaul"
599
+ ],
600
+ props: {
601
+ // PROVIDER & CORE LAYOUT
602
+ "DSProvider": [
603
+ { name: "defaultOpenLeft", type: "boolean", default: "false", description: "Default open state of the sidebar." },
604
+ { name: "defaultOpenRight", type: "boolean", default: "false", description: "Default open state of the sidebar." },
605
+ { name: "defaultWidth", type: "string", default: "275px" },
606
+ { name: "className", type: "string", default: "undefined" },
607
+ { name: "style", type: "React.CSSProperties", default: "undefined", description: "Can pass through values like '--dual-sidebar-width-icon': DS_WIDTH_ICON, to be used within the style prop" },
608
+ { name: "children", type: "React.ReactNode", default: "required" }
609
+ ],
610
+ "DSLeft": [
611
+ { name: "variant", type: "sidebar | floating | inset | frosted | card | glass | compact-card | bordered | minimal | elevated", default: "sidebar" },
612
+ { name: "collapsible", type: "offcanvas | icon | none", default: "offcanvas", description: "Collapsible state of the sidebar." },
613
+ { name: "loadingUI", type: "boolean", default: "true" },
614
+ { name: "className", type: "string", default: "undefined" },
615
+ { name: "children", type: "React.ReactNode", default: "required" }
616
+ ],
617
+ "DSRight": [
618
+ { name: "variant", type: "sidebar | floating | inset | frosted | card | glass | compact-card | bordered | minimal | elevated", default: "sidebar" },
619
+ { name: "collapsible", type: "offcanvas | icon | none", default: "offcanvas" },
620
+ { name: "loadingUI", type: "boolean", default: "true" },
621
+ { name: "className", type: "string", default: "undefined" },
622
+ { name: "children", type: "React.ReactNode", default: "required" }
623
+ ],
624
+ "DSLeftIcon": [
625
+ { name: "iconWidth", type: "string", default: "48px" },
626
+ { name: "variant", type: "sidebar | floating | inset | frosted | card | glass | compact-card | bordered | minimal | elevated", default: "sidebar" },
627
+ { name: "className", type: "string", default: "undefined" },
628
+ { name: "children", type: "React.ReactNode", default: "required" }
629
+ ],
630
+ "DSRightIcon": [
631
+ { name: "iconWidth", type: "string", default: "48px" },
632
+ { name: "variant", type: "sidebar | floating | inset | frosted | card | glass | compact-card | bordered | minimal | elevated", default: "sidebar" },
633
+ { name: "className", type: "string", default: "undefined" },
634
+ { name: "children", type: "React.ReactNode", default: "required" }
635
+ ],
636
+ "DSInset": [
637
+ { name: "variant", type: "default | inset | card | bordered", default: "default" },
638
+ { name: "className", type: "string", default: "undefined" },
639
+ { name: "children", type: "React.ReactNode", default: "required" }
640
+ ],
641
+ // STRUCTURE COMPONENTS
642
+ "DSHeader": [
643
+ { name: "variant", type: "default | bordered | elevated | compact", default: "default" },
644
+ { name: "className", type: "string", default: "undefined" },
645
+ { name: "children", type: "React.ReactNode", default: "undefined" }
646
+ ],
647
+ "DSContent": [
648
+ { name: "className", type: "string", default: "undefined" },
649
+ { name: "children", type: "React.ReactNode", default: "undefined" }
650
+ ],
651
+ "DSFooter": [
652
+ { name: "variant", type: "default | bordered | elevated | compact", default: "default" },
653
+ { name: "className", type: "string", default: "undefined" },
654
+ { name: "children", type: "React.ReactNode", default: "undefined" }
655
+ ],
656
+ // MENU SYSTEM
657
+ "DSMenu": [
658
+ { name: "className", type: "string", default: "undefined" },
659
+ { name: "children", type: "React.ReactNode", default: "undefined" }
660
+ ],
661
+ "DSMenuItem": [
662
+ { name: "variant", type: "default | spaced | compact | comfortable", default: "default" },
663
+ { name: "className", type: "string", default: "undefined" },
664
+ { name: "children", type: "React.ReactNode", default: "undefined" }
665
+ ],
666
+ "DSMenuButton": [
667
+ { name: "side", type: "left | right", default: "required" },
668
+ { name: "asChild", type: "boolean", default: "false" },
669
+ { name: "isActive", type: "boolean", default: "false" },
670
+ { name: "tooltip", type: "string | TooltipContentProps", default: "undefined" },
671
+ { name: "variant", type: "default | ghost | outline | soft | solid | minimal | bordered | pill", default: "default" },
672
+ { name: "size", type: "default | sm | lg | icon", default: "default" },
673
+ { name: "className", type: "string", default: "undefined" },
674
+ { name: "children", type: "React.ReactNode", default: "undefined" }
675
+ ],
676
+ "DSMenuAction": [
677
+ { name: "asChild", type: "boolean", default: "false" },
678
+ { name: "showOnHover", type: "boolean", default: "false" },
679
+ { name: "className", type: "string", default: "undefined" },
680
+ { name: "children", type: "React.ReactNode", default: "undefined" }
681
+ ],
682
+ "DSMenuBadge": [
683
+ { name: "variant", type: "default | primary | secondary | success | warning | danger | outline | ghost | dot", default: "default" },
684
+ { name: "className", type: "string", default: "undefined" },
685
+ { name: "children", type: "React.ReactNode", default: "undefined" }
686
+ ],
687
+ "DSMenuSkeleton": [
688
+ { name: "showIcon", type: "boolean", default: "false" },
689
+ { name: "className", type: "string", default: "undefined" }
690
+ ],
691
+ "DSMenuSub": [
692
+ { name: "className", type: "string", default: "undefined" },
693
+ { name: "children", type: "React.ReactNode", default: "undefined" }
694
+ ],
695
+ "DSMenuSubItem": [
696
+ { name: "variant", type: "default | indented | dotted", default: "default" },
697
+ { name: "className", type: "string", default: "undefined" },
698
+ { name: "children", type: "React.ReactNode", default: "undefined" }
699
+ ],
700
+ "DSMenuSubButton": [
701
+ { name: "asChild", type: "boolean", default: "false" },
702
+ { name: "size", type: "default | sm | lg", default: "default" },
703
+ { name: "isActive", type: "boolean", default: "false" },
704
+ { name: "variant", type: "default | ghost | minimal | indent", default: "default" },
705
+ { name: "className", type: "string", default: "undefined" },
706
+ { name: "children", type: "React.ReactNode", default: "undefined" }
707
+ ],
708
+ "DSMenuLink": [
709
+ { name: "to", type: "string", default: "required" },
710
+ { name: "icon", type: "React.ReactNode", default: "undefined" },
711
+ { name: "tooltip", type: "string", default: "undefined" },
712
+ { name: "variant", type: "default | ghost | outline | soft | solid | minimal | bordered | pill", default: "default" },
713
+ { name: "size", type: "default | sm | lg | icon", default: "default" },
714
+ { name: "className", type: "string", default: "undefined" },
715
+ { name: "children", type: "React.ReactNode", default: "required" }
716
+ ],
717
+ "DSMenuAnchor": [
718
+ { name: "to", type: "string", default: "required" },
719
+ { name: "icon", type: "React.ReactNode", default: "undefined" },
720
+ { name: "tooltip", type: "string", default: "undefined" },
721
+ { name: "newTab", type: "boolean", default: "true" },
722
+ { name: "variant", type: "default | ghost | outline | soft | solid | minimal | bordered | pill", default: "default" },
723
+ { name: "size", type: "default | sm | lg | icon", default: "default" },
724
+ { name: "className", type: "string", default: "undefined" },
725
+ { name: "onClick", type: "React.MouseEventHandler", default: "undefined" },
726
+ { name: "children", type: "React.ReactNode", default: "required" }
727
+ ],
728
+ // GROUP SYSTEM
729
+ "DSGroup": [
730
+ { name: "variant", type: "default | separated | card | bordered | subtle", default: "default" },
731
+ { name: "className", type: "string", default: "undefined" },
732
+ { name: "children", type: "React.ReactNode", default: "undefined" }
733
+ ],
734
+ "DSGroupLabel": [
735
+ { name: "asChild", type: "boolean", default: "false" },
736
+ { name: "variant", type: "default | prominent | subtle | separated", default: "default" },
737
+ { name: "className", type: "string", default: "undefined" },
738
+ { name: "children", type: "React.ReactNode", default: "undefined" }
739
+ ],
740
+ "DSGroupAction": [
741
+ { name: "asChild", type: "boolean", default: "false" },
742
+ { name: "className", type: "string", default: "undefined" },
743
+ { name: "children", type: "React.ReactNode", default: "undefined" }
744
+ ],
745
+ "DSGroupContent": [
746
+ { name: "className", type: "string", default: "undefined" },
747
+ { name: "children", type: "React.ReactNode", default: "undefined" }
748
+ ],
749
+ // UI ELEMENTS
750
+ "DSTrigger": [
751
+ { name: "side", type: "left | right", default: "left" },
752
+ { name: "className", type: "string", default: "undefined" },
753
+ { name: "onClick", type: "React.MouseEventHandler", default: "undefined" }
754
+ ],
755
+ "DSBurger": [
756
+ { name: "opened", type: "boolean", default: "undefined" },
757
+ { name: "size", type: "sm | md | lg | xl", default: "md" },
758
+ { name: "color", type: "string", default: "currentColor" },
759
+ { name: "onClick", type: "() => void", default: "undefined" }
760
+ ],
761
+ "DSInput": [
762
+ { name: "className", type: "string", default: "undefined" },
763
+ { name: "type", type: "string", default: "text" },
764
+ { name: "placeholder", type: "string", default: "undefined" },
765
+ { name: "value", type: "string", default: "undefined" },
766
+ { name: "onChange", type: "React.ChangeEventHandler", default: "undefined" }
767
+ ],
768
+ "DSSeparator": [
769
+ { name: "variant", type: "default | thick | dashed | gradient", default: "default" },
770
+ { name: "spacing", type: "default | sm | lg | none", default: "default" },
771
+ { name: "className", type: "string", default: "undefined" },
772
+ { name: "orientation", type: "horizontal | vertical", default: "horizontal" }
773
+ ],
774
+ // RAIL COMPONENTS
775
+ "DSLeftRail": [
776
+ { name: "side", type: "left | right", default: "left" },
777
+ { name: "className", type: "string", default: "undefined" }
778
+ ],
779
+ "DSRightRail": [
780
+ { name: "side", type: "left | right", default: "right" },
781
+ { name: "className", type: "string", default: "undefined" }
782
+ ],
783
+ // THEME SYSTEM
784
+ "DSThemeSelector": [
785
+ { name: "size", type: "number", default: "28" },
786
+ { name: "className", type: "string", default: "undefined" },
787
+ { name: "children", type: "React.ReactNode", default: "required" }
788
+ ],
789
+ "DSThemeProvider": [
790
+ { name: "children", type: "React.ReactNode", default: "required" }
791
+ ],
792
+ // DRAWER SYSTEM - TOP/BOTTOM (Vaul)
793
+ // drawer top position
794
+ "DSD & DSD Bottom": [
795
+ { "name": "open", "type": "boolean", "default": "undefined" },
796
+ { "name": "defaultOpen", "type": "boolean", "default": "false" },
797
+ { "name": "onOpenChange", "type": "(open: boolean) => void", "default": "undefined" },
798
+ { "name": "shouldScaleBackground", "type": "boolean", "default": "false" },
799
+ { "name": "setBackgroundColorOnScale", "type": "boolean", "default": "true" },
800
+ { "name": "closeThreshold", "type": "number", "default": "0.5" },
801
+ { "name": "scrollLockTimeout", "type": "number", "default": "500" },
802
+ { "name": "snapPoints", "type": "(number | string)[]", "default": "undefined" },
803
+ { "name": "activeSnapPoint", "type": "number | string | null", "default": "undefined" },
804
+ { "name": "setActiveSnapPoint", "type": "(snapPoint: number | string | null) => void", "default": "undefined" },
805
+ { "name": "fadeFromIndex", "type": "number", "default": "snapPoints.length - 1" },
806
+ { "name": "modal", "type": "boolean", "default": "true" },
807
+ { "name": "handleOnly", "type": "boolean", "default": "false" },
808
+ { "name": "dismissible", "type": "boolean", "default": "true" },
809
+ { "name": "onDrag", "type": "(event: PointerEvent, percentageDragged: number) => void", "default": "undefined" },
810
+ { "name": "onRelease", "type": "(event: PointerEvent, open: boolean) => void", "default": "undefined" },
811
+ { "name": "noBodyStyles", "type": "boolean", "default": "false" },
812
+ { "name": "direction", "type": "'top' | 'bottom' | 'left' | 'right'", "default": "'bottom'" },
813
+ { "name": "preventScrollRestoration", "type": "boolean", "default": "true" },
814
+ { "name": "disablePreventScroll", "type": "boolean", "default": "false" },
815
+ { "name": "snapToSequentialPoint", "type": "boolean", "default": "false" },
816
+ { "name": "onAnimationEnd", "type": "(open: boolean) => void", "default": "undefined" },
817
+ { "name": "container", "type": "HTMLElement | null", "default": "document.body" },
818
+ { "name": "nested", "type": "boolean", "default": "false" },
819
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
820
+ ],
821
+ "DSDTrigger": [
822
+ { "name": "asChild", "type": "boolean", "default": "false" },
823
+ { "name": "className", "type": "string", "default": "undefined" },
824
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
825
+ ],
826
+ "DSDPortal": [
827
+ { "name": "container", "type": "HTMLElement | null", "default": "document.body" },
828
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
829
+ ],
830
+ "DSDClose": [
831
+ { "name": "asChild", "type": "boolean", "default": "false" },
832
+ { "name": "className", "type": "string", "default": "undefined" },
833
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
834
+ ],
835
+ "DSDOverlay": [
836
+ { "name": "asChild", "type": "boolean", "default": "false" },
837
+ { "name": "className", "type": "string", "default": "undefined" }
838
+ ],
839
+ "DSDContent": [
840
+ { "name": "asChild", "type": "boolean", "default": "false" },
841
+ { "name": "className", "type": "string", "default": "undefined" },
842
+ { "name": "children", "type": "React.ReactNode", "default": "required" }
843
+ ],
844
+ "DSDTitle": [
845
+ { "name": "asChild", "type": "boolean", "default": "false" },
846
+ { "name": "className", "type": "string", "default": "undefined" },
847
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
848
+ ],
849
+ "DSDDescription": [
850
+ { "name": "asChild", "type": "boolean", "default": "false" },
851
+ { "name": "className", "type": "string", "default": "undefined" },
852
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
853
+ ],
854
+ // LOADING UI
855
+ "DSLoading": [
856
+ { name: "variant", type: "default | minimal | card | centered", default: "default" },
857
+ { name: "size", type: "default | sm | md | lg | full", default: "default" }
858
+ ],
859
+ // AVATAR SYSTEM
860
+ "DSA": [
861
+ { "name": "className", "type": "string", "default": "undefined" },
862
+ { "name": "asChild", "type": "boolean", "default": "false" }
863
+ ],
864
+ "DSAImage": [
865
+ { "name": "className", "type": "string", "default": "undefined" },
866
+ { "name": "src", "type": "string", "default": "required" },
867
+ { "name": "alt", "type": "string", "default": "required" },
868
+ { "name": "onLoadingStatusChange", "type": "function", "default": "undefined" },
869
+ { "name": "asChild", "type": "boolean", "default": "false" }
870
+ ],
871
+ "DSAFallback": [
872
+ { "name": "className", "type": "string", "default": "undefined" },
873
+ { "name": "delayMs", "type": "number", "default": "0" },
874
+ { "name": "asChild", "type": "boolean", "default": "false" }
875
+ ],
876
+ // DROPDOWN MENU SYSTEM
877
+ //
878
+ "DSDM": [
879
+ { "name": "defaultOpen", "type": "boolean", "default": "undefined" },
880
+ { "name": "open", "type": "boolean", "default": "undefined" },
881
+ { "name": "onOpenChange", "type": "(open: boolean) => void", "default": "undefined" },
882
+ { "name": "dir", "type": "'ltr' | 'rtl'", "default": "undefined" },
883
+ { "name": "modal", "type": "boolean", "default": "true" }
884
+ ],
885
+ "DSDMPortal": [
886
+ { "name": "forceMount", "type": "boolean", "default": "undefined" },
887
+ { "name": "container", "type": "HTMLElement | null", "default": "document.body" }
888
+ ],
889
+ "DSDMTrigger": [
890
+ { "name": "asChild", "type": "boolean", "default": "false" },
891
+ { "name": "disabled", "type": "boolean", "default": "false" }
892
+ ],
893
+ "DSDMContent": [
894
+ { "name": "className", "type": "string", "default": "undefined" },
895
+ { "name": "forceMount", "type": "boolean", "default": "undefined" },
896
+ { "name": "side", "type": "'top' | 'right' | 'bottom' | 'left'", "default": "'bottom'" },
897
+ { "name": "sideOffset", "type": "number", "default": "0" },
898
+ { "name": "align", "type": "'start' | 'center' | 'end'", "default": "'center'" },
899
+ { "name": "alignOffset", "type": "number", "default": "0" },
900
+ { "name": "avoidCollisions", "type": "boolean", "default": "true" },
901
+ { "name": "collisionBoundary", "type": "Element | Element[] | null", "default": "[]" },
902
+ { "name": "collisionPadding", "type": "number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>", "default": "0" },
903
+ { "name": "arrowPadding", "type": "number", "default": "0" },
904
+ { "name": "sticky", "type": "'partial' | 'always'", "default": "'partial'" },
905
+ { "name": "hideWhenDetached", "type": "boolean", "default": "false" },
906
+ { "name": "loop", "type": "boolean", "default": "false" },
907
+ { "name": "onCloseAutoFocus", "type": "(event: Event) => void", "default": "undefined" },
908
+ { "name": "onEscapeKeyDown", "type": "(event: KeyboardEvent) => void", "default": "undefined" },
909
+ { "name": "onPointerDownOutside", "type": "(event: PointerDownOutsideEvent) => void", "default": "undefined" },
910
+ { "name": "onFocusOutside", "type": "(event: FocusOutsideEvent) => void", "default": "undefined" },
911
+ { "name": "onInteractOutside", "type": "(event: PointerDownOutsideEvent | FocusOutsideEvent) => void", "default": "undefined" }
912
+ ],
913
+ "DSDMArrow": [
914
+ { "name": "className", "type": "string", "default": "undefined" },
915
+ { "name": "width", "type": "number", "default": "10" },
916
+ { "name": "height", "type": "number", "default": "5" },
917
+ { "name": "asChild", "type": "boolean", "default": "false" }
918
+ ],
919
+ "DSDMGroup": [
920
+ { "name": "asChild", "type": "boolean", "default": "false" }
921
+ ],
922
+ "DSDMLabel": [
923
+ { "name": "className", "type": "string", "default": "undefined" },
924
+ { "name": "asChild", "type": "boolean", "default": "false" }
925
+ ],
926
+ "DSDMItem": [
927
+ { "name": "className", "type": "string", "default": "undefined" },
928
+ { "name": "disabled", "type": "boolean", "default": "false" },
929
+ { "name": "onSelect", "type": "(event: Event) => void", "default": "undefined" },
930
+ { "name": "textValue", "type": "string", "default": "undefined" },
931
+ { "name": "asChild", "type": "boolean", "default": "false" }
932
+ ],
933
+ "DSDMCheckboxItem": [
934
+ { "name": "className", "type": "string", "default": "undefined" },
935
+ { "name": "checked", "type": "boolean | 'indeterminate'", "default": "undefined" },
936
+ { "name": "onCheckedChange", "type": "(checked: boolean) => void", "default": "undefined" },
937
+ { "name": "disabled", "type": "boolean", "default": "false" },
938
+ { "name": "onSelect", "type": "(event: Event) => void", "default": "undefined" },
939
+ { "name": "textValue", "type": "string", "default": "undefined" },
940
+ { "name": "asChild", "type": "boolean", "default": "false" }
941
+ ],
942
+ "DSDMRadioGroup": [
943
+ { "name": "value", "type": "string", "default": "undefined" },
944
+ { "name": "onValueChange", "type": "(value: string) => void", "default": "undefined" },
945
+ { "name": "asChild", "type": "boolean", "default": "false" }
946
+ ],
947
+ "DSDMRadioItem": [
948
+ { "name": "className", "type": "string", "default": "undefined" },
949
+ { "name": "value", "type": "string", "default": "required" },
950
+ { "name": "disabled", "type": "boolean", "default": "false" },
951
+ { "name": "onSelect", "type": "(event: Event) => void", "default": "undefined" },
952
+ { "name": "textValue", "type": "string", "default": "undefined" },
953
+ { "name": "asChild", "type": "boolean", "default": "false" }
954
+ ],
955
+ "DSDMItemIndicator": [
956
+ { "name": "className", "type": "string", "default": "undefined" },
957
+ { "name": "forceMount", "type": "boolean", "default": "undefined" },
958
+ { "name": "asChild", "type": "boolean", "default": "false" }
959
+ ],
960
+ "DSDMSeparator": [
961
+ { "name": "className", "type": "string", "default": "undefined" },
962
+ { "name": "asChild", "type": "boolean", "default": "false" }
963
+ ],
964
+ "DSDMSub": [
965
+ { "name": "defaultOpen", "type": "boolean", "default": "undefined" },
966
+ { "name": "open", "type": "boolean", "default": "undefined" },
967
+ { "name": "onOpenChange", "type": "(open: boolean) => void", "default": "undefined" }
968
+ ],
969
+ "DSDMSubTrigger": [
970
+ { "name": "className", "type": "string", "default": "undefined" },
971
+ { "name": "disabled", "type": "boolean", "default": "false" },
972
+ { "name": "textValue", "type": "string", "default": "undefined" },
973
+ { "name": "asChild", "type": "boolean", "default": "false" }
974
+ ],
975
+ "DSDMSubContent": [
976
+ { "name": "className", "type": "string", "default": "undefined" },
977
+ { "name": "forceMount", "type": "boolean", "default": "undefined" },
978
+ { "name": "side", "type": "'top' | 'right' | 'bottom' | 'left'", "default": "'right'" },
979
+ { "name": "sideOffset", "type": "number", "default": "0" },
980
+ { "name": "align", "type": "'start' | 'center' | 'end'", "default": "'start'" },
981
+ { "name": "alignOffset", "type": "number", "default": "0" },
982
+ { "name": "avoidCollisions", "type": "boolean", "default": "true" },
983
+ { "name": "collisionBoundary", "type": "Element | Element[] | null", "default": "[]" },
984
+ { "name": "collisionPadding", "type": "number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>", "default": "0" },
985
+ { "name": "arrowPadding", "type": "number", "default": "0" },
986
+ { "name": "sticky", "type": "'partial' | 'always'", "default": "'partial'" },
987
+ { "name": "hideWhenDetached", "type": "boolean", "default": "false" },
988
+ { "name": "loop", "type": "boolean", "default": "false" },
989
+ { "name": "onEscapeKeyDown", "type": "(event: KeyboardEvent) => void", "default": "undefined" },
990
+ { "name": "onPointerDownOutside", "type": "(event: PointerDownOutsideEvent) => void", "default": "undefined" },
991
+ { "name": "onFocusOutside", "type": "(event: FocusOutsideEvent) => void", "default": "undefined" },
992
+ { "name": "onInteractOutside", "type": "(event: PointerDownOutsideEvent | FocusOutsideEvent) => void", "default": "undefined" }
993
+ ],
994
+ // COLLAPSIBLE SYSTEM
995
+ //
996
+ "DSC": [
997
+ { "name": "defaultOpen", "type": "boolean", "default": "false" },
998
+ { "name": "open", "type": "boolean", "default": "undefined" },
999
+ { "name": "onOpenChange", "type": "(open: boolean) => void", "default": "undefined" },
1000
+ { "name": "disabled", "type": "boolean", "default": "false" },
1001
+ { "name": "asChild", "type": "boolean", "default": "false" }
1002
+ ],
1003
+ "DSCTrigger": [
1004
+ { "name": "asChild", "type": "boolean", "default": "false" },
1005
+ { "name": "disabled", "type": "boolean", "default": "false" }
1006
+ ],
1007
+ "DSCContent": [
1008
+ { "name": "className", "type": "string", "default": "undefined" },
1009
+ { "name": "forceMount", "type": "boolean", "default": "undefined" },
1010
+ { "name": "asChild", "type": "boolean", "default": "false" }
1011
+ ],
1012
+ // HOOKS
1013
+ "useDS": [
1014
+ { name: "leftState", type: "expanded | collapsed", default: "readonly", description: "The current state of the sidebar." },
1015
+ { name: "rightState", type: "expanded | collapsed", default: "readonly" },
1016
+ { name: "openLeft", type: "boolean", default: "readonly", description: "Whether the sidebar is open." },
1017
+ { name: "openRight", type: "boolean", default: "readonly" },
1018
+ { name: "setOpenLeft", type: "(open: boolean) => void", default: "readonly", description: "Sets the open state of the sidebar." },
1019
+ { name: "setOpenRight", type: "(open: boolean) => void", default: "readonly", description: "" },
1020
+ { name: "openMobile", type: "boolean", default: "readonly", description: "Whether the sidebar is open on mobile." },
1021
+ { name: "openMobileRight", type: "boolean", default: "readonly", description: "" },
1022
+ { name: "setOpenMobile", type: "(open: boolean) => void", default: "readonly", description: "Sets the open state of the sidebar on mobile." },
1023
+ { name: "setOpenMobileRight", type: "(open: boolean) => void", default: "readonly", description: "" },
1024
+ { name: "toggleLeft", type: "() => void", default: "readonly", description: "Toggles the sidebar. Desktop and mobile." },
1025
+ { name: "toggleRight", type: "() => void", default: "readonly", description: "" },
1026
+ { name: "isMobile", type: "boolean", default: "readonly", description: "Whether the sidebar is on mobile." },
1027
+ { name: "sidebarWidth", type: "number", default: "readonly", description: "Controls the default width value." },
1028
+ { name: "leftVariant", type: "SidebarVariant", default: "readonly", description: "States the current variant type, this is more so used within the source file." },
1029
+ { name: "rightVariant", type: "SidebarVariant", default: "readonly", description: "" },
1030
+ { name: "setLeftVariant", type: "(variant: SidebarVariant) => void", default: "readonly", description: "Sets the state the current variant type, this is more so used within the source file" },
1031
+ { name: "setRightVariant", type: "(variant: SidebarVariant) => void", default: "readonly", description: "" },
1032
+ { name: "isIconLeftActive", type: "boolean", default: "readonly", description: "Checks if icon sidebars are actively used." },
1033
+ { name: "isIconRightActive", type: "boolean", default: "readonly", description: "" },
1034
+ { name: "setIsIconLeftActive", type: "(open: boolean) => void", default: "readonly", description: "Sets isIconLeftActive state, used within the source file." },
1035
+ { name: "setIsIconRightActive", type: "(open: boolean) => void", default: "readonly", description: "" },
1036
+ { name: "iconLeftWidth", type: "number", default: "readonly", description: "Controls the default width value." },
1037
+ { name: "iconRightWidth", type: "number", default: "readonly", description: "" },
1038
+ { name: "setIconLeftWidth", type: "(width: number) => void", default: "readonly", description: "Sets setIconLeftWidth state, used within the source file." },
1039
+ { name: "setIconRightWidth", type: "(width: number) => void", default: "readonly", description: "" },
1040
+ { name: "topHeight", type: "string", default: "readonly", description: "Sets height for inset variant styles." },
1041
+ { name: "setTopHeight", type: "(height: string) => void", default: "readonly", description: "" },
1042
+ { name: "bottomHeight", type: "string", default: "readonly", description: "" },
1043
+ { name: "setBottomHeight", type: "(height: string) => void", default: "readonly", description: "" }
1044
+ ],
1045
+ "useDSTheme": [
1046
+ { name: "theme", type: "DSTheme", default: "readonly" },
1047
+ { name: "setTheme", type: "(theme: DSTheme) => void", default: "readonly" },
1048
+ { name: "themeVars", type: "Record<string, string>", default: "readonly" }
1049
+ ]
1050
+ },
1051
+ desc: "A comprehensive dual sidebar layout system with left and right collapsible sidebars, support for multiple variants including icon sidebars, theme system, responsive mobile views, keyboard shortcuts, and top/bottom drawer support. Perfect for complex application layouts requiring flexible navigation structures.",
1052
+ status: "stable",
1053
+ lastUpdated: "2024-11-03"
1054
+ },
1055
+ {
1056
+ name: "Dual Sidebar Agnostic",
1057
+ value: "dual-sidebar-agnostic",
1058
+ importPath: "~/components/catalyst-ui/overlays/dual-sidebar-agnostic",
1059
+ multiImport: "useDS, DSLeftRail, DSRightRail, DSHeader, DSContent, DSFooter, DSAvatar, DSAvatarImage, DSAvatarFallback, DSGroup, DSGroupAction, DSGroupContent, DSGroupLabel, DSInput, DSMenu, DSMenuAction, DSMenuBadge, DSMenuButton, DSMenuItem, DSMenuSkeleton, DSMenuSub, DSMenuSubButton, DSMenuSubItem, DSSeparator, DSMenuAnchor, DSMenuLink, DSLoading, useDSTheme, DSThemeSelector, type DSTheme, DSThemeProvider, DSProvider, DSInset, DSTrigger, DSLeft, DSLeftIcon, DSRight, DSRightIcon, DSD, DSDBottom, DSDTrigger, DSDPortal, DSDClose, DSDOverlay, DSDContent, DSDHeader, DSDFooter, DSDTitle, DSDDescription, DSDM, DSDMPortal, DSDMTrigger, DSDMContent, DSDMGroup, DSDMLabel, DSDMItem, DSDMCheckboxItem, DSDMRadioGroup, DSDMRadioItem, DSDMSeparator, DSDMShortcut, DSDMSub, DSDMSubTrigger, DSDMSubContent, DSDMAnchor, DSC, DSCTrigger, DSCContent",
1060
+ basicusage: `
1061
+ <DSProvider defaultOpenLeft={true} defaultOpenRight={false}>
1062
+ <DSLeft variant="sidebar" collapsible="offcanvas">
1063
+ <DSHeader>
1064
+ <DSTrigger side="left" />
1065
+ </DSHeader>
1066
+ <DSContent>
1067
+ <DSMenu>
1068
+ <DSMenuItem>
1069
+ <DSMenuButton side="left">
1070
+ Menu Item 1
1071
+ </DSMenuButton>
1072
+ </DSMenuItem>
1073
+ </DSMenu>
1074
+ </DSContent>
1075
+ </DSLeft>
1076
+
1077
+ <DSInset>
1078
+ <div className="p-4">
1079
+ Main content area
1080
+ </div>
1081
+ </DSInset>
1082
+
1083
+ <DSRight variant="sidebar" collapsible="offcanvas">
1084
+ <DSHeader>
1085
+ <DSTrigger side="right" />
1086
+ </DSHeader>
1087
+ <DSContent>
1088
+ <DSMenu>
1089
+ <DSMenuItem>
1090
+ <DSMenuButton side="right">
1091
+ Menu Item 1
1092
+ </DSMenuButton>
1093
+ </DSMenuItem>
1094
+ </DSMenu>
1095
+ </DSContent>
1096
+ </DSRight>
1097
+ </DSProvider>`,
1098
+ path: "/components/catalyst-ui/components/overlay/dual-sidebar-agnostic.tsx",
1099
+ source: null,
1100
+ usagePath: null,
1101
+ usage: `
1102
+ export default function DSExample() {
1103
+ const [activePage, setActivePage] = React.useState('home');
1104
+ const data = {
1105
+ user: {
1106
+ name: "shadcn",
1107
+ email: "m@example.com",
1108
+ avatar: "/avatars/shadcn.jpg",
1109
+ },
1110
+ navMain: [
1111
+ {
1112
+ title: "Inbox",
1113
+ url: "#",
1114
+ icon: Inbox,
1115
+ isActive: true,
1116
+ },
1117
+ {
1118
+ title: "Drafts",
1119
+ url: "#",
1120
+ icon: File,
1121
+ isActive: false,
1122
+ },
1123
+ {
1124
+ title: "Sent",
1125
+ url: "#",
1126
+ icon: Send,
1127
+ isActive: false,
1128
+ },
1129
+ {
1130
+ title: "Junk",
1131
+ url: "#",
1132
+ icon: ArchiveX,
1133
+ isActive: false,
1134
+ },
1135
+ {
1136
+ title: "Trash",
1137
+ url: "#",
1138
+ icon: Trash2,
1139
+ isActive: false,
1140
+ },
1141
+ ],
1142
+ }
1143
+ const [activeItem, setActiveItem] = React.useState(data.navMain[0])
1144
+ const [mails, setMails] = React.useState(data.mails)
1145
+ return (
1146
+ <div className="bg-[#111827] w-[100vw] h-[100vh] overflow-hidden">
1147
+ {/* Left Sidebar */}
1148
+ <DSProvider>
1149
+ <DSLeft variant="inset">
1150
+ <DSHeader>
1151
+ <h2 className="text-xl font-bold">My App</h2>
1152
+ <p className="text-sm text-gray-400">Navigation</p>
1153
+ </DSHeader>
1154
+
1155
+ <DSContent>
1156
+ <DSGroup>
1157
+ <DSGroupLabel>Main Menu</DSGroupLabel>
1158
+ <DSGroupContent>
1159
+ <DSMenu>
1160
+ <DSMenuItem>
1161
+ <DSMenuButton
1162
+ icon={<Home size={20} />}
1163
+ isActive={activePage === 'home'}
1164
+ onClick={() => setActivePage('home')}
1165
+ >
1166
+ Home
1167
+ </DSMenuButton>
1168
+ </DSMenuItem>
1169
+
1170
+ </DSMenu>
1171
+ </DSGroupContent>
1172
+ </DSGroup>
1173
+
1174
+ <DSGroup>
1175
+ <DSGroupLabel>Settings</DSGroupLabel>
1176
+ <DSGroupContent>
1177
+ <DSMenu>
1178
+ <DSMenuItem>
1179
+ <DSMenuButton
1180
+ icon={<Settings size={20} />}
1181
+ isActive={activePage === 'settings'}
1182
+ onClick={() => setActivePage('settings')}
1183
+ >
1184
+ Settings
1185
+ </DSMenuButton>
1186
+ </DSMenuItem>
1187
+ </DSMenu>
1188
+ </DSGroupContent>
1189
+ </DSGroup>
1190
+ </DSContent>
1191
+
1192
+ <DSFooter>
1193
+ <div className="flex items-center gap-3">
1194
+ <div className="w-8 h-8 bg-blue-500 rounded-full flex items-center justify-center">
1195
+ JD
1196
+ </div>
1197
+ <div className="flex-1">
1198
+ <p className="text-sm font-medium">John Doe</p>
1199
+ <p className="text-xs text-gray-400">john@example.com</p>
1200
+ </div>
1201
+ </div>
1202
+ </DSFooter>
1203
+ </DSLeft>
1204
+
1205
+ <DSLeftIcon>
1206
+ <DSHeader>
1207
+ <DSMenu>
1208
+ <DSMenuItem>
1209
+ <DSMenuButton size="lg" asChild className="md:h-8 md:p-0" >
1210
+ <a href="#">
1211
+ <div className="bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg">
1212
+ <Command className="size-4" />
1213
+ </div>
1214
+ </a>
1215
+ </DSMenuButton>
1216
+ </DSMenuItem>
1217
+ </DSMenu>
1218
+ </DSHeader>
1219
+
1220
+ <DSContent>
1221
+ <DSGroup>
1222
+ <DSGroupContent>
1223
+ <DSMenu>
1224
+ {data.navMain.map((item) => (
1225
+ <DSMenuItem key={item.title}>
1226
+ <DSMenuButton
1227
+ tooltip={{
1228
+ children: item.title,
1229
+ hidden: false,
1230
+ }}
1231
+ onClick={() => {
1232
+ setActiveItem(item)
1233
+ const mail = data.mails.sort(() => Math.random() - 0.5)
1234
+ setMails(
1235
+ mail.slice(
1236
+ 0,
1237
+ Math.max(5, Math.floor(Math.random() * 10) + 1)
1238
+ )
1239
+ )
1240
+ setOpen(true)
1241
+ }}
1242
+ isActive={activeItem?.title === item.title}
1243
+ className="px-2.5 md:px-2"
1244
+ >
1245
+ <item.icon />
1246
+ <span>{item.title}</span>
1247
+ </DSMenuButton>
1248
+ </DSMenuItem>
1249
+ ))}
1250
+ <DSMenuItem>
1251
+ <DSMenuButton>
1252
+ <DSD>
1253
+ <DSDTrigger>
1254
+ <Button variant="ghost" size='icon'><Ghost /></Button>
1255
+ </DSDTrigger>
1256
+ <DSDContent>
1257
+
1258
+ </DSDContent>
1259
+ </DSD>
1260
+ </DSMenuButton>
1261
+ </DSMenuItem>
1262
+ </DSMenu>
1263
+ </DSGroupContent>
1264
+ </DSGroup>
1265
+ </DSContent>
1266
+
1267
+ <DSFooter>
1268
+ <NavUser user={data.user} />
1269
+ </DSFooter>
1270
+ </DSLeftIcon>
1271
+
1272
+ <DSInset>
1273
+ <div className="items-center justify-center">
1274
+ <div className="flex items-center justify-between p-4 border-b mx-auto">
1275
+ <DSTrigger />
1276
+ <DSThemeSelector >
1277
+ <Zap className="text-primary" />
1278
+ </DSThemeSelector>
1279
+ <DSTrigger side='right' />
1280
+ </div>
1281
+ <div className="flex-1 p-4 overflow-y-auto">
1282
+ <OutletContent />
1283
+ </div>
1284
+ </div>
1285
+ </DSInset>
1286
+
1287
+ <DSRightIcon>
1288
+ <DSHeader>
1289
+ <DSMenu>
1290
+ <DSMenuItem>
1291
+ <DSMenuButton size="lg" asChild className="md:h-8 md:p-0" >
1292
+ <a href="#">
1293
+ <div className="bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg">
1294
+ <Command className="size-4" />
1295
+ </div>
1296
+ </a>
1297
+ </DSMenuButton>
1298
+ </DSMenuItem>
1299
+ </DSMenu>
1300
+ </DSHeader>
1301
+
1302
+ <DSContent>
1303
+ <DSGroup>
1304
+ <DSGroupContent>
1305
+ <DSMenu>
1306
+ {data.navMain.map((item) => (
1307
+ <DSMenuItem key={item.title}>
1308
+ <DSMenuButton
1309
+ tooltip={{
1310
+ children: item.title,
1311
+ hidden: false,
1312
+ }}
1313
+ onClick={() => {
1314
+ setActiveItem(item)
1315
+ const mail = data.mails.sort(() => Math.random() - 0.5)
1316
+ setMails(
1317
+ mail.slice(
1318
+ 0,
1319
+ Math.max(5, Math.floor(Math.random() * 10) + 1)
1320
+ )
1321
+ )
1322
+ setOpen(true)
1323
+ }}
1324
+ isActive={activeItem?.title === item.title}
1325
+ className="px-2.5 md:px-2"
1326
+ >
1327
+ <item.icon />
1328
+ <span>{item.title}</span>
1329
+ </DSMenuButton>
1330
+ </DSMenuItem>
1331
+ ))}
1332
+ <DSMenuItem>
1333
+ <DSMenuButton>
1334
+ <DSDBottom>
1335
+ <DSDTrigger>
1336
+ <Button variant="ghost" size='icon'><Ghost /></Button>
1337
+ </DSDTrigger>
1338
+ <DSDContent>
1339
+
1340
+ </DSDContent>
1341
+ </DSDBottom>
1342
+ </DSMenuButton>
1343
+ </DSMenuItem>
1344
+
1345
+ </DSMenu>
1346
+ </DSGroupContent>
1347
+ </DSGroup>
1348
+ </DSContent>
1349
+
1350
+ <DSFooter>
1351
+ <NavUser user={data.user} />
1352
+ </DSFooter>
1353
+ </DSRightIcon>
1354
+
1355
+ <DSRight variant="inset">
1356
+ <DSHeader>
1357
+ <div className="flex items-center gap-2">
1358
+ <Bell size={20} />
1359
+ <h2 className="text-lg font-bold">Activity</h2>
1360
+ </div>
1361
+ </DSHeader>
1362
+
1363
+ <DSContent>
1364
+ <DSGroup>
1365
+ <DSGroupLabel>Recent Notifications</DSGroupLabel>
1366
+ <DSGroupContent>
1367
+ <div className="space-y-3">
1368
+ <div className="p-3 bg-gray-800 rounded-lg">
1369
+ <p className="text-sm font-medium">New message</p>
1370
+ <p className="text-xs text-gray-400">5 minutes ago</p>
1371
+ </div>
1372
+ </div>
1373
+ </DSGroupContent>
1374
+ </DSGroup>
1375
+
1376
+ <DSGroup>
1377
+ <DSGroupLabel>Quick Actions</DSGroupLabel>
1378
+ <DSGroupContent>
1379
+ <div className="space-y-2">
1380
+ <Button>New Project</Button>
1381
+ <Button>Invite User</Button>
1382
+ </div>
1383
+ </DSGroupContent>
1384
+ </DSGroup>
1385
+ </DSContent>
1386
+
1387
+ <DSFooter>
1388
+ <Input placeholder="Search..." />
1389
+ </DSFooter>
1390
+ </DSRight>
1391
+ </DSProvider>
1392
+ </div>
1393
+ );
1394
+ }`,
1395
+ premium: false,
1396
+ category: "Overlay",
1397
+ tags: ["layout", "sidebar", "navigation", "dual", "responsive", "collapsible"],
1398
+ features: [
1399
+ "Dual Sidebar Layout",
1400
+ "Left & Right Sidebars",
1401
+ "Responsive Mobile Views",
1402
+ "Collapsible Variants",
1403
+ "Icon Sidebars",
1404
+ "Keyboard Shortcuts (⌘B, ⌘G)",
1405
+ "Theme System",
1406
+ "Floating & Inset Variants",
1407
+ "Top & Bottom Drawers",
1408
+ "TypeScript",
1409
+ "Accessible"
1410
+ ],
1411
+ dependencies: [
1412
+ "lucide-react",
1413
+ "react",
1414
+ "@radix-ui/react-slot",
1415
+ "class-variance-authority",
1416
+ "@remix-run/react",
1417
+ "vaul"
1418
+ ],
1419
+ props: {
1420
+ "DSProvider": [
1421
+ { name: "defaultOpenLeft", type: "boolean", default: "false", description: "Default open state of the sidebar." },
1422
+ { name: "defaultOpenRight", type: "boolean", default: "false", description: "Default open state of the sidebar." },
1423
+ { name: "defaultWidth", type: "string", default: "275px" },
1424
+ { name: "className", type: "string", default: "undefined" },
1425
+ { name: "style", type: "React.CSSProperties", default: "undefined", description: "Can pass through values like '--dual-sidebar-width-icon': DS_WIDTH_ICON, to be used within the style prop" },
1426
+ { name: "children", type: "React.ReactNode", default: "required" }
1427
+ ],
1428
+ "DSLeft": [
1429
+ { name: "variant", type: "sidebar | floating | inset | frosted | card | glass | compact-card | bordered | minimal | elevated", default: "sidebar" },
1430
+ { name: "collapsible", type: "offcanvas | icon | none", default: "offcanvas", description: "Collapsible state of the sidebar." },
1431
+ { name: "loadingUI", type: "boolean", default: "true" },
1432
+ { name: "className", type: "string", default: "undefined" },
1433
+ { name: "children", type: "React.ReactNode", default: "required" }
1434
+ ],
1435
+ "DSRight": [
1436
+ { name: "variant", type: "sidebar | floating | inset | frosted | card | glass | compact-card | bordered | minimal | elevated", default: "sidebar" },
1437
+ { name: "collapsible", type: "offcanvas | icon | none", default: "offcanvas" },
1438
+ { name: "loadingUI", type: "boolean", default: "true" },
1439
+ { name: "className", type: "string", default: "undefined" },
1440
+ { name: "children", type: "React.ReactNode", default: "required" }
1441
+ ],
1442
+ "DSLeftIcon": [
1443
+ { name: "iconWidth", type: "string", default: "48px" },
1444
+ { name: "variant", type: "sidebar | floating | inset | frosted | card | glass | compact-card | bordered | minimal | elevated", default: "sidebar" },
1445
+ { name: "className", type: "string", default: "undefined" },
1446
+ { name: "children", type: "React.ReactNode", default: "required" }
1447
+ ],
1448
+ "DSRightIcon": [
1449
+ { name: "iconWidth", type: "string", default: "48px" },
1450
+ { name: "variant", type: "sidebar | floating | inset | frosted | card | glass | compact-card | bordered | minimal | elevated", default: "sidebar" },
1451
+ { name: "className", type: "string", default: "undefined" },
1452
+ { name: "children", type: "React.ReactNode", default: "required" }
1453
+ ],
1454
+ "DSInset": [
1455
+ { name: "variant", type: "default | inset | card | bordered", default: "default" },
1456
+ { name: "className", type: "string", default: "undefined" },
1457
+ { name: "children", type: "React.ReactNode", default: "required" }
1458
+ ],
1459
+ // STRUCTURE COMPONENTS
1460
+ "DSHeader": [
1461
+ { name: "variant", type: "default | bordered | elevated | compact", default: "default" },
1462
+ { name: "className", type: "string", default: "undefined" },
1463
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1464
+ ],
1465
+ "DSContent": [
1466
+ { name: "className", type: "string", default: "undefined" },
1467
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1468
+ ],
1469
+ "DSFooter": [
1470
+ { name: "variant", type: "default | bordered | elevated | compact", default: "default" },
1471
+ { name: "className", type: "string", default: "undefined" },
1472
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1473
+ ],
1474
+ // MENU SYSTEM
1475
+ "DSMenu": [
1476
+ { name: "className", type: "string", default: "undefined" },
1477
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1478
+ ],
1479
+ "DSMenuItem": [
1480
+ { name: "variant", type: "default | spaced | compact | comfortable", default: "default" },
1481
+ { name: "className", type: "string", default: "undefined" },
1482
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1483
+ ],
1484
+ "DSMenuButton": [
1485
+ { name: "asChild", type: "boolean", default: "false" },
1486
+ { name: "isActive", type: "boolean", default: "false" },
1487
+ { name: "tooltip", type: "string | TooltipContentProps", default: "undefined" },
1488
+ { name: "variant", type: "default | ghost | outline | soft | solid | minimal | bordered | pill", default: "default" },
1489
+ { name: "size", type: "default | sm | lg | icon", default: "default" },
1490
+ { name: "className", type: "string", default: "undefined" },
1491
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1492
+ ],
1493
+ "DSMenuAction": [
1494
+ { name: "asChild", type: "boolean", default: "false" },
1495
+ { name: "showOnHover", type: "boolean", default: "false" },
1496
+ { name: "className", type: "string", default: "undefined" },
1497
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1498
+ ],
1499
+ "DSMenuBadge": [
1500
+ { name: "variant", type: "default | primary | secondary | success | warning | danger | outline | ghost | dot", default: "default" },
1501
+ { name: "className", type: "string", default: "undefined" },
1502
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1503
+ ],
1504
+ "DSMenuSkeleton": [
1505
+ { name: "showIcon", type: "boolean", default: "false" },
1506
+ { name: "className", type: "string", default: "undefined" }
1507
+ ],
1508
+ "DSMenuSub": [
1509
+ { name: "className", type: "string", default: "undefined" },
1510
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1511
+ ],
1512
+ "DSMenuSubItem": [
1513
+ { name: "variant", type: "default | indented | dotted", default: "default" },
1514
+ { name: "className", type: "string", default: "undefined" },
1515
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1516
+ ],
1517
+ "DSMenuSubButton": [
1518
+ { name: "asChild", type: "boolean", default: "false" },
1519
+ { name: "size", type: "default | sm | lg", default: "default" },
1520
+ { name: "isActive", type: "boolean", default: "false" },
1521
+ { name: "variant", type: "default | ghost | minimal | indent", default: "default" },
1522
+ { name: "className", type: "string", default: "undefined" },
1523
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1524
+ ],
1525
+ "DSMenuLink": [
1526
+ { name: "to", type: "string", default: "required" },
1527
+ { name: "icon", type: "React.ReactNode", default: "undefined" },
1528
+ { name: "tooltip", type: "string", default: "undefined" },
1529
+ { name: "variant", type: "default | ghost | outline | soft | solid | minimal | bordered | pill", default: "default" },
1530
+ { name: "size", type: "default | sm | lg | icon", default: "default" },
1531
+ { name: "className", type: "string", default: "undefined" },
1532
+ { name: "children", type: "React.ReactNode", default: "required" }
1533
+ ],
1534
+ "DSMenuAnchor": [
1535
+ { name: "to", type: "string", default: "required" },
1536
+ { name: "icon", type: "React.ReactNode", default: "undefined" },
1537
+ { name: "tooltip", type: "string", default: "undefined" },
1538
+ { name: "newTab", type: "boolean", default: "true" },
1539
+ { name: "variant", type: "default | ghost | outline | soft | solid | minimal | bordered | pill", default: "default" },
1540
+ { name: "size", type: "default | sm | lg | icon", default: "default" },
1541
+ { name: "className", type: "string", default: "undefined" },
1542
+ { name: "onClick", type: "React.MouseEventHandler", default: "undefined" },
1543
+ { name: "children", type: "React.ReactNode", default: "required" }
1544
+ ],
1545
+ // GROUP SYSTEM
1546
+ "DSGroup": [
1547
+ { name: "variant", type: "default | separated | card | bordered | subtle", default: "default" },
1548
+ { name: "className", type: "string", default: "undefined" },
1549
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1550
+ ],
1551
+ "DSGroupLabel": [
1552
+ { name: "asChild", type: "boolean", default: "false" },
1553
+ { name: "variant", type: "default | prominent | subtle | separated", default: "default" },
1554
+ { name: "className", type: "string", default: "undefined" },
1555
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1556
+ ],
1557
+ "DSGroupAction": [
1558
+ { name: "asChild", type: "boolean", default: "false" },
1559
+ { name: "className", type: "string", default: "undefined" },
1560
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1561
+ ],
1562
+ "DSGroupContent": [
1563
+ { name: "className", type: "string", default: "undefined" },
1564
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1565
+ ],
1566
+ // UI ELEMENTS
1567
+ "DSTrigger": [
1568
+ { name: "side", type: "left | right", default: "left" },
1569
+ { name: "className", type: "string", default: "undefined" },
1570
+ { name: "onClick", type: "React.MouseEventHandler", default: "undefined" }
1571
+ ],
1572
+ "DSBurger": [
1573
+ { name: "opened", type: "boolean", default: "undefined" },
1574
+ { name: "size", type: "sm | md | lg | xl", default: "md" },
1575
+ { name: "color", type: "string", default: "currentColor" },
1576
+ { name: "onClick", type: "() => void", default: "undefined" }
1577
+ ],
1578
+ "DSInput": [
1579
+ { name: "className", type: "string", default: "undefined" },
1580
+ { name: "type", type: "string", default: "text" },
1581
+ { name: "placeholder", type: "string", default: "undefined" },
1582
+ { name: "value", type: "string", default: "undefined" },
1583
+ { name: "onChange", type: "React.ChangeEventHandler", default: "undefined" }
1584
+ ],
1585
+ "DSSeparator": [
1586
+ { name: "variant", type: "default | thick | dashed | gradient", default: "default" },
1587
+ { name: "spacing", type: "default | sm | lg | none", default: "default" },
1588
+ { name: "className", type: "string", default: "undefined" },
1589
+ { name: "orientation", type: "horizontal | vertical", default: "horizontal" }
1590
+ ],
1591
+ // RAIL COMPONENTS
1592
+ "DSLeftRail": [
1593
+ { name: "side", type: "left | right", default: "left" },
1594
+ { name: "className", type: "string", default: "undefined" }
1595
+ ],
1596
+ "DSRightRail": [
1597
+ { name: "side", type: "left | right", default: "right" },
1598
+ { name: "className", type: "string", default: "undefined" }
1599
+ ],
1600
+ // THEME SYSTEM
1601
+ "DSThemeSelector": [
1602
+ { name: "size", type: "number", default: "28" },
1603
+ { name: "className", type: "string", default: "undefined" },
1604
+ { name: "children", type: "React.ReactNode", default: "required" }
1605
+ ],
1606
+ "DSThemeProvider": [
1607
+ { name: "children", type: "React.ReactNode", default: "required" }
1608
+ ],
1609
+ // DRAWER SYSTEM - TOP/BOTTOM (Vaul)
1610
+ // drawer top position
1611
+ "DSD & DSD Bottom": [
1612
+ { "name": "open", "type": "boolean", "default": "undefined" },
1613
+ { "name": "defaultOpen", "type": "boolean", "default": "false" },
1614
+ { "name": "onOpenChange", "type": "(open: boolean) => void", "default": "undefined" },
1615
+ { "name": "shouldScaleBackground", "type": "boolean", "default": "false" },
1616
+ { "name": "setBackgroundColorOnScale", "type": "boolean", "default": "true" },
1617
+ { "name": "closeThreshold", "type": "number", "default": "0.5" },
1618
+ { "name": "scrollLockTimeout", "type": "number", "default": "500" },
1619
+ { "name": "snapPoints", "type": "(number | string)[]", "default": "undefined" },
1620
+ { "name": "activeSnapPoint", "type": "number | string | null", "default": "undefined" },
1621
+ { "name": "setActiveSnapPoint", "type": "(snapPoint: number | string | null) => void", "default": "undefined" },
1622
+ { "name": "fadeFromIndex", "type": "number", "default": "snapPoints.length - 1" },
1623
+ { "name": "modal", "type": "boolean", "default": "true" },
1624
+ { "name": "handleOnly", "type": "boolean", "default": "false" },
1625
+ { "name": "dismissible", "type": "boolean", "default": "true" },
1626
+ { "name": "onDrag", "type": "(event: PointerEvent, percentageDragged: number) => void", "default": "undefined" },
1627
+ { "name": "onRelease", "type": "(event: PointerEvent, open: boolean) => void", "default": "undefined" },
1628
+ { "name": "noBodyStyles", "type": "boolean", "default": "false" },
1629
+ { "name": "direction", "type": "'top' | 'bottom' | 'left' | 'right'", "default": "'bottom'" },
1630
+ { "name": "preventScrollRestoration", "type": "boolean", "default": "true" },
1631
+ { "name": "disablePreventScroll", "type": "boolean", "default": "false" },
1632
+ { "name": "snapToSequentialPoint", "type": "boolean", "default": "false" },
1633
+ { "name": "onAnimationEnd", "type": "(open: boolean) => void", "default": "undefined" },
1634
+ { "name": "container", "type": "HTMLElement | null", "default": "document.body" },
1635
+ { "name": "nested", "type": "boolean", "default": "false" },
1636
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
1637
+ ],
1638
+ "DSDTrigger": [
1639
+ { "name": "asChild", "type": "boolean", "default": "false" },
1640
+ { "name": "className", "type": "string", "default": "undefined" },
1641
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
1642
+ ],
1643
+ "DSDPortal": [
1644
+ { "name": "container", "type": "HTMLElement | null", "default": "document.body" },
1645
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
1646
+ ],
1647
+ "DSDClose": [
1648
+ { "name": "asChild", "type": "boolean", "default": "false" },
1649
+ { "name": "className", "type": "string", "default": "undefined" },
1650
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
1651
+ ],
1652
+ "DSDOverlay": [
1653
+ { "name": "asChild", "type": "boolean", "default": "false" },
1654
+ { "name": "className", "type": "string", "default": "undefined" }
1655
+ ],
1656
+ "DSDContent": [
1657
+ { "name": "asChild", "type": "boolean", "default": "false" },
1658
+ { "name": "className", "type": "string", "default": "undefined" },
1659
+ { "name": "children", "type": "React.ReactNode", "default": "required" }
1660
+ ],
1661
+ "DSDTitle": [
1662
+ { "name": "asChild", "type": "boolean", "default": "false" },
1663
+ { "name": "className", "type": "string", "default": "undefined" },
1664
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
1665
+ ],
1666
+ "DSDDescription": [
1667
+ { "name": "asChild", "type": "boolean", "default": "false" },
1668
+ { "name": "className", "type": "string", "default": "undefined" },
1669
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
1670
+ ],
1671
+ // LOADING UI
1672
+ "DSLoading": [
1673
+ { name: "variant", type: "default | minimal | card | centered", default: "default" },
1674
+ { name: "size", type: "default | sm | md | lg | full", default: "default" }
1675
+ ],
1676
+ // AVATAR SYSTEM
1677
+ "DSA": [
1678
+ { "name": "className", "type": "string", "default": "undefined" },
1679
+ { "name": "asChild", "type": "boolean", "default": "false" }
1680
+ ],
1681
+ "DSAImage": [
1682
+ { "name": "className", "type": "string", "default": "undefined" },
1683
+ { "name": "src", "type": "string", "default": "required" },
1684
+ { "name": "alt", "type": "string", "default": "required" },
1685
+ { "name": "onLoadingStatusChange", "type": "function", "default": "undefined" },
1686
+ { "name": "asChild", "type": "boolean", "default": "false" }
1687
+ ],
1688
+ "DSAFallback": [
1689
+ { "name": "className", "type": "string", "default": "undefined" },
1690
+ { "name": "delayMs", "type": "number", "default": "0" },
1691
+ { "name": "asChild", "type": "boolean", "default": "false" }
1692
+ ],
1693
+ // DROPDOWN MENU SYSTEM
1694
+ //
1695
+ "DSDM": [
1696
+ { "name": "defaultOpen", "type": "boolean", "default": "undefined" },
1697
+ { "name": "open", "type": "boolean", "default": "undefined" },
1698
+ { "name": "onOpenChange", "type": "(open: boolean) => void", "default": "undefined" },
1699
+ { "name": "dir", "type": "'ltr' | 'rtl'", "default": "undefined" },
1700
+ { "name": "modal", "type": "boolean", "default": "true" }
1701
+ ],
1702
+ "DSDMPortal": [
1703
+ { "name": "forceMount", "type": "boolean", "default": "undefined" },
1704
+ { "name": "container", "type": "HTMLElement | null", "default": "document.body" }
1705
+ ],
1706
+ "DSDMTrigger": [
1707
+ { "name": "asChild", "type": "boolean", "default": "false" },
1708
+ { "name": "disabled", "type": "boolean", "default": "false" }
1709
+ ],
1710
+ "DSDMContent": [
1711
+ { "name": "className", "type": "string", "default": "undefined" },
1712
+ { "name": "forceMount", "type": "boolean", "default": "undefined" },
1713
+ { "name": "side", "type": "'top' | 'right' | 'bottom' | 'left'", "default": "'bottom'" },
1714
+ { "name": "sideOffset", "type": "number", "default": "0" },
1715
+ { "name": "align", "type": "'start' | 'center' | 'end'", "default": "'center'" },
1716
+ { "name": "alignOffset", "type": "number", "default": "0" },
1717
+ { "name": "avoidCollisions", "type": "boolean", "default": "true" },
1718
+ { "name": "collisionBoundary", "type": "Element | Element[] | null", "default": "[]" },
1719
+ { "name": "collisionPadding", "type": "number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>", "default": "0" },
1720
+ { "name": "arrowPadding", "type": "number", "default": "0" },
1721
+ { "name": "sticky", "type": "'partial' | 'always'", "default": "'partial'" },
1722
+ { "name": "hideWhenDetached", "type": "boolean", "default": "false" },
1723
+ { "name": "loop", "type": "boolean", "default": "false" },
1724
+ { "name": "onCloseAutoFocus", "type": "(event: Event) => void", "default": "undefined" },
1725
+ { "name": "onEscapeKeyDown", "type": "(event: KeyboardEvent) => void", "default": "undefined" },
1726
+ { "name": "onPointerDownOutside", "type": "(event: PointerDownOutsideEvent) => void", "default": "undefined" },
1727
+ { "name": "onFocusOutside", "type": "(event: FocusOutsideEvent) => void", "default": "undefined" },
1728
+ { "name": "onInteractOutside", "type": "(event: PointerDownOutsideEvent | FocusOutsideEvent) => void", "default": "undefined" }
1729
+ ],
1730
+ "DSDMArrow": [
1731
+ { "name": "className", "type": "string", "default": "undefined" },
1732
+ { "name": "width", "type": "number", "default": "10" },
1733
+ { "name": "height", "type": "number", "default": "5" },
1734
+ { "name": "asChild", "type": "boolean", "default": "false" }
1735
+ ],
1736
+ "DSDMGroup": [
1737
+ { "name": "asChild", "type": "boolean", "default": "false" }
1738
+ ],
1739
+ "DSDMLabel": [
1740
+ { "name": "className", "type": "string", "default": "undefined" },
1741
+ { "name": "asChild", "type": "boolean", "default": "false" }
1742
+ ],
1743
+ "DSDMItem": [
1744
+ { "name": "className", "type": "string", "default": "undefined" },
1745
+ { "name": "disabled", "type": "boolean", "default": "false" },
1746
+ { "name": "onSelect", "type": "(event: Event) => void", "default": "undefined" },
1747
+ { "name": "textValue", "type": "string", "default": "undefined" },
1748
+ { "name": "asChild", "type": "boolean", "default": "false" }
1749
+ ],
1750
+ "DSDMCheckboxItem": [
1751
+ { "name": "className", "type": "string", "default": "undefined" },
1752
+ { "name": "checked", "type": "boolean | 'indeterminate'", "default": "undefined" },
1753
+ { "name": "onCheckedChange", "type": "(checked: boolean) => void", "default": "undefined" },
1754
+ { "name": "disabled", "type": "boolean", "default": "false" },
1755
+ { "name": "onSelect", "type": "(event: Event) => void", "default": "undefined" },
1756
+ { "name": "textValue", "type": "string", "default": "undefined" },
1757
+ { "name": "asChild", "type": "boolean", "default": "false" }
1758
+ ],
1759
+ "DSDMRadioGroup": [
1760
+ { "name": "value", "type": "string", "default": "undefined" },
1761
+ { "name": "onValueChange", "type": "(value: string) => void", "default": "undefined" },
1762
+ { "name": "asChild", "type": "boolean", "default": "false" }
1763
+ ],
1764
+ "DSDMRadioItem": [
1765
+ { "name": "className", "type": "string", "default": "undefined" },
1766
+ { "name": "value", "type": "string", "default": "required" },
1767
+ { "name": "disabled", "type": "boolean", "default": "false" },
1768
+ { "name": "onSelect", "type": "(event: Event) => void", "default": "undefined" },
1769
+ { "name": "textValue", "type": "string", "default": "undefined" },
1770
+ { "name": "asChild", "type": "boolean", "default": "false" }
1771
+ ],
1772
+ "DSDMItemIndicator": [
1773
+ { "name": "className", "type": "string", "default": "undefined" },
1774
+ { "name": "forceMount", "type": "boolean", "default": "undefined" },
1775
+ { "name": "asChild", "type": "boolean", "default": "false" }
1776
+ ],
1777
+ "DSDMSeparator": [
1778
+ { "name": "className", "type": "string", "default": "undefined" },
1779
+ { "name": "asChild", "type": "boolean", "default": "false" }
1780
+ ],
1781
+ "DSDMSub": [
1782
+ { "name": "defaultOpen", "type": "boolean", "default": "undefined" },
1783
+ { "name": "open", "type": "boolean", "default": "undefined" },
1784
+ { "name": "onOpenChange", "type": "(open: boolean) => void", "default": "undefined" }
1785
+ ],
1786
+ "DSDMSubTrigger": [
1787
+ { "name": "className", "type": "string", "default": "undefined" },
1788
+ { "name": "disabled", "type": "boolean", "default": "false" },
1789
+ { "name": "textValue", "type": "string", "default": "undefined" },
1790
+ { "name": "asChild", "type": "boolean", "default": "false" }
1791
+ ],
1792
+ "DSDMSubContent": [
1793
+ { "name": "className", "type": "string", "default": "undefined" },
1794
+ { "name": "forceMount", "type": "boolean", "default": "undefined" },
1795
+ { "name": "side", "type": "'top' | 'right' | 'bottom' | 'left'", "default": "'right'" },
1796
+ { "name": "sideOffset", "type": "number", "default": "0" },
1797
+ { "name": "align", "type": "'start' | 'center' | 'end'", "default": "'start'" },
1798
+ { "name": "alignOffset", "type": "number", "default": "0" },
1799
+ { "name": "avoidCollisions", "type": "boolean", "default": "true" },
1800
+ { "name": "collisionBoundary", "type": "Element | Element[] | null", "default": "[]" },
1801
+ { "name": "collisionPadding", "type": "number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>", "default": "0" },
1802
+ { "name": "arrowPadding", "type": "number", "default": "0" },
1803
+ { "name": "sticky", "type": "'partial' | 'always'", "default": "'partial'" },
1804
+ { "name": "hideWhenDetached", "type": "boolean", "default": "false" },
1805
+ { "name": "loop", "type": "boolean", "default": "false" },
1806
+ { "name": "onEscapeKeyDown", "type": "(event: KeyboardEvent) => void", "default": "undefined" },
1807
+ { "name": "onPointerDownOutside", "type": "(event: PointerDownOutsideEvent) => void", "default": "undefined" },
1808
+ { "name": "onFocusOutside", "type": "(event: FocusOutsideEvent) => void", "default": "undefined" },
1809
+ { "name": "onInteractOutside", "type": "(event: PointerDownOutsideEvent | FocusOutsideEvent) => void", "default": "undefined" }
1810
+ ],
1811
+ // COLLAPSIBLE SYSTEM
1812
+ //
1813
+ "DSC": [
1814
+ { "name": "defaultOpen", "type": "boolean", "default": "false" },
1815
+ { "name": "open", "type": "boolean", "default": "undefined" },
1816
+ { "name": "onOpenChange", "type": "(open: boolean) => void", "default": "undefined" },
1817
+ { "name": "disabled", "type": "boolean", "default": "false" },
1818
+ { "name": "asChild", "type": "boolean", "default": "false" }
1819
+ ],
1820
+ "DSCTrigger": [
1821
+ { "name": "asChild", "type": "boolean", "default": "false" },
1822
+ { "name": "disabled", "type": "boolean", "default": "false" }
1823
+ ],
1824
+ "DSCContent": [
1825
+ { "name": "className", "type": "string", "default": "undefined" },
1826
+ { "name": "forceMount", "type": "boolean", "default": "undefined" },
1827
+ { "name": "asChild", "type": "boolean", "default": "false" }
1828
+ ],
1829
+ // HOOKS
1830
+ "useDS": [
1831
+ { name: "leftState", type: "expanded | collapsed", default: "readonly", description: "The current state of the sidebar." },
1832
+ { name: "rightState", type: "expanded | collapsed", default: "readonly" },
1833
+ { name: "openLeft", type: "boolean", default: "readonly", description: "Whether the sidebar is open." },
1834
+ { name: "openRight", type: "boolean", default: "readonly" },
1835
+ { name: "setOpenLeft", type: "(open: boolean) => void", default: "readonly", description: "Sets the open state of the sidebar." },
1836
+ { name: "setOpenRight", type: "(open: boolean) => void", default: "readonly", description: "" },
1837
+ { name: "openMobile", type: "boolean", default: "readonly", description: "Whether the sidebar is open on mobile." },
1838
+ { name: "openMobileRight", type: "boolean", default: "readonly", description: "" },
1839
+ { name: "setOpenMobile", type: "(open: boolean) => void", default: "readonly", description: "Sets the open state of the sidebar on mobile." },
1840
+ { name: "setOpenMobileRight", type: "(open: boolean) => void", default: "readonly", description: "" },
1841
+ { name: "toggleLeft", type: "() => void", default: "readonly", description: "Toggles the sidebar. Desktop and mobile." },
1842
+ { name: "toggleRight", type: "() => void", default: "readonly", description: "" },
1843
+ { name: "isMobile", type: "boolean", default: "readonly", description: "Whether the sidebar is on mobile." },
1844
+ { name: "sidebarWidth", type: "number", default: "readonly", description: "Controls the default width value." },
1845
+ { name: "leftVariant", type: "SidebarVariant", default: "readonly", description: "States the current variant type, this is more so used within the source file." },
1846
+ { name: "rightVariant", type: "SidebarVariant", default: "readonly", description: "" },
1847
+ { name: "setLeftVariant", type: "(variant: SidebarVariant) => void", default: "readonly", description: "Sets the state the current variant type, this is more so used within the source file" },
1848
+ { name: "setRightVariant", type: "(variant: SidebarVariant) => void", default: "readonly", description: "" },
1849
+ { name: "isIconLeftActive", type: "boolean", default: "readonly", description: "Checks if icon sidebars are actively used." },
1850
+ { name: "isIconRightActive", type: "boolean", default: "readonly", description: "" },
1851
+ { name: "setIsIconLeftActive", type: "(open: boolean) => void", default: "readonly", description: "Sets isIconLeftActive state, used within the source file." },
1852
+ { name: "setIsIconRightActive", type: "(open: boolean) => void", default: "readonly", description: "" },
1853
+ { name: "iconLeftWidth", type: "number", default: "readonly", description: "Controls the default width value." },
1854
+ { name: "iconRightWidth", type: "number", default: "readonly", description: "" },
1855
+ { name: "setIconLeftWidth", type: "(width: number) => void", default: "readonly", description: "Sets setIconLeftWidth state, used within the source file." },
1856
+ { name: "setIconRightWidth", type: "(width: number) => void", default: "readonly", description: "" },
1857
+ { name: "topHeight", type: "string", default: "readonly", description: "Sets height for inset variant styles." },
1858
+ { name: "setTopHeight", type: "(height: string) => void", default: "readonly", description: "" },
1859
+ { name: "bottomHeight", type: "string", default: "readonly", description: "" },
1860
+ { name: "setBottomHeight", type: "(height: string) => void", default: "readonly", description: "" }
1861
+ ],
1862
+ "useDSTheme": [
1863
+ { name: "theme", type: "DSTheme", default: "readonly" },
1864
+ { name: "setTheme", type: "(theme: DSTheme) => void", default: "readonly" },
1865
+ { name: "themeVars", type: "Record<string, string>", default: "readonly" }
1866
+ ]
1867
+ },
1868
+ desc: "A comprehensive dual sidebar layout system with left and right collapsible sidebars, support for multiple variants including icon sidebars, theme system, responsive mobile views, keyboard shortcuts, and top/bottom drawer support. Perfect for complex application layouts requiring flexible navigation structures.",
1869
+ status: "stable",
1870
+ lastUpdated: "2024-11-03"
1871
+ },
1872
+ {
1873
+ name: "Sidebar",
1874
+ value: "sidebar",
1875
+ importPath: "~/components/catalyst-ui",
1876
+ multiImport: 'Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, useSidebar',
1877
+ path: "/components/catalyst-ui/overlays/sidebar-original.tsx",
1878
+ premium: false,
1879
+ source: null,
1880
+ usage: null,
1881
+ basicusage: `
1882
+ const SIDEBAR_WIDTH = "16rem"
1883
+ const SIDEBAR_WIDTH_MOBILE = "18rem"
1884
+
1885
+ <SidebarProvider
1886
+ style={{
1887
+ "--sidebar-width": "20rem",
1888
+ "--sidebar-width-mobile": "20rem",
1889
+ }}
1890
+ >
1891
+ <Sidebar />
1892
+ </SidebarProvider>
1893
+
1894
+ const SIDEBAR_KEYBOARD_SHORTCUT = "b"
1895
+
1896
+
1897
+
1898
+
1899
+
1900
+ export async function Layout({ children }: { children: React.ReactNode }) {
1901
+ const cookieStore = await cookies()
1902
+ const defaultOpen = cookieStore.get("sidebar_state")?.value === "true"
1903
+
1904
+ return (
1905
+ <SidebarProvider defaultOpen={defaultOpen}>
1906
+ <AppSidebar />
1907
+ <main>
1908
+ <SidebarTrigger />
1909
+ {children}
1910
+ </main>
1911
+ </SidebarProvider>
1912
+ )
1913
+ }
1914
+
1915
+ const SIDEBAR_COOKIE_NAME = "sidebar_state"
1916
+
1917
+ <Sidebar side="left | right" />
1918
+
1919
+ <Sidebar variant="sidebar | floating | inset" />
1920
+
1921
+ <SidebarProvider>
1922
+ <Sidebar variant="inset" />
1923
+ <SidebarInset>
1924
+ <main>{children}</main>
1925
+ </SidebarInset>
1926
+ </SidebarProvider>
1927
+
1928
+ <Sidebar collapsible="offcanvas | icon | none" />
1929
+
1930
+ const { state, open, setOpen, openMobile, setOpenMobile, isMobile, toggleSidebar } = useSidebar()
1931
+
1932
+ <SidebarMenuLink to='/settings' icon={<Settings />}>
1933
+ Settings
1934
+ </SidebarMenuLink>
1935
+ <SidebarMenuAnchor to='/settings' icon={<Settings />}>
1936
+ Settings
1937
+ </SidebarMenuAnchor>
1938
+ `,
1939
+ usagePath: "/components/catalyst-ui/overlays/sidebar-original.tsx",
1940
+ category: "Overlay",
1941
+ tags: ["ui", "components", "interactive"],
1942
+ features: ["Responsive", "TypeScript", "Accessible"],
1943
+ dependencies: ["@radix-ui/react-slot", "class-variance-authority"],
1944
+ props: {
1945
+ "DSProvider": [
1946
+ { name: "defaultOpenLeft", type: "boolean", default: "false", description: "Default open state of the sidebar." },
1947
+ { name: "defaultOpenRight", type: "boolean", default: "false", description: "Default open state of the sidebar." },
1948
+ { name: "defaultWidth", type: "string", default: "275px" },
1949
+ { name: "className", type: "string", default: "undefined" },
1950
+ { name: "style", type: "React.CSSProperties", default: "undefined", description: "Can pass through values like '--dual-sidebar-width-icon': DS_WIDTH_ICON, to be used within the style prop" },
1951
+ { name: "children", type: "React.ReactNode", default: "required" }
1952
+ ],
1953
+ "DSLeft": [
1954
+ { name: "variant", type: "sidebar | floating | inset | frosted | card | glass | compact-card | bordered | minimal | elevated", default: "sidebar" },
1955
+ { name: "collapsible", type: "offcanvas | icon | none", default: "offcanvas", description: "Collapsible state of the sidebar." },
1956
+ { name: "loadingUI", type: "boolean", default: "true" },
1957
+ { name: "className", type: "string", default: "undefined" },
1958
+ { name: "children", type: "React.ReactNode", default: "required" }
1959
+ ],
1960
+ "DSRight": [
1961
+ { name: "variant", type: "sidebar | floating | inset | frosted | card | glass | compact-card | bordered | minimal | elevated", default: "sidebar" },
1962
+ { name: "collapsible", type: "offcanvas | icon | none", default: "offcanvas" },
1963
+ { name: "loadingUI", type: "boolean", default: "true" },
1964
+ { name: "className", type: "string", default: "undefined" },
1965
+ { name: "children", type: "React.ReactNode", default: "required" }
1966
+ ],
1967
+ "DSLeftIcon": [
1968
+ { name: "iconWidth", type: "string", default: "48px" },
1969
+ { name: "variant", type: "sidebar | floating | inset | frosted | card | glass | compact-card | bordered | minimal | elevated", default: "sidebar" },
1970
+ { name: "className", type: "string", default: "undefined" },
1971
+ { name: "children", type: "React.ReactNode", default: "required" }
1972
+ ],
1973
+ "DSRightIcon": [
1974
+ { name: "iconWidth", type: "string", default: "48px" },
1975
+ { name: "variant", type: "sidebar | floating | inset | frosted | card | glass | compact-card | bordered | minimal | elevated", default: "sidebar" },
1976
+ { name: "className", type: "string", default: "undefined" },
1977
+ { name: "children", type: "React.ReactNode", default: "required" }
1978
+ ],
1979
+ "DSInset": [
1980
+ { name: "variant", type: "default | inset | card | bordered", default: "default" },
1981
+ { name: "className", type: "string", default: "undefined" },
1982
+ { name: "children", type: "React.ReactNode", default: "required" }
1983
+ ],
1984
+ // STRUCTURE COMPONENTS
1985
+ "DSHeader": [
1986
+ { name: "variant", type: "default | bordered | elevated | compact", default: "default" },
1987
+ { name: "className", type: "string", default: "undefined" },
1988
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1989
+ ],
1990
+ "DSContent": [
1991
+ { name: "className", type: "string", default: "undefined" },
1992
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1993
+ ],
1994
+ "DSFooter": [
1995
+ { name: "variant", type: "default | bordered | elevated | compact", default: "default" },
1996
+ { name: "className", type: "string", default: "undefined" },
1997
+ { name: "children", type: "React.ReactNode", default: "undefined" }
1998
+ ],
1999
+ // MENU SYSTEM
2000
+ "DSMenu": [
2001
+ { name: "className", type: "string", default: "undefined" },
2002
+ { name: "children", type: "React.ReactNode", default: "undefined" }
2003
+ ],
2004
+ "DSMenuItem": [
2005
+ { name: "variant", type: "default | spaced | compact | comfortable", default: "default" },
2006
+ { name: "className", type: "string", default: "undefined" },
2007
+ { name: "children", type: "React.ReactNode", default: "undefined" }
2008
+ ],
2009
+ "DSMenuButton": [
2010
+ { name: "asChild", type: "boolean", default: "false" },
2011
+ { name: "isActive", type: "boolean", default: "false" },
2012
+ { name: "tooltip", type: "string | TooltipContentProps", default: "undefined" },
2013
+ { name: "variant", type: "default | ghost | outline | soft | solid | minimal | bordered | pill", default: "default" },
2014
+ { name: "size", type: "default | sm | lg | icon", default: "default" },
2015
+ { name: "className", type: "string", default: "undefined" },
2016
+ { name: "children", type: "React.ReactNode", default: "undefined" }
2017
+ ],
2018
+ "DSMenuAction": [
2019
+ { name: "asChild", type: "boolean", default: "false" },
2020
+ { name: "showOnHover", type: "boolean", default: "false" },
2021
+ { name: "className", type: "string", default: "undefined" },
2022
+ { name: "children", type: "React.ReactNode", default: "undefined" }
2023
+ ],
2024
+ "DSMenuBadge": [
2025
+ { name: "variant", type: "default | primary | secondary | success | warning | danger | outline | ghost | dot", default: "default" },
2026
+ { name: "className", type: "string", default: "undefined" },
2027
+ { name: "children", type: "React.ReactNode", default: "undefined" }
2028
+ ],
2029
+ "DSMenuSkeleton": [
2030
+ { name: "showIcon", type: "boolean", default: "false" },
2031
+ { name: "className", type: "string", default: "undefined" }
2032
+ ],
2033
+ "DSMenuSub": [
2034
+ { name: "className", type: "string", default: "undefined" },
2035
+ { name: "children", type: "React.ReactNode", default: "undefined" }
2036
+ ],
2037
+ "DSMenuSubItem": [
2038
+ { name: "variant", type: "default | indented | dotted", default: "default" },
2039
+ { name: "className", type: "string", default: "undefined" },
2040
+ { name: "children", type: "React.ReactNode", default: "undefined" }
2041
+ ],
2042
+ "DSMenuSubButton": [
2043
+ { name: "asChild", type: "boolean", default: "false" },
2044
+ { name: "size", type: "default | sm | lg", default: "default" },
2045
+ { name: "isActive", type: "boolean", default: "false" },
2046
+ { name: "variant", type: "default | ghost | minimal | indent", default: "default" },
2047
+ { name: "className", type: "string", default: "undefined" },
2048
+ { name: "children", type: "React.ReactNode", default: "undefined" }
2049
+ ],
2050
+ "DSMenuLink": [
2051
+ { name: "to", type: "string", default: "required" },
2052
+ { name: "icon", type: "React.ReactNode", default: "undefined" },
2053
+ { name: "tooltip", type: "string", default: "undefined" },
2054
+ { name: "variant", type: "default | ghost | outline | soft | solid | minimal | bordered | pill", default: "default" },
2055
+ { name: "size", type: "default | sm | lg | icon", default: "default" },
2056
+ { name: "className", type: "string", default: "undefined" },
2057
+ { name: "children", type: "React.ReactNode", default: "required" }
2058
+ ],
2059
+ "DSMenuAnchor": [
2060
+ { name: "to", type: "string", default: "required" },
2061
+ { name: "icon", type: "React.ReactNode", default: "undefined" },
2062
+ { name: "tooltip", type: "string", default: "undefined" },
2063
+ { name: "newTab", type: "boolean", default: "true" },
2064
+ { name: "variant", type: "default | ghost | outline | soft | solid | minimal | bordered | pill", default: "default" },
2065
+ { name: "size", type: "default | sm | lg | icon", default: "default" },
2066
+ { name: "className", type: "string", default: "undefined" },
2067
+ { name: "onClick", type: "React.MouseEventHandler", default: "undefined" },
2068
+ { name: "children", type: "React.ReactNode", default: "required" }
2069
+ ],
2070
+ // GROUP SYSTEM
2071
+ "DSGroup": [
2072
+ { name: "variant", type: "default | separated | card | bordered | subtle", default: "default" },
2073
+ { name: "className", type: "string", default: "undefined" },
2074
+ { name: "children", type: "React.ReactNode", default: "undefined" }
2075
+ ],
2076
+ "DSGroupLabel": [
2077
+ { name: "asChild", type: "boolean", default: "false" },
2078
+ { name: "variant", type: "default | prominent | subtle | separated", default: "default" },
2079
+ { name: "className", type: "string", default: "undefined" },
2080
+ { name: "children", type: "React.ReactNode", default: "undefined" }
2081
+ ],
2082
+ "DSGroupAction": [
2083
+ { name: "asChild", type: "boolean", default: "false" },
2084
+ { name: "className", type: "string", default: "undefined" },
2085
+ { name: "children", type: "React.ReactNode", default: "undefined" }
2086
+ ],
2087
+ "DSGroupContent": [
2088
+ { name: "className", type: "string", default: "undefined" },
2089
+ { name: "children", type: "React.ReactNode", default: "undefined" }
2090
+ ],
2091
+ // UI ELEMENTS
2092
+ "DSTrigger": [
2093
+ { name: "side", type: "left | right", default: "left" },
2094
+ { name: "className", type: "string", default: "undefined" },
2095
+ { name: "onClick", type: "React.MouseEventHandler", default: "undefined" }
2096
+ ],
2097
+ "DSBurger": [
2098
+ { name: "opened", type: "boolean", default: "undefined" },
2099
+ { name: "size", type: "sm | md | lg | xl", default: "md" },
2100
+ { name: "color", type: "string", default: "currentColor" },
2101
+ { name: "onClick", type: "() => void", default: "undefined" }
2102
+ ],
2103
+ "DSInput": [
2104
+ { name: "className", type: "string", default: "undefined" },
2105
+ { name: "type", type: "string", default: "text" },
2106
+ { name: "placeholder", type: "string", default: "undefined" },
2107
+ { name: "value", type: "string", default: "undefined" },
2108
+ { name: "onChange", type: "React.ChangeEventHandler", default: "undefined" }
2109
+ ],
2110
+ "DSSeparator": [
2111
+ { name: "variant", type: "default | thick | dashed | gradient", default: "default" },
2112
+ { name: "spacing", type: "default | sm | lg | none", default: "default" },
2113
+ { name: "className", type: "string", default: "undefined" },
2114
+ { name: "orientation", type: "horizontal | vertical", default: "horizontal" }
2115
+ ],
2116
+ // RAIL COMPONENTS
2117
+ "DSLeftRail": [
2118
+ { name: "side", type: "left | right", default: "left" },
2119
+ { name: "className", type: "string", default: "undefined" }
2120
+ ],
2121
+ "DSRightRail": [
2122
+ { name: "side", type: "left | right", default: "right" },
2123
+ { name: "className", type: "string", default: "undefined" }
2124
+ ],
2125
+ // THEME SYSTEM
2126
+ "DSThemeSelector": [
2127
+ { name: "size", type: "number", default: "28" },
2128
+ { name: "className", type: "string", default: "undefined" },
2129
+ { name: "children", type: "React.ReactNode", default: "required" }
2130
+ ],
2131
+ "DSThemeProvider": [
2132
+ { name: "children", type: "React.ReactNode", default: "required" }
2133
+ ],
2134
+ // DRAWER SYSTEM - TOP/BOTTOM (Vaul)
2135
+ // drawer top position
2136
+ "DSD & DSD Bottom": [
2137
+ { "name": "open", "type": "boolean", "default": "undefined" },
2138
+ { "name": "defaultOpen", "type": "boolean", "default": "false" },
2139
+ { "name": "onOpenChange", "type": "(open: boolean) => void", "default": "undefined" },
2140
+ { "name": "shouldScaleBackground", "type": "boolean", "default": "false" },
2141
+ { "name": "setBackgroundColorOnScale", "type": "boolean", "default": "true" },
2142
+ { "name": "closeThreshold", "type": "number", "default": "0.5" },
2143
+ { "name": "scrollLockTimeout", "type": "number", "default": "500" },
2144
+ { "name": "snapPoints", "type": "(number | string)[]", "default": "undefined" },
2145
+ { "name": "activeSnapPoint", "type": "number | string | null", "default": "undefined" },
2146
+ { "name": "setActiveSnapPoint", "type": "(snapPoint: number | string | null) => void", "default": "undefined" },
2147
+ { "name": "fadeFromIndex", "type": "number", "default": "snapPoints.length - 1" },
2148
+ { "name": "modal", "type": "boolean", "default": "true" },
2149
+ { "name": "handleOnly", "type": "boolean", "default": "false" },
2150
+ { "name": "dismissible", "type": "boolean", "default": "true" },
2151
+ { "name": "onDrag", "type": "(event: PointerEvent, percentageDragged: number) => void", "default": "undefined" },
2152
+ { "name": "onRelease", "type": "(event: PointerEvent, open: boolean) => void", "default": "undefined" },
2153
+ { "name": "noBodyStyles", "type": "boolean", "default": "false" },
2154
+ { "name": "direction", "type": "'top' | 'bottom' | 'left' | 'right'", "default": "'bottom'" },
2155
+ { "name": "preventScrollRestoration", "type": "boolean", "default": "true" },
2156
+ { "name": "disablePreventScroll", "type": "boolean", "default": "false" },
2157
+ { "name": "snapToSequentialPoint", "type": "boolean", "default": "false" },
2158
+ { "name": "onAnimationEnd", "type": "(open: boolean) => void", "default": "undefined" },
2159
+ { "name": "container", "type": "HTMLElement | null", "default": "document.body" },
2160
+ { "name": "nested", "type": "boolean", "default": "false" },
2161
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
2162
+ ],
2163
+ "DSDTrigger": [
2164
+ { "name": "asChild", "type": "boolean", "default": "false" },
2165
+ { "name": "className", "type": "string", "default": "undefined" },
2166
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
2167
+ ],
2168
+ "DSDPortal": [
2169
+ { "name": "container", "type": "HTMLElement | null", "default": "document.body" },
2170
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
2171
+ ],
2172
+ "DSDClose": [
2173
+ { "name": "asChild", "type": "boolean", "default": "false" },
2174
+ { "name": "className", "type": "string", "default": "undefined" },
2175
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
2176
+ ],
2177
+ "DSDOverlay": [
2178
+ { "name": "asChild", "type": "boolean", "default": "false" },
2179
+ { "name": "className", "type": "string", "default": "undefined" }
2180
+ ],
2181
+ "DSDContent": [
2182
+ { "name": "asChild", "type": "boolean", "default": "false" },
2183
+ { "name": "className", "type": "string", "default": "undefined" },
2184
+ { "name": "children", "type": "React.ReactNode", "default": "required" }
2185
+ ],
2186
+ "DSDTitle": [
2187
+ { "name": "asChild", "type": "boolean", "default": "false" },
2188
+ { "name": "className", "type": "string", "default": "undefined" },
2189
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
2190
+ ],
2191
+ "DSDDescription": [
2192
+ { "name": "asChild", "type": "boolean", "default": "false" },
2193
+ { "name": "className", "type": "string", "default": "undefined" },
2194
+ { "name": "children", "type": "React.ReactNode", "default": "undefined" }
2195
+ ],
2196
+ // LOADING UI
2197
+ "DSLoading": [
2198
+ { name: "variant", type: "default | minimal | card | centered", default: "default" },
2199
+ { name: "size", type: "default | sm | md | lg | full", default: "default" }
2200
+ ],
2201
+ // AVATAR SYSTEM
2202
+ "DSA": [
2203
+ { "name": "className", "type": "string", "default": "undefined" },
2204
+ { "name": "asChild", "type": "boolean", "default": "false" }
2205
+ ],
2206
+ "DSAImage": [
2207
+ { "name": "className", "type": "string", "default": "undefined" },
2208
+ { "name": "src", "type": "string", "default": "required" },
2209
+ { "name": "alt", "type": "string", "default": "required" },
2210
+ { "name": "onLoadingStatusChange", "type": "function", "default": "undefined" },
2211
+ { "name": "asChild", "type": "boolean", "default": "false" }
2212
+ ],
2213
+ "DSAFallback": [
2214
+ { "name": "className", "type": "string", "default": "undefined" },
2215
+ { "name": "delayMs", "type": "number", "default": "0" },
2216
+ { "name": "asChild", "type": "boolean", "default": "false" }
2217
+ ],
2218
+ // DROPDOWN MENU SYSTEM
2219
+ //
2220
+ "DSDM": [
2221
+ { "name": "defaultOpen", "type": "boolean", "default": "undefined" },
2222
+ { "name": "open", "type": "boolean", "default": "undefined" },
2223
+ { "name": "onOpenChange", "type": "(open: boolean) => void", "default": "undefined" },
2224
+ { "name": "dir", "type": "'ltr' | 'rtl'", "default": "undefined" },
2225
+ { "name": "modal", "type": "boolean", "default": "true" }
2226
+ ],
2227
+ "DSDMPortal": [
2228
+ { "name": "forceMount", "type": "boolean", "default": "undefined" },
2229
+ { "name": "container", "type": "HTMLElement | null", "default": "document.body" }
2230
+ ],
2231
+ "DSDMTrigger": [
2232
+ { "name": "asChild", "type": "boolean", "default": "false" },
2233
+ { "name": "disabled", "type": "boolean", "default": "false" }
2234
+ ],
2235
+ "DSDMContent": [
2236
+ { "name": "className", "type": "string", "default": "undefined" },
2237
+ { "name": "forceMount", "type": "boolean", "default": "undefined" },
2238
+ { "name": "side", "type": "'top' | 'right' | 'bottom' | 'left'", "default": "'bottom'" },
2239
+ { "name": "sideOffset", "type": "number", "default": "0" },
2240
+ { "name": "align", "type": "'start' | 'center' | 'end'", "default": "'center'" },
2241
+ { "name": "alignOffset", "type": "number", "default": "0" },
2242
+ { "name": "avoidCollisions", "type": "boolean", "default": "true" },
2243
+ { "name": "collisionBoundary", "type": "Element | Element[] | null", "default": "[]" },
2244
+ { "name": "collisionPadding", "type": "number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>", "default": "0" },
2245
+ { "name": "arrowPadding", "type": "number", "default": "0" },
2246
+ { "name": "sticky", "type": "'partial' | 'always'", "default": "'partial'" },
2247
+ { "name": "hideWhenDetached", "type": "boolean", "default": "false" },
2248
+ { "name": "loop", "type": "boolean", "default": "false" },
2249
+ { "name": "onCloseAutoFocus", "type": "(event: Event) => void", "default": "undefined" },
2250
+ { "name": "onEscapeKeyDown", "type": "(event: KeyboardEvent) => void", "default": "undefined" },
2251
+ { "name": "onPointerDownOutside", "type": "(event: PointerDownOutsideEvent) => void", "default": "undefined" },
2252
+ { "name": "onFocusOutside", "type": "(event: FocusOutsideEvent) => void", "default": "undefined" },
2253
+ { "name": "onInteractOutside", "type": "(event: PointerDownOutsideEvent | FocusOutsideEvent) => void", "default": "undefined" }
2254
+ ],
2255
+ "DSDMArrow": [
2256
+ { "name": "className", "type": "string", "default": "undefined" },
2257
+ { "name": "width", "type": "number", "default": "10" },
2258
+ { "name": "height", "type": "number", "default": "5" },
2259
+ { "name": "asChild", "type": "boolean", "default": "false" }
2260
+ ],
2261
+ "DSDMGroup": [
2262
+ { "name": "asChild", "type": "boolean", "default": "false" }
2263
+ ],
2264
+ "DSDMLabel": [
2265
+ { "name": "className", "type": "string", "default": "undefined" },
2266
+ { "name": "asChild", "type": "boolean", "default": "false" }
2267
+ ],
2268
+ "DSDMItem": [
2269
+ { "name": "className", "type": "string", "default": "undefined" },
2270
+ { "name": "disabled", "type": "boolean", "default": "false" },
2271
+ { "name": "onSelect", "type": "(event: Event) => void", "default": "undefined" },
2272
+ { "name": "textValue", "type": "string", "default": "undefined" },
2273
+ { "name": "asChild", "type": "boolean", "default": "false" }
2274
+ ],
2275
+ "DSDMCheckboxItem": [
2276
+ { "name": "className", "type": "string", "default": "undefined" },
2277
+ { "name": "checked", "type": "boolean | 'indeterminate'", "default": "undefined" },
2278
+ { "name": "onCheckedChange", "type": "(checked: boolean) => void", "default": "undefined" },
2279
+ { "name": "disabled", "type": "boolean", "default": "false" },
2280
+ { "name": "onSelect", "type": "(event: Event) => void", "default": "undefined" },
2281
+ { "name": "textValue", "type": "string", "default": "undefined" },
2282
+ { "name": "asChild", "type": "boolean", "default": "false" }
2283
+ ],
2284
+ "DSDMRadioGroup": [
2285
+ { "name": "value", "type": "string", "default": "undefined" },
2286
+ { "name": "onValueChange", "type": "(value: string) => void", "default": "undefined" },
2287
+ { "name": "asChild", "type": "boolean", "default": "false" }
2288
+ ],
2289
+ "DSDMRadioItem": [
2290
+ { "name": "className", "type": "string", "default": "undefined" },
2291
+ { "name": "value", "type": "string", "default": "required" },
2292
+ { "name": "disabled", "type": "boolean", "default": "false" },
2293
+ { "name": "onSelect", "type": "(event: Event) => void", "default": "undefined" },
2294
+ { "name": "textValue", "type": "string", "default": "undefined" },
2295
+ { "name": "asChild", "type": "boolean", "default": "false" }
2296
+ ],
2297
+ "DSDMItemIndicator": [
2298
+ { "name": "className", "type": "string", "default": "undefined" },
2299
+ { "name": "forceMount", "type": "boolean", "default": "undefined" },
2300
+ { "name": "asChild", "type": "boolean", "default": "false" }
2301
+ ],
2302
+ "DSDMSeparator": [
2303
+ { "name": "className", "type": "string", "default": "undefined" },
2304
+ { "name": "asChild", "type": "boolean", "default": "false" }
2305
+ ],
2306
+ "DSDMSub": [
2307
+ { "name": "defaultOpen", "type": "boolean", "default": "undefined" },
2308
+ { "name": "open", "type": "boolean", "default": "undefined" },
2309
+ { "name": "onOpenChange", "type": "(open: boolean) => void", "default": "undefined" }
2310
+ ],
2311
+ "DSDMSubTrigger": [
2312
+ { "name": "className", "type": "string", "default": "undefined" },
2313
+ { "name": "disabled", "type": "boolean", "default": "false" },
2314
+ { "name": "textValue", "type": "string", "default": "undefined" },
2315
+ { "name": "asChild", "type": "boolean", "default": "false" }
2316
+ ],
2317
+ "DSDMSubContent": [
2318
+ { "name": "className", "type": "string", "default": "undefined" },
2319
+ { "name": "forceMount", "type": "boolean", "default": "undefined" },
2320
+ { "name": "side", "type": "'top' | 'right' | 'bottom' | 'left'", "default": "'right'" },
2321
+ { "name": "sideOffset", "type": "number", "default": "0" },
2322
+ { "name": "align", "type": "'start' | 'center' | 'end'", "default": "'start'" },
2323
+ { "name": "alignOffset", "type": "number", "default": "0" },
2324
+ { "name": "avoidCollisions", "type": "boolean", "default": "true" },
2325
+ { "name": "collisionBoundary", "type": "Element | Element[] | null", "default": "[]" },
2326
+ { "name": "collisionPadding", "type": "number | Partial<Record<'top' | 'right' | 'bottom' | 'left', number>>", "default": "0" },
2327
+ { "name": "arrowPadding", "type": "number", "default": "0" },
2328
+ { "name": "sticky", "type": "'partial' | 'always'", "default": "'partial'" },
2329
+ { "name": "hideWhenDetached", "type": "boolean", "default": "false" },
2330
+ { "name": "loop", "type": "boolean", "default": "false" },
2331
+ { "name": "onEscapeKeyDown", "type": "(event: KeyboardEvent) => void", "default": "undefined" },
2332
+ { "name": "onPointerDownOutside", "type": "(event: PointerDownOutsideEvent) => void", "default": "undefined" },
2333
+ { "name": "onFocusOutside", "type": "(event: FocusOutsideEvent) => void", "default": "undefined" },
2334
+ { "name": "onInteractOutside", "type": "(event: PointerDownOutsideEvent | FocusOutsideEvent) => void", "default": "undefined" }
2335
+ ],
2336
+ // COLLAPSIBLE SYSTEM
2337
+ //
2338
+ "DSC": [
2339
+ { "name": "defaultOpen", "type": "boolean", "default": "false" },
2340
+ { "name": "open", "type": "boolean", "default": "undefined" },
2341
+ { "name": "onOpenChange", "type": "(open: boolean) => void", "default": "undefined" },
2342
+ { "name": "disabled", "type": "boolean", "default": "false" },
2343
+ { "name": "asChild", "type": "boolean", "default": "false" }
2344
+ ],
2345
+ "DSCTrigger": [
2346
+ { "name": "asChild", "type": "boolean", "default": "false" },
2347
+ { "name": "disabled", "type": "boolean", "default": "false" }
2348
+ ],
2349
+ "DSCContent": [
2350
+ { "name": "className", "type": "string", "default": "undefined" },
2351
+ { "name": "forceMount", "type": "boolean", "default": "undefined" },
2352
+ { "name": "asChild", "type": "boolean", "default": "false" }
2353
+ ],
2354
+ // HOOKS
2355
+ "useDS": [
2356
+ { name: "leftState", type: "expanded | collapsed", default: "readonly", description: "The current state of the sidebar." },
2357
+ { name: "rightState", type: "expanded | collapsed", default: "readonly" },
2358
+ { name: "openLeft", type: "boolean", default: "readonly", description: "Whether the sidebar is open." },
2359
+ { name: "openRight", type: "boolean", default: "readonly" },
2360
+ { name: "setOpenLeft", type: "(open: boolean) => void", default: "readonly", description: "Sets the open state of the sidebar." },
2361
+ { name: "setOpenRight", type: "(open: boolean) => void", default: "readonly", description: "" },
2362
+ { name: "openMobile", type: "boolean", default: "readonly", description: "Whether the sidebar is open on mobile." },
2363
+ { name: "openMobileRight", type: "boolean", default: "readonly", description: "" },
2364
+ { name: "setOpenMobile", type: "(open: boolean) => void", default: "readonly", description: "Sets the open state of the sidebar on mobile." },
2365
+ { name: "setOpenMobileRight", type: "(open: boolean) => void", default: "readonly", description: "" },
2366
+ { name: "toggleLeft", type: "() => void", default: "readonly", description: "Toggles the sidebar. Desktop and mobile." },
2367
+ { name: "toggleRight", type: "() => void", default: "readonly", description: "" },
2368
+ { name: "isMobile", type: "boolean", default: "readonly", description: "Whether the sidebar is on mobile." },
2369
+ { name: "sidebarWidth", type: "number", default: "readonly", description: "Controls the default width value." },
2370
+ { name: "leftVariant", type: "SidebarVariant", default: "readonly", description: "States the current variant type, this is more so used within the source file." },
2371
+ { name: "rightVariant", type: "SidebarVariant", default: "readonly", description: "" },
2372
+ { name: "setLeftVariant", type: "(variant: SidebarVariant) => void", default: "readonly", description: "Sets the state the current variant type, this is more so used within the source file" },
2373
+ { name: "setRightVariant", type: "(variant: SidebarVariant) => void", default: "readonly", description: "" },
2374
+ { name: "isIconLeftActive", type: "boolean", default: "readonly", description: "Checks if icon sidebars are actively used." },
2375
+ { name: "isIconRightActive", type: "boolean", default: "readonly", description: "" },
2376
+ { name: "setIsIconLeftActive", type: "(open: boolean) => void", default: "readonly", description: "Sets isIconLeftActive state, used within the source file." },
2377
+ { name: "setIsIconRightActive", type: "(open: boolean) => void", default: "readonly", description: "" },
2378
+ { name: "iconLeftWidth", type: "number", default: "readonly", description: "Controls the default width value." },
2379
+ { name: "iconRightWidth", type: "number", default: "readonly", description: "" },
2380
+ { name: "setIconLeftWidth", type: "(width: number) => void", default: "readonly", description: "Sets setIconLeftWidth state, used within the source file." },
2381
+ { name: "setIconRightWidth", type: "(width: number) => void", default: "readonly", description: "" },
2382
+ { name: "topHeight", type: "string", default: "readonly", description: "Sets height for inset variant styles." },
2383
+ { name: "setTopHeight", type: "(height: string) => void", default: "readonly", description: "" },
2384
+ { name: "bottomHeight", type: "string", default: "readonly", description: "" },
2385
+ { name: "setBottomHeight", type: "(height: string) => void", default: "readonly", description: "" }
2386
+ ],
2387
+ "useDSTheme": [
2388
+ { name: "theme", type: "DSTheme", default: "readonly" },
2389
+ { name: "setTheme", type: "(theme: DSTheme) => void", default: "readonly" },
2390
+ { name: "themeVars", type: "Record<string, string>", default: "readonly" }
2391
+ ]
2392
+ },
2393
+ desc: "Shadcn's original sidebar. Reverting it back to its original untouched state. If you would like an upgraded, and largely expanded version, see Dual Sidebar ( remix-run ) and Dual Sidebar Agnostic ( to be used with any platform ).",
2394
+ customize: null
2395
+ },
2396
+ {
2397
+ name: "ModalV1",
2398
+ value: "modal-1",
2399
+ importPath: "~/components/catalyst-ui/overlays/modal-integrations-1",
2400
+ multiImport: null,
2401
+ path: "/components/catlyst-ui/components/overlay/modal-integrations-1.tsx",
2402
+ premium: true,
2403
+ source: `
2404
+
2405
+
2406
+
2407
+
2408
+
2409
+ // Types
2410
+ export type ModalVariant = "default" | "alert" | "confirmation" | "success" | "error";
2411
+
2412
+ export interface ModalProps {
2413
+ open: boolean;
2414
+ onClose: () => void;
2415
+ title: string;
2416
+ description?: string;
2417
+ variant?: ModalVariant;
2418
+ showCloseButton?: boolean;
2419
+ children?: React.ReactNode;
2420
+ size?: "sm" | "md" | "lg" | "xl";
2421
+ overlayClassName?: string;
2422
+ contentClassName?: string;
2423
+ }
2424
+
2425
+ export function Modal({
2426
+ open,
2427
+ onClose,
2428
+ title,
2429
+ description,
2430
+ variant = "default",
2431
+ showCloseButton = true,
2432
+ children,
2433
+ size = "md",
2434
+ overlayClassName,
2435
+ contentClassName,
2436
+ }: ModalProps) {
2437
+ if (!open) return null;
2438
+
2439
+ // Handle escape key press
2440
+ useState(() => {
2441
+ const handleEscape = (e: KeyboardEvent) => {
2442
+ if (e.key === "Escape") onClose();
2443
+ };
2444
+
2445
+ if (open) {
2446
+ document.addEventListener("keydown", handleEscape);
2447
+ document.body.style.overflow = "hidden";
2448
+ }
2449
+
2450
+ return () => {
2451
+ document.removeEventListener("keydown", handleEscape);
2452
+ document.body.style.overflow = "unset";
2453
+ };
2454
+ });
2455
+
2456
+ const handleOverlayClick = (e: React.MouseEvent) => {
2457
+ if (e.target === e.currentTarget) onClose();
2458
+ };
2459
+
2460
+ // Get icon based on variant
2461
+ const getIcon = () => {
2462
+ switch (variant) {
2463
+ case "alert":
2464
+ return <AlertCircle className="h-6 w-6 text-yellow-500" />;
2465
+ case "confirmation":
2466
+ return <Info className="h-6 w-6 text-blue-500" />;
2467
+ case "success":
2468
+ return <CheckCircle2 className="h-6 w-6 text-green-500" />;
2469
+ case "error":
2470
+ return <AlertTriangle className="h-6 w-6 text-red-500" />;
2471
+ default:
2472
+ return null;
2473
+ }
2474
+ };
2475
+
2476
+ const sizeClasses = {
2477
+ sm: "max-w-md",
2478
+ md: "max-w-lg",
2479
+ lg: "max-w-2xl",
2480
+ xl: "max-w-4xl",
2481
+ };
2482
+
2483
+ return (
2484
+ <div
2485
+ className={cn(
2486
+ "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4 backdrop-blur-sm",
2487
+ overlayClassName
2488
+ )}
2489
+ onClick={handleOverlayClick}
2490
+ >
2491
+ <div
2492
+ className={cn(
2493
+ "relative w-full rounded-lg bg-background p-6 shadow-lg",
2494
+ sizeClasses[size],
2495
+ contentClassName
2496
+ )}
2497
+ >
2498
+ {showCloseButton && (
2499
+ <Button
2500
+ variant="ghost"
2501
+ size="icon"
2502
+ className="absolute right-4 top-4"
2503
+ onClick={onClose}
2504
+ >
2505
+ <X className="h-4 w-4" />
2506
+ <span className="sr-only">Close</span>
2507
+ </Button>
2508
+ )}
2509
+
2510
+ <div className="flex items-start gap-4">
2511
+ {variant !== "default" && <div className="mt-0.5">{getIcon()}</div>}
2512
+
2513
+ <div className="flex-1">
2514
+ <h3 className="text-lg font-semibold text-foreground">
2515
+ {title}
2516
+ </h3>
2517
+
2518
+ {description && (
2519
+ <p className="mt-2 text-sm text-muted-foreground">
2520
+ {description}
2521
+ </p>
2522
+ )}
2523
+
2524
+ {children && (
2525
+ <div className="mt-4">
2526
+ {children}
2527
+ </div>
2528
+ )}
2529
+ </div>
2530
+ </div>
2531
+ </div>
2532
+ </div>
2533
+ );
2534
+ }
2535
+
2536
+ // Confirmation Modal Component
2537
+ interface ConfirmationModalProps extends Omit<ModalProps, "children" | "variant"> {
2538
+ confirmText?: string;
2539
+ cancelText?: string;
2540
+ onConfirm: () => void;
2541
+ onCancel?: () => void;
2542
+ destructive?: boolean;
2543
+ }
2544
+
2545
+ export function ConfirmationModal({
2546
+ confirmText = "Confirm",
2547
+ cancelText = "Cancel",
2548
+ onConfirm,
2549
+ onCancel,
2550
+ destructive = false,
2551
+ ...props
2552
+ }: ConfirmationModalProps) {
2553
+ const handleCancel = () => {
2554
+ onCancel?.();
2555
+ props.onClose();
2556
+ };
2557
+
2558
+ const handleConfirm = () => {
2559
+ onConfirm();
2560
+ props.onClose();
2561
+ };
2562
+
2563
+ return (
2564
+ <Modal {...props} variant="confirmation">
2565
+ <div className="mt-6 flex justify-end gap-3">
2566
+ <Button variant="outline" onClick={handleCancel}>
2567
+ {cancelText}
2568
+ </Button>
2569
+ <Button
2570
+ variant={destructive ? "destructive" : "default"}
2571
+ onClick={handleConfirm}
2572
+ >
2573
+ {confirmText}
2574
+ </Button>
2575
+ </div>
2576
+ </Modal>
2577
+ );
2578
+ }
2579
+
2580
+ // Alert Modal Component
2581
+ interface AlertModalProps extends Omit<ModalProps, "children" | "variant"> {
2582
+ buttonText?: string;
2583
+ onButtonClick?: () => void;
2584
+ }
2585
+
2586
+ export function AlertModal({
2587
+ buttonText = "OK",
2588
+ onButtonClick,
2589
+ ...props
2590
+ }: AlertModalProps) {
2591
+ const handleButtonClick = () => {
2592
+ onButtonClick?.();
2593
+ props.onClose();
2594
+ };
2595
+
2596
+ return (
2597
+ <Modal {...props} variant="alert">
2598
+ <div className="mt-6 flex justify-end">
2599
+ <Button onClick={handleButtonClick}>
2600
+ {buttonText}
2601
+ </Button>
2602
+ </div>
2603
+ </Modal>
2604
+ );
2605
+ }
2606
+
2607
+ // Demo Component
2608
+ export function ModalIntegrationsDemo() {
2609
+ const [defaultOpen, setDefaultOpen] = useState(false);
2610
+ const [alertOpen, setAlertOpen] = useState(false);
2611
+ const [confirmOpen, setConfirmOpen] = useState(false);
2612
+ const [successOpen, setSuccessOpen] = useState(false);
2613
+ const [errorOpen, setErrorOpen] = useState(false);
2614
+
2615
+ return (
2616
+ <div className="p-6 space-y-4">
2617
+ <h2 className="text-2xl font-bold">Modal Demonstrations</h2>
2618
+
2619
+ <div className="flex flex-wrap gap-4">
2620
+ <Button onClick={() => setDefaultOpen(true)}>
2621
+ Open Default Modal
2622
+ </Button>
2623
+
2624
+ <Button onClick={() => setAlertOpen(true)}>
2625
+ Open Alert Modal
2626
+ </Button>
2627
+
2628
+ <Button onClick={() => setConfirmOpen(true)}>
2629
+ Open Confirmation Modal
2630
+ </Button>
2631
+
2632
+ <Button onClick={() => setSuccessOpen(true)}>
2633
+ Open Success Modal
2634
+ </Button>
2635
+
2636
+ <Button onClick={() => setErrorOpen(true)}>
2637
+ Open Error Modal
2638
+ </Button>
2639
+ </div>
2640
+
2641
+ {/* Default Modal */}
2642
+ <Modal
2643
+ open={defaultOpen}
2644
+ onClose={() => setDefaultOpen(false)}
2645
+ title="Default Modal"
2646
+ description="This is a default modal with some sample content."
2647
+ >
2648
+ <div className="mt-4 p-4 border rounded-md bg-muted/20">
2649
+ <p className="text-sm">Additional content can be placed here.</p>
2650
+ </div>
2651
+ </Modal>
2652
+
2653
+ {/* Alert Modal */}
2654
+ <AlertModal
2655
+ open={alertOpen}
2656
+ onClose={() => setAlertOpen(false)}
2657
+ title="Alert"
2658
+ description="This is an important alert message!"
2659
+ buttonText="Got it"
2660
+ />
2661
+
2662
+ {/* Confirmation Modal */}
2663
+ <ConfirmationModal
2664
+ open={confirmOpen}
2665
+ onClose={() => setConfirmOpen(false)}
2666
+ title="Confirm Action"
2667
+ description="Are you sure you want to proceed with this action?"
2668
+ confirmText="Yes, proceed"
2669
+ cancelText="No, cancel"
2670
+ onConfirm={() => console.log("Action confirmed")}
2671
+ />
2672
+
2673
+ {/* Success Modal */}
2674
+ <Modal
2675
+ open={successOpen}
2676
+ onClose={() => setSuccessOpen(false)}
2677
+ title="Success!"
2678
+ description="Your action was completed successfully."
2679
+ variant="success"
2680
+ >
2681
+ <div className="mt-4 flex justify-end">
2682
+ <Button onClick={() => setSuccessOpen(false)}>
2683
+ Continue
2684
+ </Button>
2685
+ </div>
2686
+ </Modal>
2687
+
2688
+ {/* Error Modal */}
2689
+ <Modal
2690
+ open={errorOpen}
2691
+ onClose={() => setErrorOpen(false)}
2692
+ title="Error"
2693
+ description="Something went wrong with your request."
2694
+ variant="error"
2695
+ >
2696
+ <div className="mt-4 flex justify-end">
2697
+ <Button variant="destructive" onClick={() => setErrorOpen(false)}>
2698
+ Dismiss
2699
+ </Button>
2700
+ </div>
2701
+ </Modal>
2702
+ </div>
2703
+ );
2704
+ }`,
2705
+ category: "Overlay",
2706
+ tags: ["ui", "components", "interactive"],
2707
+ features: ["Responsive", "TypeScript", "Accessible"],
2708
+ dependencies: ["react", "lucide-react"],
2709
+ basicusage: `
2710
+ <Modal>
2711
+ Content
2712
+ </Modal>
2713
+
2714
+ <Modal open="" onClose={() => {}} title="" description="" variant="default" showCloseButton=true children="" size="md" overlayClassName="" contentClassName={() => {}}>
2715
+ Content
2716
+ </Modal>`,
2717
+ usage: null,
2718
+ usagePath: "/components/catalyst-ui/components/overlay/modal-integrations-1",
2719
+ props: {
2720
+ "Modal": [
2721
+ { name: "open", type: "string", default: null },
2722
+ { name: "onClose", type: "string", default: null },
2723
+ { name: "title", type: "string", default: null },
2724
+ { name: "description", type: "string", default: null },
2725
+ { name: "variant", type: "string", default: "default" },
2726
+ { name: "showCloseButton", type: "boolean", default: true },
2727
+ { name: "children", type: "string", default: null },
2728
+ { name: "size", type: "string", default: "md" },
2729
+ { name: "overlayClassName", type: "string", default: null },
2730
+ { name: "contentClassName", type: "string", default: null }
2731
+ ],
2732
+ "ConfirmationModal": [
2733
+ { name: "confirmText", type: "string", default: "Confirm" },
2734
+ { name: "cancelText", type: "string", default: "Cancel" },
2735
+ { name: "onConfirm", type: "string", default: null },
2736
+ { name: "onCancel", type: "string", default: null },
2737
+ { name: "destructive", type: "boolean", default: false },
2738
+ { name: "props", type: "any", default: null }
2739
+ ],
2740
+ "AlertModal": [
2741
+ { name: "buttonText", type: "string", default: "OK" },
2742
+ { name: "onButtonClick", type: "string", default: null },
2743
+ { name: "props", type: "any", default: null }
2744
+ ],
2745
+ },
2746
+ desc: null,
2747
+ status: null,
2748
+ lastUpdated: null
2749
+ },
2750
+ {
2751
+ name: "Transitionable Portal",
2752
+ value: "transitionable-portal",
2753
+ importPath: "~/components/catalyst-ui/overlays/transitionable-portal",
2754
+ multiImport: null,
2755
+ path: "/components/catalyst-ui/components/overlay/transitionable-portal.tsx",
2756
+ premium: true,
2757
+ source: null,
2758
+ category: "Overlay",
2759
+ tags: ["ui", "components", "interactive"],
2760
+ features: ["Responsive", "TypeScript", "Accessible"],
2761
+ dependencies: ["react", "react-dom", "lucide-react"],
2762
+ basicusage: `
2763
+ <TransitionablePortal>
2764
+ Content
2765
+ </TransitionablePortal>
2766
+
2767
+ <TransitionablePortal children="" open="" onOpen={() => {}} onClose={() => {}} closeOnDocumentClick=true closeOnEscape=true trigger="" transition="fade" duration=300 className="" overlayClassName="" contentClassName={() => {}} showCloseButton=false portal="">
2768
+ Content
2769
+ </TransitionablePortal>`,
2770
+ usage: null,
2771
+ usagePath: "/components/catalyst-ui/components/overlay/transitionable-portal.tsx",
2772
+ props: {
2773
+ "TransitionablePortal": [
2774
+ { name: "children", type: "string", default: null },
2775
+ { name: "open", type: "string", default: null },
2776
+ { name: "onOpen", type: "string", default: null },
2777
+ { name: "onClose", type: "string", default: null },
2778
+ { name: "closeOnDocumentClick", type: "boolean", default: true },
2779
+ { name: "closeOnEscape", type: "boolean", default: true },
2780
+ { name: "trigger", type: "string", default: null },
2781
+ { name: "transition", type: "string", default: "fade" },
2782
+ { name: "duration", type: "number", default: 300 },
2783
+ { name: "className", type: "string", default: null },
2784
+ { name: "overlayClassName", type: "string", default: null },
2785
+ { name: "contentClassName", type: "string", default: null },
2786
+ { name: "showCloseButton", type: "boolean", default: false },
2787
+ { name: "portal", type: "string", default: null }
2788
+ ],
2789
+ },
2790
+ desc: null,
2791
+ status: null,
2792
+ lastUpdated: null
2793
+ },
2794
+ {
2795
+ name: "Modal Integrations",
2796
+ value: "modal-integrations",
2797
+ importPath: "~/components/catalyst-ui/overlays/modal-integrations",
2798
+ multiImport: "Modal, ConfirmationModal, AlertModal",
2799
+ path: "/components/catlyst-ui/components/overlay/modal-integrations.tsx",
2800
+ premium: true,
2801
+ source: `
2802
+
2803
+
2804
+
2805
+
2806
+
2807
+ // Types
2808
+ export type ModalVariant = "default" | "alert" | "confirmation" | "success" | "error";
2809
+
2810
+ export interface ModalProps {
2811
+ open: boolean;
2812
+ onClose: () => void;
2813
+ title: string;
2814
+ description?: string;
2815
+ variant?: ModalVariant;
2816
+ showCloseButton?: boolean;
2817
+ children?: React.ReactNode;
2818
+ size?: "sm" | "md" | "lg" | "xl";
2819
+ overlayClassName?: string;
2820
+ contentClassName?: string;
2821
+ }
2822
+
2823
+ export function Modal({
2824
+ open,
2825
+ onClose,
2826
+ title,
2827
+ description,
2828
+ variant = "default",
2829
+ showCloseButton = true,
2830
+ children,
2831
+ size = "md",
2832
+ overlayClassName,
2833
+ contentClassName,
2834
+ }: ModalProps) {
2835
+ if (!open) return null;
2836
+
2837
+ // Handle escape key press
2838
+ useState(() => {
2839
+ const handleEscape = (e: KeyboardEvent) => {
2840
+ if (e.key === "Escape") onClose();
2841
+ };
2842
+
2843
+ if (open) {
2844
+ document.addEventListener("keydown", handleEscape);
2845
+ document.body.style.overflow = "hidden";
2846
+ }
2847
+
2848
+ return () => {
2849
+ document.removeEventListener("keydown", handleEscape);
2850
+ document.body.style.overflow = "unset";
2851
+ };
2852
+ });
2853
+
2854
+ const handleOverlayClick = (e: React.MouseEvent) => {
2855
+ if (e.target === e.currentTarget) onClose();
2856
+ };
2857
+
2858
+ // Get icon based on variant
2859
+ const getIcon = () => {
2860
+ switch (variant) {
2861
+ case "alert":
2862
+ return <AlertCircle className="h-6 w-6 text-yellow-500" />;
2863
+ case "confirmation":
2864
+ return <Info className="h-6 w-6 text-blue-500" />;
2865
+ case "success":
2866
+ return <CheckCircle2 className="h-6 w-6 text-green-500" />;
2867
+ case "error":
2868
+ return <AlertTriangle className="h-6 w-6 text-red-500" />;
2869
+ default:
2870
+ return null;
2871
+ }
2872
+ };
2873
+
2874
+ const sizeClasses = {
2875
+ sm: "max-w-md",
2876
+ md: "max-w-lg",
2877
+ lg: "max-w-2xl",
2878
+ xl: "max-w-4xl",
2879
+ };
2880
+
2881
+ return (
2882
+ <div
2883
+ className={cn(
2884
+ "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4 backdrop-blur-sm",
2885
+ overlayClassName
2886
+ )}
2887
+ onClick={handleOverlayClick}
2888
+ >
2889
+ <div
2890
+ className={cn(
2891
+ "relative w-full rounded-lg bg-background p-6 shadow-lg",
2892
+ sizeClasses[size],
2893
+ contentClassName
2894
+ )}
2895
+ >
2896
+ {showCloseButton && (
2897
+ <Button
2898
+ variant="ghost"
2899
+ size="icon"
2900
+ className="absolute right-4 top-4"
2901
+ onClick={onClose}
2902
+ >
2903
+ <X className="h-4 w-4" />
2904
+ <span className="sr-only">Close</span>
2905
+ </Button>
2906
+ )}
2907
+
2908
+ <div className="flex items-start gap-4">
2909
+ {variant !== "default" && <div className="mt-0.5">{getIcon()}</div>}
2910
+
2911
+ <div className="flex-1">
2912
+ <h3 className="text-lg font-semibold text-foreground">
2913
+ {title}
2914
+ </h3>
2915
+
2916
+ {description && (
2917
+ <p className="mt-2 text-sm text-muted-foreground">
2918
+ {description}
2919
+ </p>
2920
+ )}
2921
+
2922
+ {children && (
2923
+ <div className="mt-4">
2924
+ {children}
2925
+ </div>
2926
+ )}
2927
+ </div>
2928
+ </div>
2929
+ </div>
2930
+ </div>
2931
+ );
2932
+ }
2933
+
2934
+ // Confirmation Modal Component
2935
+ interface ConfirmationModalProps extends Omit<ModalProps, "children" | "variant"> {
2936
+ confirmText?: string;
2937
+ cancelText?: string;
2938
+ onConfirm: () => void;
2939
+ onCancel?: () => void;
2940
+ destructive?: boolean;
2941
+ }
2942
+
2943
+ export function ConfirmationModal({
2944
+ confirmText = "Confirm",
2945
+ cancelText = "Cancel",
2946
+ onConfirm,
2947
+ onCancel,
2948
+ destructive = false,
2949
+ ...props
2950
+ }: ConfirmationModalProps) {
2951
+ const handleCancel = () => {
2952
+ onCancel?.();
2953
+ props.onClose();
2954
+ };
2955
+
2956
+ const handleConfirm = () => {
2957
+ onConfirm();
2958
+ props.onClose();
2959
+ };
2960
+
2961
+ return (
2962
+ <Modal {...props} variant="confirmation">
2963
+ <div className="mt-6 flex justify-end gap-3">
2964
+ <Button variant="outline" onClick={handleCancel}>
2965
+ {cancelText}
2966
+ </Button>
2967
+ <Button
2968
+ variant={destructive ? "destructive" : "default"}
2969
+ onClick={handleConfirm}
2970
+ >
2971
+ {confirmText}
2972
+ </Button>
2973
+ </div>
2974
+ </Modal>
2975
+ );
2976
+ }
2977
+
2978
+ // Alert Modal Component
2979
+ interface AlertModalProps extends Omit<ModalProps, "children" | "variant"> {
2980
+ buttonText?: string;
2981
+ onButtonClick?: () => void;
2982
+ }
2983
+
2984
+ export function AlertModal({
2985
+ buttonText = "OK",
2986
+ onButtonClick,
2987
+ ...props
2988
+ }: AlertModalProps) {
2989
+ const handleButtonClick = () => {
2990
+ onButtonClick?.();
2991
+ props.onClose();
2992
+ };
2993
+
2994
+ return (
2995
+ <Modal {...props} variant="alert">
2996
+ <div className="mt-6 flex justify-end">
2997
+ <Button onClick={handleButtonClick}>
2998
+ {buttonText}
2999
+ </Button>
3000
+ </div>
3001
+ </Modal>
3002
+ );
3003
+ }
3004
+
3005
+ // Demo Component
3006
+ export function ModalIntegrationsDemo() {
3007
+ const [defaultOpen, setDefaultOpen] = useState(false);
3008
+ const [alertOpen, setAlertOpen] = useState(false);
3009
+ const [confirmOpen, setConfirmOpen] = useState(false);
3010
+ const [successOpen, setSuccessOpen] = useState(false);
3011
+ const [errorOpen, setErrorOpen] = useState(false);
3012
+
3013
+ return (
3014
+ <div className="p-6 space-y-4">
3015
+ <h2 className="text-2xl font-bold">Modal Demonstrations</h2>
3016
+
3017
+ <div className="flex flex-wrap gap-4">
3018
+ <Button onClick={() => setDefaultOpen(true)}>
3019
+ Open Default Modal
3020
+ </Button>
3021
+
3022
+ <Button onClick={() => setAlertOpen(true)}>
3023
+ Open Alert Modal
3024
+ </Button>
3025
+
3026
+ <Button onClick={() => setConfirmOpen(true)}>
3027
+ Open Confirmation Modal
3028
+ </Button>
3029
+
3030
+ <Button onClick={() => setSuccessOpen(true)}>
3031
+ Open Success Modal
3032
+ </Button>
3033
+
3034
+ <Button onClick={() => setErrorOpen(true)}>
3035
+ Open Error Modal
3036
+ </Button>
3037
+ </div>
3038
+
3039
+ {/* Default Modal */}
3040
+ <Modal
3041
+ open={defaultOpen}
3042
+ onClose={() => setDefaultOpen(false)}
3043
+ title="Default Modal"
3044
+ description="This is a default modal with some sample content."
3045
+ >
3046
+ <div className="mt-4 p-4 border rounded-md bg-muted/20">
3047
+ <p className="text-sm">Additional content can be placed here.</p>
3048
+ </div>
3049
+ </Modal>
3050
+
3051
+ {/* Alert Modal */}
3052
+ <AlertModal
3053
+ open={alertOpen}
3054
+ onClose={() => setAlertOpen(false)}
3055
+ title="Alert"
3056
+ description="This is an important alert message!"
3057
+ buttonText="Got it"
3058
+ />
3059
+
3060
+ {/* Confirmation Modal */}
3061
+ <ConfirmationModal
3062
+ open={confirmOpen}
3063
+ onClose={() => setConfirmOpen(false)}
3064
+ title="Confirm Action"
3065
+ description="Are you sure you want to proceed with this action?"
3066
+ confirmText="Yes, proceed"
3067
+ cancelText="No, cancel"
3068
+ onConfirm={() => console.log("Action confirmed")}
3069
+ />
3070
+
3071
+ {/* Success Modal */}
3072
+ <Modal
3073
+ open={successOpen}
3074
+ onClose={() => setSuccessOpen(false)}
3075
+ title="Success!"
3076
+ description="Your action was completed successfully."
3077
+ variant="success"
3078
+ >
3079
+ <div className="mt-4 flex justify-end">
3080
+ <Button onClick={() => setSuccessOpen(false)}>
3081
+ Continue
3082
+ </Button>
3083
+ </div>
3084
+ </Modal>
3085
+
3086
+ {/* Error Modal */}
3087
+ <Modal
3088
+ open={errorOpen}
3089
+ onClose={() => setErrorOpen(false)}
3090
+ title="Error"
3091
+ description="Something went wrong with your request."
3092
+ variant="error"
3093
+ >
3094
+ <div className="mt-4 flex justify-end">
3095
+ <Button variant="destructive" onClick={() => setErrorOpen(false)}>
3096
+ Dismiss
3097
+ </Button>
3098
+ </div>
3099
+ </Modal>
3100
+ </div>
3101
+ );
3102
+ }`,
3103
+ category: "Overlay",
3104
+ tags: ["ui", "components", "interactive"],
3105
+ features: ["Responsive", "TypeScript", "Accessible"],
3106
+ dependencies: ["react", "lucide-react"],
3107
+ basicusage: `
3108
+ <Modal>
3109
+ Content
3110
+ </Modal>
3111
+
3112
+ <Modal open="" onClose={() => {}} title="" description="" variant="default" showCloseButton=true children="" size="md" overlayClassName="" contentClassName={() => {}}>
3113
+ Content
3114
+ </Modal>`,
3115
+ usage: null,
3116
+ usagePath: null,
3117
+ props: {
3118
+ "Modal": [
3119
+ { name: "open", type: "string", default: null },
3120
+ { name: "onClose", type: "string", default: null },
3121
+ { name: "title", type: "string", default: null },
3122
+ { name: "description", type: "string", default: null },
3123
+ { name: "variant", type: "string", default: "default" },
3124
+ { name: "showCloseButton", type: "boolean", default: true },
3125
+ { name: "children", type: "string", default: null },
3126
+ { name: "size", type: "string", default: "md" },
3127
+ { name: "overlayClassName", type: "string", default: null },
3128
+ { name: "contentClassName", type: "string", default: null }
3129
+ ],
3130
+ "ConfirmationModal": [
3131
+ { name: "confirmText", type: "string", default: "Confirm" },
3132
+ { name: "cancelText", type: "string", default: "Cancel" },
3133
+ { name: "onConfirm", type: "string", default: null },
3134
+ { name: "onCancel", type: "string", default: null },
3135
+ { name: "destructive", type: "boolean", default: false },
3136
+ { name: "props", type: "any", default: null }
3137
+ ],
3138
+ "AlertModal": [
3139
+ { name: "buttonText", type: "string", default: "OK" },
3140
+ { name: "onButtonClick", type: "string", default: null },
3141
+ { name: "props", type: "any", default: null }
3142
+ ],
3143
+ },
3144
+ desc: null,
3145
+ status: null,
3146
+ lastUpdated: null
3147
+ },
3148
+ {
3149
+ name: "Loading Overlay",
3150
+ value: "loading-overlay",
3151
+ importPath: "~/components/catalyst-ui/overlays/loading-overlay",
3152
+ path: "/components/catalyst-ui/components/overlay/loading-overlay.tsx",
3153
+ source: null,
3154
+ usagePath: "/components/catalyst-ui/components/overlay/loading-overlay.tsx",
3155
+ basicusage: `
3156
+ const [visible, setVisible] = useState(false)
3157
+
3158
+ <LoadingOverlay visible={visible} />
3159
+ `,
3160
+ usage: null,
3161
+ premium: true,
3162
+ category: "Overlay",
3163
+ tags: ["overlay", "loading", "spinner"],
3164
+ features: ["Responsive", "TypeScript", "Accessible"],
3165
+ dependencies: ["lucide-react"],
3166
+ props: [
3167
+ { name: "visible", type: "boolean", default: "false" },
3168
+ { name: "loaderProps", type: "props", default: "null" },
3169
+ { name: "overlayProps", type: "props", default: "null" },
3170
+ { name: "className", type: "string", default: "null" },
3171
+ { name: "zIndex", type: "int", default: 1000 },
3172
+ ],
3173
+ props2: [],
3174
+ desc: "Check source file for usage. Loading overlay component with customizable spinner and backdrop",
3175
+ status: null,
3176
+ lastUpdated: null
3177
+ },
3178
+ {
3179
+ name: "Overlay Panel",
3180
+ value: "overlay-panel",
3181
+ importPath: "~/components/catalyst-ui/overlays/overlay-panel",
3182
+ path: "/components/catalyst-ui/components/overlay/overlay-panel.tsx",
3183
+ premium: true,
3184
+ source: `
3185
+
3186
+
3187
+
3188
+
3189
+
3190
+
3191
+ export type OverlayPanelProps = {
3192
+ children: React.ReactNode;
3193
+ content: React.ReactNode;
3194
+ className?: string;
3195
+ closeOnClickOutside?: boolean;
3196
+ showCloseButton?: boolean;
3197
+ placement?: "top" | "right" | "bottom" | "left";
3198
+ open?: boolean;
3199
+ onOpenChange?: (open: boolean) => void;
3200
+ };
3201
+
3202
+ export function OverlayPanel({
3203
+ children,
3204
+ content,
3205
+ className,
3206
+ closeOnClickOutside = true,
3207
+ showCloseButton = true,
3208
+ placement = "bottom",
3209
+ open,
3210
+ onOpenChange,
3211
+ }: OverlayPanelProps) {
3212
+ const [isOpen, setIsOpen] = React.useState(false);
3213
+ const controlled = open !== undefined;
3214
+ const panelOpen = controlled ? open : isOpen;
3215
+
3216
+ const handleOpenChange = (open: boolean) => {
3217
+ if (!controlled) {
3218
+ setIsOpen(open);
3219
+ }
3220
+ onOpenChange?.(open);
3221
+ };
3222
+
3223
+ const handleClose = () => {
3224
+ handleOpenChange(false);
3225
+ };
3226
+
3227
+ return (
3228
+ <Popover open={panelOpen} onOpenChange={handleOpenChange}>
3229
+ <PopoverTrigger asChild>{children}</PopoverTrigger>
3230
+ <PopoverContent
3231
+ className={cn("w-80 p-4", className)}
3232
+ align={placement}
3233
+ onCloseAutoFocus={(e) => e.preventDefault()}
3234
+ >
3235
+ <div className="relative">
3236
+ {showCloseButton && (
3237
+ <Button
3238
+ variant="ghost"
3239
+ size="icon"
3240
+ className="absolute right-0 top-0 h-6 w-6"
3241
+ onClick={handleClose}
3242
+ >
3243
+ <X className="h-4 w-4" />
3244
+ </Button>
3245
+ )}
3246
+ <div className={showCloseButton ? "pr-6" : ""}>
3247
+ {content}
3248
+ </div>
3249
+ </div>
3250
+ </PopoverContent>
3251
+ </Popover>
3252
+ );
3253
+ }`,
3254
+ basicusage: `
3255
+
3256
+
3257
+ function ExampleComponent() {
3258
+ return (
3259
+ <OverlayPanel
3260
+ content={
3261
+ <div className="space-y-4">
3262
+ <h3 className="font-semibold">Panel Title</h3>
3263
+ <p className="text-sm text-muted-foreground">
3264
+ This is the content of the overlay panel.
3265
+ </p>
3266
+ <Button size="sm">Action</Button>
3267
+ </div>
3268
+ }
3269
+ placement="right"
3270
+ showCloseButton={true}
3271
+ >
3272
+ <Button>Open Panel</Button>
3273
+ </OverlayPanel>
3274
+ );
3275
+ }`,
3276
+ usage: `
3277
+
3278
+ <OverlayPanel
3279
+ content={
3280
+ <div className="space-y-4">
3281
+ <h3 className="font-semibold">Basic Panel</h3>
3282
+ <p className="text-sm text-muted-foreground">
3283
+ This is a basic overlay panel with some content. You can put any
3284
+ content here including forms, images, or other components.
3285
+ </p>
3286
+ <Button size="sm">Action</Button>
3287
+ </div>
3288
+ }
3289
+ >
3290
+
3291
+ <OverlayPanel
3292
+ placement="right"
3293
+ content={
3294
+ <div className="space-y-4">
3295
+ <h3 className="font-semibold">Right Aligned</h3>
3296
+ <p className="text-sm text-muted-foreground">
3297
+ This panel appears on the right side of the trigger.
3298
+ </p>
3299
+ <div className="flex gap-2">
3300
+ <Button variant="outline" size="sm">
3301
+ Cancel
3302
+ </Button>
3303
+ <Button size="sm">Confirm</Button>
3304
+ </div>
3305
+ </div>
3306
+ }
3307
+ >
3308
+ <Button variant="outline">Right Panel</Button>
3309
+ </OverlayPanel>
3310
+
3311
+ <OverlayPanel
3312
+ showCloseButton={false}
3313
+ content={
3314
+ <div className="space-y-4">
3315
+ <h3 className="font-semibold">No Close Button</h3>
3316
+ <p className="text-sm text-muted-foreground">
3317
+ This panel doesn't have a close button. Click outside to close.
3318
+ </p>
3319
+ <Button variant="outline" size="sm" onClick={() => { }}>
3320
+ Close Programmatically
3321
+ </Button>
3322
+ </div>
3323
+ }
3324
+ >
3325
+ <Button variant="outline">No Close Button</Button>
3326
+ </OverlayPanel>
3327
+
3328
+ <OverlayPanel
3329
+ className="w-96"
3330
+ content={
3331
+ <div className="space-y-4">
3332
+ <h3 className="font-semibold">Wider Panel</h3>
3333
+ <p className="text-sm text-muted-foreground">
3334
+ This panel has custom width and more content area for larger
3335
+ content displays.
3336
+ </p>
3337
+ <div className="grid grid-cols-2 gap-2">
3338
+ <Button variant="outline" size="sm">
3339
+ Option 1
3340
+ </Button>
3341
+ <Button variant="outline" size="sm">
3342
+ Option 2
3343
+ </Button>
3344
+ <Button variant="outline" size="sm">
3345
+ Option 3
3346
+ </Button>
3347
+ <Button variant="outline" size="sm">
3348
+ Option 4
3349
+ </Button>
3350
+ </div>
3351
+ </div>
3352
+ }
3353
+ >
3354
+ <Button variant="outline">Wider Panel</Button>
3355
+ </OverlayPanel>
3356
+
3357
+ <OverlayPanel
3358
+ open={customOpen}
3359
+ onOpenChange={setCustomOpen}
3360
+ content={
3361
+ <div className="space-y-4">
3362
+ <h3 className="font-semibold">Controlled Panel</h3>
3363
+ <p className="text-sm text-muted-foreground">
3364
+ This panel is controlled by external state.
3365
+ </p>
3366
+ <Button
3367
+ variant="outline"
3368
+ size="sm"
3369
+ onClick={() => setCustomOpen(false)}
3370
+ >
3371
+ Close
3372
+ </Button>
3373
+ </div>
3374
+ }
3375
+ >
3376
+ <Button onClick={() => setCustomOpen(true)}>
3377
+ Controlled Panel
3378
+ </Button>
3379
+ </OverlayPanel>
3380
+
3381
+ <OverlayPanel
3382
+ placement="top"
3383
+ content={
3384
+ <div className="space-y-4">
3385
+ <h3 className="font-semibold">Top Panel</h3>
3386
+ <p className="text-sm text-muted-foreground">
3387
+ This panel appears above the trigger element.
3388
+ </p>
3389
+ <div className="flex gap-2">
3390
+ <Button variant="outline" size="sm">
3391
+ Cancel
3392
+ </Button>
3393
+ <Button size="sm">Save</Button>
3394
+ </div>
3395
+ </div>
3396
+ }
3397
+ >
3398
+ <Button variant="outline">Top Panel</Button>
3399
+ </OverlayPanel>
3400
+ `,
3401
+ usagePath: null,
3402
+ category: "Overlay",
3403
+ tags: ["ui", "components", "interactive"],
3404
+ features: ["Responsive", "TypeScript", "Accessible"],
3405
+ dependencies: [],
3406
+ props: [
3407
+ { "name": "children", "type": "React.ReactNode", "default": "undefined", "required": true },
3408
+ { "name": "content", "type": "React.ReactNode", "default": "undefined", "required": true },
3409
+ { "name": "className", "type": "string", "default": "undefined" },
3410
+ { "name": "closeOnClickOutside", "type": "boolean", "default": "true" },
3411
+ { "name": "showCloseButton", "type": "boolean", "default": "true" },
3412
+ { "name": "placement", "type": "'top' | 'right' | 'bottom' | 'left'", "default": "'bottom'" },
3413
+ { "name": "open", "type": "boolean", "default": "undefined" },
3414
+ { "name": "onOpenChange", "type": "(open: boolean) => void", "default": "undefined" }
3415
+ ],
3416
+ props2: [],
3417
+ desc: null,
3418
+ status: null,
3419
+ lastUpdated: null
3420
+ },
3421
+ {
3422
+ name: "modal integrations",
3423
+ value: "modal-integrations",
3424
+ importPath: "~/components/catalyst-ui/overlays/modal-integrations",
3425
+ path: "/components/catalyst-ui/components/overlay/modal-integrations.tsx",
3426
+ premium: true,
3427
+ source: null,
3428
+ usage: null,
3429
+ usagePath: null,
3430
+ category: "Overlay",
3431
+ tags: ["ui", "components", "interactive"],
3432
+ features: ["Responsive", "TypeScript", "Accessible"],
3433
+ dependencies: ["@radix-ui/react-aspect-ratio"],
3434
+ props: [
3435
+ { name: "className", type: "string", default: "null" },
3436
+ { name: "size", type: "sm | md | lg | xl", default: "md" },
3437
+ ],
3438
+ props2: [],
3439
+ desc: null,
3440
+ status: null,
3441
+ lastUpdated: null
3442
+ },
3443
+ {
3444
+ name: "confirm popup",
3445
+ value: "confirm-popup",
3446
+ importPath: "~/components/catalyst-ui/overlays/confirm-popup",
3447
+ path: "/components/catalyst-ui/components/overlay/confirm-popup.tsx",
3448
+ premium: true,
3449
+ source: ``,
3450
+ basicusage: `
3451
+
3452
+
3453
+ function ExampleComponent() {
3454
+ return (
3455
+ <ConfirmPopup
3456
+ title="Delete Item"
3457
+ message="Are you sure you want to delete this item?"
3458
+ onConfirm={() => console.log("Item deleted")}
3459
+ acceptLabel="Delete"
3460
+ rejectLabel="Cancel"
3461
+ variant="danger"
3462
+ >
3463
+ <Button variant="destructive">Delete Item</Button>
3464
+ </ConfirmPopup>
3465
+ );
3466
+ }
3467
+ `,
3468
+ usage: `
3469
+ <ConfirmPopup
3470
+ title="Delete Item"
3471
+ message="Are you sure you want to delete this item? This action cannot be undone."
3472
+ onConfirm={() => console.log("Item deleted")}
3473
+ acceptLabel="Delete"
3474
+ rejectLabel="Cancel"
3475
+ variant="danger"
3476
+ >
3477
+ <Button variant="destructive">Danger Variant</Button>
3478
+ </ConfirmPopup>
3479
+
3480
+ <ConfirmPopup
3481
+ title="Confirm Action"
3482
+ message="Do you want to proceed with this action?"
3483
+ onConfirm={() => console.log("Action confirmed")}
3484
+ variant="default"
3485
+ >
3486
+ <Button>Default Variant</Button>
3487
+ </ConfirmPopup>
3488
+
3489
+ <ConfirmPopup
3490
+ title="Warning"
3491
+ message="This action might have unintended consequences. Are you sure?"
3492
+ onConfirm={() => console.log("Warning action confirmed")}
3493
+ variant="warning"
3494
+ >
3495
+ <Button variant="outline">Warning Variant</Button>
3496
+ </ConfirmPopup>
3497
+
3498
+ <ConfirmPopup
3499
+ title="Information"
3500
+ message="You need to confirm this information before proceeding."
3501
+ onConfirm={() => console.log("Info action confirmed")}
3502
+ variant="info"
3503
+ >
3504
+ <Button variant="outline">Info Variant</Button>
3505
+ </ConfirmPopup>
3506
+
3507
+ <ConfirmPopup
3508
+ title="Success"
3509
+ message="Your action was completed successfully. Would you like to continue?"
3510
+ onConfirm={() => console.log("Success action confirmed")}
3511
+ variant="success"
3512
+ >
3513
+ <Button variant="default">Success Variant</Button>
3514
+ </ConfirmPopup>
3515
+
3516
+ <ConfirmPopup
3517
+ title="Controlled Example"
3518
+ message="This popup is controlled by external state."
3519
+ onConfirm={() => setShowSuccessPopup(false)}
3520
+ onCancel={() => setShowSuccessPopup(false)}
3521
+ open={showSuccessPopup}
3522
+ onOpenChange={setShowSuccessPopup}
3523
+ variant="success"
3524
+ >
3525
+ <Button onClick={() => setShowSuccessPopup(true)}>
3526
+ Controlled Popup
3527
+ </Button>
3528
+ </ConfirmPopup>
3529
+ `,
3530
+ usagePath: null,
3531
+ category: "Overlay",
3532
+ tags: ["ui", "components", "interactive"],
3533
+ features: ["Responsive", "TypeScript", "Accessible"],
3534
+ dependencies: ["@radix-ui/react-aspect-ratio"],
3535
+ props: [
3536
+ { "name": "children", "type": "React.ReactNode", "default": "undefined", "required": true },
3537
+ { "name": "title", "type": "string", "default": "undefined" },
3538
+ { "name": "message", "type": "string", "default": "undefined", "required": true },
3539
+ { "name": "onConfirm", "type": "() => void", "default": "undefined", "required": true },
3540
+ { "name": "onCancel", "type": "() => void", "default": "undefined" },
3541
+ { "name": "acceptLabel", "type": "string", "default": "\"Yes\"" },
3542
+ { "name": "rejectLabel", "type": "string", "default": "\"No\"" },
3543
+ { "name": "variant", "type": "\"default\" | \"danger\" | \"warning\" | \"info\" | \"success\"", "default": "\"default\"" },
3544
+ { "name": "open", "type": "boolean", "default": "undefined" },
3545
+ { "name": "onOpenChange", "type": "(open: boolean) => void", "default": "undefined" }
3546
+ ],
3547
+ props2: [],
3548
+ desc: null,
3549
+ status: null,
3550
+ lastUpdated: null
3551
+ },
3552
+ {
3553
+ name: "Popconfirm",
3554
+ value: "popconfirm",
3555
+ importPath: "~/components/catalyst-ui/overlays/popconfirm",
3556
+ path: "/components/catlyst-ui/components/overlay/popconfirm.tsx",
3557
+ premium: true,
3558
+ source: `
3559
+
3560
+
3561
+
3562
+
3563
+
3564
+
3565
+
3566
+
3567
+
3568
+
3569
+
3570
+ const Popover = PopoverPrimitive.Root;
3571
+ const PopoverTrigger = PopoverPrimitive.Trigger;
3572
+
3573
+ const popconfirmVariants = cva(
3574
+ "z-50 w-72 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
3575
+ {
3576
+ variants: {
3577
+ variant: {
3578
+ default: "",
3579
+ warning: "border-yellow-200 bg-yellow-50 text-yellow-900 dark:border-yellow-800 dark:bg-yellow-950 dark:text-yellow-100",
3580
+ danger: "border-red-200 bg-red-50 text-red-900 dark:border-red-800 dark:bg-red-950 dark:text-red-100",
3581
+ info: "border-blue-200 bg-blue-50 text-blue-900 dark:border-blue-800 dark:bg-blue-950 dark:text-blue-100",
3582
+ success: "border-green-200 bg-green-50 text-green-900 dark:border-green-800 dark:bg-green-950 dark:text-green-100",
3583
+ },
3584
+ size: {
3585
+ default: "w-72",
3586
+ sm: "w-64",
3587
+ lg: "w-80",
3588
+ xl: "w-96",
3589
+ },
3590
+ },
3591
+ defaultVariants: {
3592
+ variant: "default",
3593
+ size: "default",
3594
+ },
3595
+ }
3596
+ );
3597
+
3598
+ const PopoverContent = React.forwardRef<
3599
+ React.ElementRef<typeof PopoverPrimitive.Content>,
3600
+ React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content> &
3601
+ VariantProps<typeof popconfirmVariants>
3602
+ >(({ className, variant, size, align = "center", sideOffset = 4, ...props }, ref) => (
3603
+ <PopoverPrimitive.Portal>
3604
+ <PopoverPrimitive.Content
3605
+ ref={ref}
3606
+ align={align}
3607
+ sideOffset={sideOffset}
3608
+ className={cn(popconfirmVariants({ variant, size }), className)}
3609
+ {...props}
3610
+ />
3611
+ </PopoverPrimitive.Portal>
3612
+ ));
3613
+ PopoverContent.displayName = PopoverPrimitive.Content.displayName;
3614
+
3615
+ interface PopconfirmProps {
3616
+ children: React.ReactNode;
3617
+ title?: string;
3618
+ description?: string;
3619
+ okText?: string;
3620
+ cancelText?: string;
3621
+ variant?: "default" | "warning" | "danger" | "info" | "success";
3622
+ size?: "default" | "sm" | "lg" | "xl";
3623
+ placement?: "top" | "bottom" | "left" | "right" | "top-start" | "top-end" | "bottom-start" | "bottom-end" | "left-start" | "left-end" | "right-start" | "right-end";
3624
+ onConfirm?: () => void | Promise<void>;
3625
+ onCancel?: () => void;
3626
+ disabled?: boolean;
3627
+ showIcon?: boolean;
3628
+ icon?: React.ReactNode;
3629
+ okButtonProps?: React.ComponentProps<typeof Button>;
3630
+ cancelButtonProps?: React.ComponentProps<typeof Button>;
3631
+ className?: string;
3632
+ contentClassName?: string;
3633
+ open?: boolean;
3634
+ onOpenChange?: (open: boolean) => void;
3635
+ trigger?: "click" | "hover" | "focus";
3636
+ }
3637
+
3638
+ const getIcon = (variant: PopconfirmProps["variant"]) => {
3639
+ switch (variant) {
3640
+ case "warning":
3641
+ return <AlertTriangle className="h-4 w-4 text-yellow-600 dark:text-yellow-400" />;
3642
+ case "danger":
3643
+ return <XCircle className="h-4 w-4 text-red-600 dark:text-red-400" />;
3644
+ case "info":
3645
+ return <Info className="h-4 w-4 text-blue-600 dark:text-blue-400" />;
3646
+ case "success":
3647
+ return <CheckCircle className="h-4 w-4 text-green-600 dark:text-green-400" />;
3648
+ default:
3649
+ return <AlertTriangle className="h-4 w-4 text-muted-foreground" />;
3650
+ }
3651
+ };
3652
+
3653
+ export function Popconfirm({
3654
+ children,
3655
+ title = "Are you sure?",
3656
+ description,
3657
+ okText = "Yes",
3658
+ cancelText = "No",
3659
+ variant = "default",
3660
+ size = "default",
3661
+ placement = "top",
3662
+ onConfirm,
3663
+ onCancel,
3664
+ disabled = false,
3665
+ showIcon = true,
3666
+ icon,
3667
+ okButtonProps = {},
3668
+ cancelButtonProps = {},
3669
+ className,
3670
+ contentClassName,
3671
+ open,
3672
+ onOpenChange,
3673
+ trigger = "click",
3674
+ ...props
3675
+ }: PopconfirmProps) {
3676
+ const [isOpen, setIsOpen] = React.useState(false);
3677
+ const [loading, setLoading] = React.useState(false);
3678
+
3679
+ const isControlled = open !== undefined;
3680
+ const openState = isControlled ? open : isOpen;
3681
+ const setOpenState = isControlled ? onOpenChange : setIsOpen;
3682
+
3683
+ const handleConfirm = async () => {
3684
+ if (onConfirm) {
3685
+ try {
3686
+ setLoading(true);
3687
+ await onConfirm();
3688
+ setOpenState?.(false);
3689
+ } catch (error) {
3690
+ console.error("Error in onConfirm:", error);
3691
+ } finally {
3692
+ setLoading(false);
3693
+ }
3694
+ } else {
3695
+ setOpenState?.(false);
3696
+ }
3697
+ };
3698
+
3699
+ const handleCancel = () => {
3700
+ if (onCancel) {
3701
+ onCancel();
3702
+ }
3703
+ setOpenState?.(false);
3704
+ };
3705
+
3706
+ const sideMap = {
3707
+ "top": "top",
3708
+ "bottom": "bottom",
3709
+ "left": "left",
3710
+ "right": "right",
3711
+ "top-start": "top",
3712
+ "top-end": "top",
3713
+ "bottom-start": "bottom",
3714
+ "bottom-end": "bottom",
3715
+ "left-start": "left",
3716
+ "left-end": "left",
3717
+ "right-start": "right",
3718
+ "right-end": "right",
3719
+ } as const;
3720
+
3721
+ const alignMap = {
3722
+ "top": "center",
3723
+ "bottom": "center",
3724
+ "left": "center",
3725
+ "right": "center",
3726
+ "top-start": "start",
3727
+ "top-end": "end",
3728
+ "bottom-start": "start",
3729
+ "bottom-end": "end",
3730
+ "left-start": "start",
3731
+ "left-end": "end",
3732
+ "right-start": "start",
3733
+ "right-end": "end",
3734
+ } as const;
3735
+
3736
+ const triggerProps = React.useMemo(() => {
3737
+ const props: any = {};
3738
+
3739
+ if (trigger === "hover") {
3740
+ props.onMouseEnter = () => setOpenState?.(true);
3741
+ props.onMouseLeave = () => setOpenState?.(false);
3742
+ } else if (trigger === "focus") {
3743
+ props.onFocus = () => setOpenState?.(true);
3744
+ props.onBlur = () => setOpenState?.(false);
3745
+ }
3746
+
3747
+ return props;
3748
+ }, [trigger, setOpenState]);
3749
+
3750
+ const displayIcon = icon || (showIcon ? getIcon(variant) : null);
3751
+ const okVariant = variant === "danger" ? "destructive" : "default";
3752
+
3753
+ return (
3754
+ <Popover open={openState} onOpenChange={setOpenState}>
3755
+ <PopoverTrigger asChild disabled={disabled} {...triggerProps}>
3756
+ <span className={cn("cursor-pointer", disabled && "cursor-not-allowed opacity-50", className)}>
3757
+ {children}
3758
+ </span>
3759
+ </PopoverTrigger>
3760
+ <PopoverContent
3761
+ variant={variant}
3762
+ size={size}
3763
+ side={sideMap[placement]}
3764
+ align={alignMap[placement]}
3765
+ className={contentClassName}
3766
+ >
3767
+ <div className="space-y-3">
3768
+ <div className="flex items-start gap-3">
3769
+ {displayIcon && (
3770
+ <div className="flex-shrink-0 mt-0.5">
3771
+ {displayIcon}
3772
+ </div>
3773
+ )}
3774
+ <div className="space-y-1">
3775
+ <div className="font-medium text-sm leading-5">
3776
+ {title}
3777
+ </div>
3778
+ {description && (
3779
+ <div className="text-sm text-muted-foreground leading-5">
3780
+ {description}
3781
+ </div>
3782
+ )}
3783
+ </div>
3784
+ </div>
3785
+ <div className="flex items-center justify-end gap-2">
3786
+ <Button
3787
+ variant="outline"
3788
+ size="sm"
3789
+ onClick={handleCancel}
3790
+ disabled={loading}
3791
+ {...cancelButtonProps}
3792
+ >
3793
+ {cancelText}
3794
+ </Button>
3795
+ <Button
3796
+ variant={okVariant}
3797
+ size="sm"
3798
+ onClick={handleConfirm}
3799
+ loading={loading}
3800
+ {...okButtonProps}
3801
+ >
3802
+ {okText}
3803
+ </Button>
3804
+ </div>
3805
+ </div>
3806
+ </PopoverContent>
3807
+ </Popover>
3808
+ );
3809
+ }
3810
+
3811
+ Popconfirm.displayName = "Popconfirm";
3812
+ `,
3813
+ category: "Overlay",
3814
+ tags: ["utils", "auth", "user auth"],
3815
+ features: ["utils", "auth", "user auth"],
3816
+ dependencies: ["@radix-ui/react-popover", "class-variance-authority", "lucide-react"],
3817
+ usage: `
3818
+ const [messages, setMessages] = useState<string[]>([]);
3819
+
3820
+ const addMessage = (message: string) => {
3821
+ setMessages(prev => [...prev, message]);
3822
+ setTimeout(() => {
3823
+ setMessages(prev => prev.slice(1));
3824
+ }, 3000);
3825
+ };
3826
+
3827
+ const handleDelete = () => {
3828
+ addMessage("Item deleted successfully!");
3829
+ };
3830
+
3831
+ const handleEdit = () => {
3832
+ addMessage("Edit confirmed!");
3833
+ };
3834
+
3835
+ const handleDownload = () => {
3836
+ addMessage("Download started!");
3837
+ };
3838
+
3839
+ const handleLogout = () => {
3840
+ addMessage("Logged out successfully!");
3841
+ };
3842
+
3843
+ const handleAsyncAction = async () => {
3844
+ await new Promise(resolve => setTimeout(resolve, 2000));
3845
+ addMessage("Async action completed!");
3846
+ };
3847
+
3848
+ Basic Examples
3849
+ <Popconfirm
3850
+ title="Delete this item?"
3851
+ description="This action cannot be undone."
3852
+ onConfirm={handleDelete}
3853
+ >
3854
+ <Button variant="destructive" size="sm">
3855
+ <Trash2 className="h-4 w-4 mr-2" />
3856
+ Delete Item
3857
+ </Button>
3858
+ </Popconfirm>
3859
+ <Popconfirm
3860
+ title="Save changes?"
3861
+ onConfirm={handleEdit}
3862
+ >
3863
+ <Button variant="outline" size="sm">
3864
+ <Edit className="h-4 w-4 mr-2" />
3865
+ Edit
3866
+ </Button>
3867
+ </Popconfirm>
3868
+ <Popconfirm
3869
+ title="Download file?"
3870
+ description="File will be downloaded to your default location."
3871
+ okText="Download"
3872
+ cancelText="Cancel"
3873
+ onConfirm={handleDownload}
3874
+ >
3875
+ <Button size="sm">
3876
+ <Download className="h-4 w-4 mr-2" />
3877
+ Download
3878
+ </Button>
3879
+ </Popconfirm>
3880
+ Variants
3881
+ <Popconfirm
3882
+ variant="warning"
3883
+ title="Warning Action"
3884
+ description="This action requires your attention."
3885
+ onConfirm={() => addMessage("Warning action confirmed")}
3886
+ >
3887
+ <Button variant="outline" size="sm">
3888
+ Warning Style
3889
+ </Button>
3890
+ </Popconfirm>
3891
+ <Popconfirm
3892
+ variant="danger"
3893
+ title="Dangerous Action"
3894
+ description="This action is irreversible."
3895
+ okText="Delete"
3896
+ onConfirm={() => addMessage("Dangerous action confirmed")}
3897
+ >
3898
+ <Button variant="destructive" size="sm">
3899
+ Danger Style
3900
+ </Button>
3901
+ </Popconfirm>
3902
+ <Popconfirm
3903
+ variant="info"
3904
+ title="Information"
3905
+ description="This will update your settings."
3906
+ okText="Update"
3907
+ onConfirm={() => addMessage("Info action confirmed")}
3908
+ >
3909
+ <Button variant="outline" size="sm">
3910
+ Info Style
3911
+ </Button>
3912
+ </Popconfirm>
3913
+ <Popconfirm
3914
+ variant="success"
3915
+ title="Success Action"
3916
+ description="This will complete the process."
3917
+ okText="Complete"
3918
+ onConfirm={() => addMessage("Success action confirmed")}
3919
+ >
3920
+ <Button size="sm">
3921
+ Success Style
3922
+ </Button>
3923
+ </Popconfirm>
3924
+ Placements
3925
+ <Popconfirm
3926
+ title="Top placement"
3927
+ placement="top"
3928
+ onConfirm={() => addMessage("Top confirmed")}
3929
+ >
3930
+ <Button variant="outline" size="sm">Top</Button>
3931
+ </Popconfirm>
3932
+
3933
+ <Popconfirm
3934
+ title="Bottom placement"
3935
+ placement="bottom"
3936
+ onConfirm={() => addMessage("Bottom confirmed")}
3937
+ >
3938
+ <Button variant="outline" size="sm">Bottom</Button>
3939
+ </Popconfirm>
3940
+
3941
+ <Popconfirm
3942
+ title="Left placement"
3943
+ placement="left"
3944
+ onConfirm={() => addMessage("Left confirmed")}
3945
+ >
3946
+ <Button variant="outline" size="sm">Left</Button>
3947
+ </Popconfirm>
3948
+
3949
+ <Popconfirm
3950
+ title="Right placement"
3951
+ placement="right"
3952
+ onConfirm={() => addMessage("Right confirmed")}
3953
+ >
3954
+ <Button variant="outline" size="sm">Right</Button>
3955
+ </Popconfirm>
3956
+ <Popconfirm
3957
+ title="Top Start"
3958
+ placement="top-start"
3959
+ onConfirm={() => addMessage("Top start confirmed")}
3960
+ >
3961
+ <Button variant="outline" size="sm">Top Start</Button>
3962
+ </Popconfirm>
3963
+
3964
+ <Popconfirm
3965
+ title="Top End"
3966
+ placement="top-end"
3967
+ onConfirm={() => addMessage("Top end confirmed")}
3968
+ >
3969
+ <Button variant="outline" size="sm">Top End</Button>
3970
+ </Popconfirm>
3971
+ Sizes
3972
+ <Popconfirm
3973
+ size="sm"
3974
+ title="Small size"
3975
+ description="This is a smaller popconfirm."
3976
+ onConfirm={() => addMessage("Small confirmed")}
3977
+ >
3978
+ <Button variant="outline" size="sm">Small</Button>
3979
+ </Popconfirm>
3980
+ <Popconfirm
3981
+ size="default"
3982
+ title="Default size"
3983
+ description="This is the default popconfirm size."
3984
+ onConfirm={() => addMessage("Default confirmed")}
3985
+ >
3986
+ <Button variant="outline" size="sm">Default</Button>
3987
+ </Popconfirm>
3988
+ <Popconfirm
3989
+ size="lg"
3990
+ title="Large size"
3991
+ description="This is a larger popconfirm with more space for content."
3992
+ onConfirm={() => addMessage("Large confirmed")}
3993
+ >
3994
+ <Button variant="outline" size="sm">Large</Button>
3995
+ </Popconfirm>
3996
+ <Popconfirm
3997
+ size="xl"
3998
+ title="Extra large size"
3999
+ description="This is an extra large popconfirm with even more space for longer descriptions and content."
4000
+ onConfirm={() => addMessage("XL confirmed")}
4001
+ >
4002
+ <Button variant="outline" size="sm">Extra Large</Button>
4003
+ </Popconfirm>
4004
+ Custom Features
4005
+ <Popconfirm
4006
+ title="Custom Icon"
4007
+ description="This uses a custom heart icon."
4008
+ icon={<Heart className="h-4 w-4 text-red-500" />}
4009
+ onConfirm={() => addMessage("Custom icon confirmed")}
4010
+ >
4011
+ <Button variant="outline" size="sm">
4012
+ <Heart className="h-4 w-4 mr-2" />
4013
+ Custom Icon
4014
+ </Button>
4015
+ </Popconfirm>
4016
+ <Popconfirm
4017
+ title="No Icon"
4018
+ description="This popconfirm has no icon."
4019
+ showIcon={false}
4020
+ onConfirm={() => addMessage("No icon confirmed")}
4021
+ >
4022
+ <Button variant="outline" size="sm">No Icon</Button>
4023
+ </Popconfirm>
4024
+ <Popconfirm
4025
+ title="Async Action"
4026
+ description="This will take a few seconds to complete."
4027
+ onConfirm={handleAsyncAction}
4028
+ okText="Process"
4029
+ >
4030
+ <Button size="sm">
4031
+ <Settings className="h-4 w-4 mr-2" />
4032
+ Async Action
4033
+ </Button>
4034
+ </Popconfirm>
4035
+ <Popconfirm
4036
+ title="Custom Button Styles"
4037
+ description="Custom styled confirm and cancel buttons."
4038
+ okText="Proceed"
4039
+ cancelText="Abort"
4040
+ okButtonProps={{
4041
+ variant: "default",
4042
+ className: "bg-blue-600 hover:bg-blue-700"
4043
+ }}
4044
+ cancelButtonProps={{
4045
+ variant: "outline",
4046
+ className: "border-red-200 text-red-600 hover:bg-red-50"
4047
+ }}
4048
+ onConfirm={() => addMessage("Custom buttons confirmed")}
4049
+ >
4050
+ <Button variant="outline" size="sm">Custom Buttons</Button>
4051
+ </Popconfirm>
4052
+ Interactive Examples
4053
+ <Popconfirm
4054
+ variant="danger"
4055
+ title="Sign out of your account?"
4056
+ description="You will need to sign in again to access your account."
4057
+ okText="Sign Out"
4058
+ cancelText="Stay"
4059
+ onConfirm={handleLogout}
4060
+ >
4061
+ <Button variant="outline" size="sm" className="w-full">
4062
+ <LogOut className="h-4 w-4 mr-2" />
4063
+ Sign Out
4064
+ </Button>
4065
+ </Popconfirm>
4066
+ <Popconfirm
4067
+ title="Delete selected items?"
4068
+ description="3 items will be permanently deleted."
4069
+ variant="warning"
4070
+ okText="Delete All"
4071
+ onConfirm={() => addMessage("3 items deleted")}
4072
+ >
4073
+ <Button variant="destructive" size="sm" className="w-full">
4074
+ <Trash2 className="h-4 w-4 mr-2" />
4075
+ Delete Selected (3)
4076
+ </Button>
4077
+ </Popconfirm>
4078
+ <Popconfirm
4079
+ title="Archive this conversation?"
4080
+ description="The conversation will be moved to your archive."
4081
+ variant="info"
4082
+ okText="Archive"
4083
+ onConfirm={() => addMessage("Conversation archived")}
4084
+ >
4085
+ <Button variant="outline" size="sm" className="w-full">
4086
+ Archive Chat
4087
+ </Button>
4088
+ </Popconfirm>
4089
+ Usage Examples
4090
+ <Popconfirm
4091
+ title="Are you sure?"
4092
+ description="This action cannot be undone."
4093
+ onConfirm={handleConfirm}
4094
+ onCancel={handleCancel}
4095
+ >
4096
+ <Button>Delete</Button>
4097
+ </Popconfirm>
4098
+ <Popconfirm
4099
+ variant="danger"
4100
+ title="Delete item?"
4101
+ description="This will permanently delete the item."
4102
+ okText="Delete"
4103
+ cancelText="Keep"
4104
+ placement="top-start"
4105
+ size="lg"
4106
+ onConfirm={handleDelete}
4107
+ >
4108
+ <Button variant="destructive">Delete</Button>
4109
+ </Popconfirm> `,
4110
+ usagePath: null,
4111
+ props: [
4112
+ { "name": "children", "type": "React.ReactNode", "default": "undefined", "required": true },
4113
+ { "name": "title", "type": "string", "default": "\"Are you sure?\"" },
4114
+ { "name": "description", "type": "string", "default": "undefined" },
4115
+ { "name": "okText", "type": "string", "default": "\"Yes\"" },
4116
+ { "name": "cancelText", "type": "string", "default": "\"No\"" },
4117
+ { "name": "variant", "type": "\"default\" | \"warning\" | \"danger\" | \"info\" | \"success\"", "default": "\"default\"" },
4118
+ { "name": "size", "type": "\"default\" | \"sm\" | \"lg\" | \"xl\"", "default": "\"default\"" },
4119
+ { "name": "placement", "type": "\"top\" | \"bottom\" | \"left\" | \"right\" | \"top-start\" | \"top-end\" | \"bottom-start\" | \"bottom-end\" | \"left-start\" | \"left-end\" | \"right-start\" | \"right-end\"", "default": "\"top\"" },
4120
+ { "name": "onConfirm", "type": "() => void | Promise<void>", "default": "undefined" },
4121
+ { "name": "onCancel", "type": "() => void", "default": "undefined" },
4122
+ { "name": "disabled", "type": "boolean", "default": "false" },
4123
+ { "name": "showIcon", "type": "boolean", "default": "true" },
4124
+ { "name": "icon", "type": "React.ReactNode", "default": "undefined" },
4125
+ { "name": "okButtonProps", "type": "React.ComponentProps<typeof Button>", "default": "{}" },
4126
+ { "name": "cancelButtonProps", "type": "React.ComponentProps<typeof Button>", "default": "{}" },
4127
+ { "name": "className", "type": "string", "default": "undefined" },
4128
+ { "name": "contentClassName", "type": "string", "default": "undefined" },
4129
+ { "name": "open", "type": "boolean", "default": "undefined" },
4130
+ { "name": "onOpenChange", "type": "(open: boolean) => void", "default": "undefined" },
4131
+ { "name": "trigger", "type": "\"click\" | \"hover\" | \"focus\"", "default": "\"click\"" }
4132
+ ],
4133
+ desc: null,
4134
+ customize: null
4135
+ },
4136
+ ];