@a2v2ai/uikit 0.0.36 → 0.0.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/Alert/Alert.stories.tsx +121 -0
  2. package/Alert/Alert.tsx +71 -0
  3. package/AlertDialog/AlertDialog.stories.tsx +665 -0
  4. package/AlertDialog/AlertDialog.tsx +241 -0
  5. package/Avatar/Avatar.stories.tsx +128 -0
  6. package/Avatar/Avatar.tsx +71 -0
  7. package/Badge/Badge.stories.tsx +76 -0
  8. package/Badge/Badge.tsx +39 -0
  9. package/Breadcrumb/Breadcrumb.stories.tsx +231 -0
  10. package/Breadcrumb/Breadcrumb.tsx +114 -0
  11. package/Button/Button.stories.tsx +684 -0
  12. package/Button/Button.tsx +107 -0
  13. package/Calendar/Calendar.stories.tsx +291 -0
  14. package/Calendar/Calendar.tsx +246 -0
  15. package/Card/Card.stories.tsx +136 -0
  16. package/Card/Card.tsx +96 -0
  17. package/Carousel/Carousel.stories.tsx +256 -0
  18. package/Carousel/Carousel.tsx +301 -0
  19. package/ChatBubble/ChatBubble.stories.tsx +339 -0
  20. package/ChatBubble/ChatBubble.tsx +179 -0
  21. package/Checkbox/Checkbox.stories.tsx +137 -0
  22. package/Checkbox/Checkbox.tsx +53 -0
  23. package/DataTable/DataTable.stories.tsx +400 -0
  24. package/DataTable/DataTable.tsx +207 -0
  25. package/Drawer/Drawer.stories.tsx +721 -0
  26. package/Drawer/Drawer.tsx +201 -0
  27. package/DropdownMenu/DropdownMenu.stories.tsx +251 -0
  28. package/DropdownMenu/DropdownMenu.tsx +199 -0
  29. package/ErrorMessage/ErrorMessage.stories.tsx +159 -0
  30. package/ErrorMessage/ErrorMessage.tsx +55 -0
  31. package/Flex/Flex.stories.tsx +390 -0
  32. package/Flex/Flex.tsx +102 -0
  33. package/IconButton/IconButton.stories.tsx +566 -0
  34. package/IconButton/IconButton.tsx +95 -0
  35. package/Input/Input.stories.tsx +566 -0
  36. package/Input/Input.tsx +168 -0
  37. package/InputOTP/InputOTP.stories.tsx +246 -0
  38. package/InputOTP/InputOTP.tsx +127 -0
  39. package/Label/Label.stories.tsx +110 -0
  40. package/Label/Label.tsx +44 -0
  41. package/Loader/Loader.stories.tsx +170 -0
  42. package/Loader/Loader.tsx +62 -0
  43. package/Menubar/Menubar.stories.tsx +382 -0
  44. package/Menubar/Menubar.tsx +274 -0
  45. package/Menubar/index.ts +18 -0
  46. package/Pagination/Pagination.stories.tsx +196 -0
  47. package/Pagination/Pagination.tsx +122 -0
  48. package/Popover/Popover.stories.tsx +133 -0
  49. package/Popover/Popover.tsx +31 -0
  50. package/Progress/Progress.stories.tsx +146 -0
  51. package/Progress/Progress.tsx +67 -0
  52. package/RadioGroup/RadioGroup.stories.tsx +159 -0
  53. package/RadioGroup/RadioGroup.tsx +68 -0
  54. package/ScrollArea/ScrollArea.stories.tsx +136 -0
  55. package/ScrollArea/ScrollArea.tsx +46 -0
  56. package/Select/Select.stories.tsx +378 -0
  57. package/Select/Select.tsx +230 -0
  58. package/Separator/Separator.stories.tsx +110 -0
  59. package/Separator/Separator.tsx +29 -0
  60. package/Sidebar/Sidebar.stories.tsx +340 -0
  61. package/Sidebar/Sidebar.tsx +414 -0
  62. package/Sidebar/index.ts +28 -0
  63. package/Skeleton/Skeleton.stories.tsx +117 -0
  64. package/Skeleton/Skeleton.tsx +16 -0
  65. package/Slider/Slider.stories.tsx +216 -0
  66. package/Slider/Slider.tsx +29 -0
  67. package/Spinner/Spinner.stories.tsx +210 -0
  68. package/Spinner/Spinner.tsx +78 -0
  69. package/Switch/Switch.stories.tsx +146 -0
  70. package/Switch/Switch.tsx +59 -0
  71. package/Table/Table.stories.tsx +510 -0
  72. package/Table/Table.tsx +114 -0
  73. package/Tabs/Tabs.stories.tsx +197 -0
  74. package/Tabs/Tabs.tsx +74 -0
  75. package/Textarea/Textarea.stories.tsx +187 -0
  76. package/Textarea/Textarea.tsx +73 -0
  77. package/Toast/Toast.stories.tsx +285 -0
  78. package/Toast/Toast.tsx +59 -0
  79. package/Tooltip/Tooltip.stories.tsx +463 -0
  80. package/Tooltip/Tooltip.tsx +96 -0
  81. package/Typography/Typography.stories.tsx +425 -0
  82. package/Typography/Typography.tsx +106 -0
  83. package/helpers.ts +5 -0
  84. package/{icons.js → icons.ts} +1 -1
  85. package/index.ts +217 -0
  86. package/lib/typography-types.ts +223 -0
  87. package/lib/utils.ts +15 -0
  88. package/package.json +36 -33
  89. package/tsconfig.json +22 -0
  90. package/Alert/Alert.d.ts +0 -13
  91. package/Alert/Alert.js +0 -25
  92. package/AlertDialog/AlertDialog.d.ts +0 -43
  93. package/AlertDialog/AlertDialog.js +0 -71
  94. package/Avatar/Avatar.d.ts +0 -14
  95. package/Avatar/Avatar.js +0 -25
  96. package/Badge/Badge.d.ts +0 -11
  97. package/Badge/Badge.js +0 -23
  98. package/Breadcrumb/Breadcrumb.d.ts +0 -19
  99. package/Breadcrumb/Breadcrumb.js +0 -23
  100. package/Button/Button.d.ts +0 -23
  101. package/Button/Button.js +0 -52
  102. package/Calendar/Calendar.d.ts +0 -20
  103. package/Calendar/Calendar.js +0 -78
  104. package/Card/Card.d.ts +0 -16
  105. package/Card/Card.js +0 -28
  106. package/Carousel/Carousel.d.ts +0 -37
  107. package/Carousel/Carousel.js +0 -132
  108. package/ChatBubble/ChatBubble.d.ts +0 -33
  109. package/ChatBubble/ChatBubble.js +0 -107
  110. package/Checkbox/Checkbox.d.ts +0 -12
  111. package/Checkbox/Checkbox.js +0 -20
  112. package/DataTable/DataTable.d.ts +0 -35
  113. package/DataTable/DataTable.js +0 -51
  114. package/Dialog/Dialog.d.ts +0 -35
  115. package/Dialog/Dialog.js +0 -130
  116. package/Drawer/Drawer.d.ts +0 -33
  117. package/Drawer/Drawer.js +0 -55
  118. package/DropdownMenu/DropdownMenu.d.ts +0 -27
  119. package/DropdownMenu/DropdownMenu.js +0 -35
  120. package/ErrorMessage/ErrorMessage.d.ts +0 -27
  121. package/ErrorMessage/ErrorMessage.js +0 -14
  122. package/Flex/Flex.d.ts +0 -31
  123. package/Flex/Flex.js +0 -64
  124. package/IconButton/IconButton.d.ts +0 -23
  125. package/IconButton/IconButton.js +0 -48
  126. package/Input/Input.d.ts +0 -27
  127. package/Input/Input.js +0 -42
  128. package/InputOTP/InputOTP.d.ts +0 -20
  129. package/InputOTP/InputOTP.js +0 -44
  130. package/Label/Label.d.ts +0 -13
  131. package/Label/Label.js +0 -19
  132. package/Loader/Loader.d.ts +0 -21
  133. package/Loader/Loader.js +0 -30
  134. package/Menubar/Menubar.d.ts +0 -26
  135. package/Menubar/Menubar.js +0 -54
  136. package/Menubar/index.d.ts +0 -1
  137. package/Menubar/index.js +0 -1
  138. package/Pagination/Pagination.d.ts +0 -35
  139. package/Pagination/Pagination.js +0 -37
  140. package/Popover/Popover.d.ts +0 -7
  141. package/Popover/Popover.js +0 -10
  142. package/Progress/Progress.d.ts +0 -17
  143. package/Progress/Progress.js +0 -33
  144. package/RadioGroup/RadioGroup.d.ts +0 -13
  145. package/RadioGroup/RadioGroup.js +0 -26
  146. package/ScrollArea/ScrollArea.d.ts +0 -5
  147. package/ScrollArea/ScrollArea.js +0 -11
  148. package/Select/Select.d.ts +0 -29
  149. package/Select/Select.js +0 -50
  150. package/Separator/Separator.d.ts +0 -4
  151. package/Separator/Separator.js +0 -7
  152. package/Sidebar/Sidebar.d.ts +0 -48
  153. package/Sidebar/Sidebar.js +0 -116
  154. package/Sidebar/index.d.ts +0 -2
  155. package/Sidebar/index.js +0 -1
  156. package/Skeleton/Skeleton.d.ts +0 -4
  157. package/Skeleton/Skeleton.js +0 -7
  158. package/Slider/Slider.d.ts +0 -6
  159. package/Slider/Slider.js +0 -7
  160. package/Spinner/Spinner.d.ts +0 -19
  161. package/Spinner/Spinner.js +0 -31
  162. package/Switch/Switch.d.ts +0 -12
  163. package/Switch/Switch.js +0 -30
  164. package/Table/Table.d.ts +0 -10
  165. package/Table/Table.js +0 -20
  166. package/Tabs/Tabs.d.ts +0 -15
  167. package/Tabs/Tabs.js +0 -24
  168. package/Textarea/Textarea.d.ts +0 -19
  169. package/Textarea/Textarea.js +0 -31
  170. package/Toast/Toast.d.ts +0 -12
  171. package/Toast/Toast.js +0 -25
  172. package/Tooltip/Tooltip.d.ts +0 -17
  173. package/Tooltip/Tooltip.js +0 -29
  174. package/Typography/Typography.d.ts +0 -20
  175. package/Typography/Typography.js +0 -43
  176. package/helpers.d.ts +0 -4
  177. package/helpers.js +0 -5
  178. package/icons.d.ts +0 -1
  179. package/index.d.ts +0 -42
  180. package/index.js +0 -45
  181. package/lib/typography-types.d.ts +0 -4
  182. package/lib/typography-types.js +0 -90
  183. package/lib/utils.d.ts +0 -3
  184. package/lib/utils.js +0 -14
  185. package/tmpclaude-2407-cwd +0 -1
@@ -0,0 +1,414 @@
1
+ import * as React from "react"
2
+ import { cva, type VariantProps } from "class-variance-authority"
3
+ import { ChevronDown, ChevronRight } from "lucide-react"
4
+
5
+ import { cn } from "../lib/utils"
6
+
7
+ /* -----------------------------------------------------------------------------
8
+ * Context for Sidebar collapsed state
9
+ * -------------------------------------------------------------------------- */
10
+
11
+ interface SidebarContextValue {
12
+ collapsed: boolean
13
+ setCollapsed: (collapsed: boolean) => void
14
+ }
15
+
16
+ const SidebarContext = React.createContext<SidebarContextValue | undefined>(undefined)
17
+
18
+ function useSidebar() {
19
+ const context = React.useContext(SidebarContext)
20
+ if (!context) {
21
+ throw new Error("useSidebar must be used within a Sidebar")
22
+ }
23
+ return context
24
+ }
25
+
26
+ /* -----------------------------------------------------------------------------
27
+ * Sidebar (Main Container)
28
+ * -------------------------------------------------------------------------- */
29
+
30
+ export interface SidebarProps extends React.HTMLAttributes<HTMLDivElement> {
31
+ collapsed?: boolean
32
+ onCollapsedChange?: (collapsed: boolean) => void
33
+ defaultCollapsed?: boolean
34
+ }
35
+
36
+ const Sidebar = React.forwardRef<HTMLDivElement, SidebarProps>(
37
+ ({ className, collapsed: controlledCollapsed, onCollapsedChange, defaultCollapsed = false, children, ...props }, ref) => {
38
+ const [uncontrolledCollapsed, setUncontrolledCollapsed] = React.useState(defaultCollapsed)
39
+
40
+ const isControlled = controlledCollapsed !== undefined
41
+ const collapsed = isControlled ? controlledCollapsed : uncontrolledCollapsed
42
+
43
+ const setCollapsed = React.useCallback((value: boolean) => {
44
+ if (!isControlled) {
45
+ setUncontrolledCollapsed(value)
46
+ }
47
+ onCollapsedChange?.(value)
48
+ }, [isControlled, onCollapsedChange])
49
+
50
+ return (
51
+ <SidebarContext.Provider value={{ collapsed, setCollapsed }}>
52
+ <div
53
+ ref={ref}
54
+ data-slot="sidebar"
55
+ data-collapsed={collapsed}
56
+ className={cn(
57
+ "flex h-full flex-col bg-white border-r border-grey-200 transition-all duration-300",
58
+ collapsed ? "w-[52px]" : "w-[240px]",
59
+ className
60
+ )}
61
+ {...props}
62
+ >
63
+ {children}
64
+ </div>
65
+ </SidebarContext.Provider>
66
+ )
67
+ }
68
+ )
69
+ Sidebar.displayName = "Sidebar"
70
+
71
+ /* -----------------------------------------------------------------------------
72
+ * SidebarHeader
73
+ * -------------------------------------------------------------------------- */
74
+
75
+ export type SidebarHeaderProps = React.HTMLAttributes<HTMLDivElement>
76
+
77
+ const SidebarHeader = React.forwardRef<HTMLDivElement, SidebarHeaderProps>(
78
+ ({ className, children, ...props }, ref) => {
79
+ const { collapsed } = useSidebar()
80
+
81
+ return (
82
+ <div
83
+ ref={ref}
84
+ data-slot="sidebar-header"
85
+ className={cn(
86
+ "flex shrink-0 items-center",
87
+ collapsed ? "justify-center p-2" : "p-4",
88
+ className
89
+ )}
90
+ {...props}
91
+ >
92
+ {children}
93
+ </div>
94
+ )
95
+ }
96
+ )
97
+ SidebarHeader.displayName = "SidebarHeader"
98
+
99
+ /* -----------------------------------------------------------------------------
100
+ * SidebarContent
101
+ * -------------------------------------------------------------------------- */
102
+
103
+ export type SidebarContentProps = React.HTMLAttributes<HTMLDivElement>
104
+
105
+ const SidebarContent = React.forwardRef<HTMLDivElement, SidebarContentProps>(
106
+ ({ className, children, ...props }, ref) => {
107
+ const { collapsed } = useSidebar()
108
+
109
+ return (
110
+ <div
111
+ ref={ref}
112
+ data-slot="sidebar-content"
113
+ className={cn(
114
+ "flex-1 overflow-y-auto",
115
+ collapsed ? "px-2 py-4" : "p-4",
116
+ className
117
+ )}
118
+ {...props}
119
+ >
120
+ {children}
121
+ </div>
122
+ )
123
+ }
124
+ )
125
+ SidebarContent.displayName = "SidebarContent"
126
+
127
+ /* -----------------------------------------------------------------------------
128
+ * SidebarFooter
129
+ * -------------------------------------------------------------------------- */
130
+
131
+ export type SidebarFooterProps = React.HTMLAttributes<HTMLDivElement>
132
+
133
+ const SidebarFooter = React.forwardRef<HTMLDivElement, SidebarFooterProps>(
134
+ ({ className, children, ...props }, ref) => {
135
+ const { collapsed } = useSidebar()
136
+
137
+ return (
138
+ <div
139
+ ref={ref}
140
+ data-slot="sidebar-footer"
141
+ className={cn(
142
+ "flex shrink-0 items-center border-t border-grey-200",
143
+ collapsed ? "justify-center p-2" : "p-4",
144
+ className
145
+ )}
146
+ {...props}
147
+ >
148
+ {children}
149
+ </div>
150
+ )
151
+ }
152
+ )
153
+ SidebarFooter.displayName = "SidebarFooter"
154
+
155
+ /* -----------------------------------------------------------------------------
156
+ * SidebarGroup
157
+ * -------------------------------------------------------------------------- */
158
+
159
+ export type SidebarGroupProps = React.HTMLAttributes<HTMLDivElement>
160
+
161
+ const SidebarGroup = React.forwardRef<HTMLDivElement, SidebarGroupProps>(
162
+ ({ className, children, ...props }, ref) => {
163
+ const { collapsed } = useSidebar()
164
+
165
+ return (
166
+ <div
167
+ ref={ref}
168
+ data-slot="sidebar-group"
169
+ className={cn(
170
+ "flex flex-col",
171
+ collapsed ? "gap-1" : "gap-0.5",
172
+ className
173
+ )}
174
+ {...props}
175
+ >
176
+ {children}
177
+ </div>
178
+ )
179
+ }
180
+ )
181
+ SidebarGroup.displayName = "SidebarGroup"
182
+
183
+ /* -----------------------------------------------------------------------------
184
+ * SidebarGroupLabel
185
+ * -------------------------------------------------------------------------- */
186
+
187
+ export type SidebarGroupLabelProps = React.HTMLAttributes<HTMLDivElement>
188
+
189
+ const SidebarGroupLabel = React.forwardRef<HTMLDivElement, SidebarGroupLabelProps>(
190
+ ({ className, children, ...props }, ref) => {
191
+ const { collapsed } = useSidebar()
192
+
193
+ if (collapsed) return null
194
+
195
+ return (
196
+ <div
197
+ ref={ref}
198
+ data-slot="sidebar-group-label"
199
+ className={cn(
200
+ "px-3 py-2 text-xs font-normal text-grey-500",
201
+ className
202
+ )}
203
+ {...props}
204
+ >
205
+ {children}
206
+ </div>
207
+ )
208
+ }
209
+ )
210
+ SidebarGroupLabel.displayName = "SidebarGroupLabel"
211
+
212
+ /* -----------------------------------------------------------------------------
213
+ * SidebarMenuItem
214
+ * -------------------------------------------------------------------------- */
215
+
216
+ const sidebarMenuItemVariants = cva(
217
+ "flex items-center gap-2 px-3 py-2 rounded-md text-sm font-normal cursor-pointer transition-colors outline-none",
218
+ {
219
+ variants: {
220
+ active: {
221
+ true: "bg-grey-100 text-grey-900",
222
+ false: "text-grey-600 hover:bg-grey-50",
223
+ },
224
+ },
225
+ defaultVariants: {
226
+ active: false,
227
+ },
228
+ }
229
+ )
230
+
231
+ export interface SidebarMenuItemProps
232
+ extends React.HTMLAttributes<HTMLDivElement>,
233
+ VariantProps<typeof sidebarMenuItemVariants> {
234
+ icon?: React.ReactNode
235
+ label: string
236
+ labelClassName?: string
237
+ badge?: React.ReactNode
238
+ hasChildren?: boolean
239
+ expanded?: boolean
240
+ onExpandedChange?: (expanded: boolean) => void
241
+ }
242
+
243
+ const SidebarMenuItem = React.forwardRef<HTMLDivElement, SidebarMenuItemProps>(
244
+ ({ className, icon, label, labelClassName, badge, active, hasChildren, expanded, onExpandedChange, children, onClick, ...props }, ref) => {
245
+ const { collapsed } = useSidebar()
246
+ const [internalExpanded, setInternalExpanded] = React.useState(expanded ?? false)
247
+
248
+ const isExpanded = expanded !== undefined ? expanded : internalExpanded
249
+
250
+ const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
251
+ if (hasChildren) {
252
+ const newExpanded = !isExpanded
253
+ setInternalExpanded(newExpanded)
254
+ onExpandedChange?.(newExpanded)
255
+ }
256
+ onClick?.(e)
257
+ }
258
+
259
+ if (collapsed) {
260
+ return (
261
+ <div
262
+ ref={ref}
263
+ data-slot="sidebar-menu-item"
264
+ className={cn(
265
+ "flex items-center justify-center size-9 rounded-lg cursor-pointer transition-colors mx-auto",
266
+ active ? "bg-grey-100 text-grey-900" : "text-grey-600 hover:bg-grey-50",
267
+ className
268
+ )}
269
+ onClick={onClick}
270
+ {...props}
271
+ >
272
+ {icon && <span className="size-4">{icon}</span>}
273
+ </div>
274
+ )
275
+ }
276
+
277
+ return (
278
+ <div data-slot="sidebar-menu-item-wrapper">
279
+ <div
280
+ ref={ref}
281
+ data-slot="sidebar-menu-item"
282
+ className={cn(sidebarMenuItemVariants({ active }), className)}
283
+ onClick={handleClick}
284
+ {...props}
285
+ >
286
+ {icon && <span className="size-4 shrink-0">{icon}</span>}
287
+ <span className={cn("flex-1 truncate", labelClassName)}>{label}</span>
288
+ {badge && <span className="shrink-0">{badge}</span>}
289
+ {hasChildren && (
290
+ <span className="size-4 shrink-0 text-grey-400">
291
+ {isExpanded ? <ChevronDown className="size-4" /> : <ChevronRight className="size-4" />}
292
+ </span>
293
+ )}
294
+ </div>
295
+ {hasChildren && isExpanded && children && (
296
+ <div className="ml-6 mt-1 flex flex-col">
297
+ {children}
298
+ </div>
299
+ )}
300
+ </div>
301
+ )
302
+ }
303
+ )
304
+ SidebarMenuItem.displayName = "SidebarMenuItem"
305
+
306
+ /* -----------------------------------------------------------------------------
307
+ * SidebarSubMenuItem
308
+ * -------------------------------------------------------------------------- */
309
+
310
+ const sidebarSubMenuItemVariants = cva(
311
+ "flex items-center px-3 py-2 rounded-md text-sm font-normal cursor-pointer transition-colors outline-none",
312
+ {
313
+ variants: {
314
+ active: {
315
+ true: "bg-grey-100 text-grey-900",
316
+ false: "text-grey-500 hover:bg-grey-50 hover:text-grey-700",
317
+ },
318
+ },
319
+ defaultVariants: {
320
+ active: false,
321
+ },
322
+ }
323
+ )
324
+
325
+ export interface SidebarSubMenuItemProps
326
+ extends React.HTMLAttributes<HTMLDivElement>,
327
+ VariantProps<typeof sidebarSubMenuItemVariants> {
328
+ label: string
329
+ }
330
+
331
+ const SidebarSubMenuItem = React.forwardRef<HTMLDivElement, SidebarSubMenuItemProps>(
332
+ ({ className, label, active, ...props }, ref) => {
333
+ return (
334
+ <div
335
+ ref={ref}
336
+ data-slot="sidebar-sub-menu-item"
337
+ className={cn(sidebarSubMenuItemVariants({ active }), className)}
338
+ {...props}
339
+ >
340
+ <span className="truncate">{label}</span>
341
+ </div>
342
+ )
343
+ }
344
+ )
345
+ SidebarSubMenuItem.displayName = "SidebarSubMenuItem"
346
+
347
+ /* -----------------------------------------------------------------------------
348
+ * SidebarSeparator
349
+ * -------------------------------------------------------------------------- */
350
+
351
+ export type SidebarSeparatorProps = React.HTMLAttributes<HTMLDivElement>
352
+
353
+ const SidebarSeparator = React.forwardRef<HTMLDivElement, SidebarSeparatorProps>(
354
+ ({ className, ...props }, ref) => {
355
+ return (
356
+ <div
357
+ ref={ref}
358
+ data-slot="sidebar-separator"
359
+ className={cn("my-2 h-px bg-grey-200", className)}
360
+ {...props}
361
+ />
362
+ )
363
+ }
364
+ )
365
+ SidebarSeparator.displayName = "SidebarSeparator"
366
+
367
+ /* -----------------------------------------------------------------------------
368
+ * SidebarToggle
369
+ * -------------------------------------------------------------------------- */
370
+
371
+ export type SidebarToggleProps = React.ButtonHTMLAttributes<HTMLButtonElement>
372
+
373
+ const SidebarToggle = React.forwardRef<HTMLButtonElement, SidebarToggleProps>(
374
+ ({ className, children, ...props }, ref) => {
375
+ const { collapsed, setCollapsed } = useSidebar()
376
+
377
+ return (
378
+ <button
379
+ ref={ref}
380
+ data-slot="sidebar-toggle"
381
+ type="button"
382
+ className={cn(
383
+ "flex items-center justify-center p-2 rounded-md text-grey-500 hover:bg-grey-100 hover:text-grey-700 transition-colors",
384
+ className
385
+ )}
386
+ onClick={() => setCollapsed(!collapsed)}
387
+ {...props}
388
+ >
389
+ {children}
390
+ </button>
391
+ )
392
+ }
393
+ )
394
+ SidebarToggle.displayName = "SidebarToggle"
395
+
396
+ /* -----------------------------------------------------------------------------
397
+ * Exports
398
+ * -------------------------------------------------------------------------- */
399
+
400
+ export {
401
+ Sidebar,
402
+ SidebarHeader,
403
+ SidebarContent,
404
+ SidebarFooter,
405
+ SidebarGroup,
406
+ SidebarGroupLabel,
407
+ SidebarMenuItem,
408
+ SidebarSubMenuItem,
409
+ SidebarSeparator,
410
+ SidebarToggle,
411
+ useSidebar,
412
+ sidebarMenuItemVariants,
413
+ sidebarSubMenuItemVariants,
414
+ }
@@ -0,0 +1,28 @@
1
+ export {
2
+ Sidebar,
3
+ SidebarHeader,
4
+ SidebarContent,
5
+ SidebarFooter,
6
+ SidebarGroup,
7
+ SidebarGroupLabel,
8
+ SidebarMenuItem,
9
+ SidebarSubMenuItem,
10
+ SidebarSeparator,
11
+ SidebarToggle,
12
+ useSidebar,
13
+ sidebarMenuItemVariants,
14
+ sidebarSubMenuItemVariants,
15
+ } from "./Sidebar"
16
+
17
+ export type {
18
+ SidebarProps,
19
+ SidebarHeaderProps,
20
+ SidebarContentProps,
21
+ SidebarFooterProps,
22
+ SidebarGroupProps,
23
+ SidebarGroupLabelProps,
24
+ SidebarMenuItemProps,
25
+ SidebarSubMenuItemProps,
26
+ SidebarSeparatorProps,
27
+ SidebarToggleProps,
28
+ } from "./Sidebar"
@@ -0,0 +1,117 @@
1
+ import type { Meta, StoryObj } from "@storybook/react"
2
+
3
+ import { Flex } from "../Flex/Flex"
4
+ import { Typography } from "../Typography/Typography"
5
+ import { Skeleton } from "./Skeleton"
6
+
7
+ const meta: Meta<typeof Skeleton> = {
8
+ title: "Components/Skeleton",
9
+ component: Skeleton,
10
+ parameters: {
11
+ layout: "centered",
12
+ },
13
+ tags: ["autodocs"],
14
+ }
15
+
16
+ export default meta
17
+ type Story = StoryObj<typeof meta>
18
+
19
+ export const Default: Story = {
20
+ render: () => <Skeleton className="w-[100px] h-[20px]" />,
21
+ }
22
+
23
+ export const Card: Story = {
24
+ render: () => (
25
+ <div className="flex items-center space-x-4">
26
+ <Skeleton className="h-12 w-12 rounded-full" />
27
+ <div className="space-y-2">
28
+ <Skeleton className="h-4 w-[250px]" />
29
+ <Skeleton className="h-4 w-[200px]" />
30
+ </div>
31
+ </div>
32
+ ),
33
+ }
34
+
35
+ export const Text: Story = {
36
+ render: () => (
37
+ <div className="space-y-2">
38
+ <Skeleton className="h-4 w-[300px]" />
39
+ <Skeleton className="h-4 w-[250px]" />
40
+ <Skeleton className="h-4 w-[280px]" />
41
+ </div>
42
+ ),
43
+ }
44
+
45
+ export const Avatar: Story = {
46
+ render: () => <Skeleton className="h-12 w-12 rounded-full" />,
47
+ }
48
+
49
+ export const Button: Story = {
50
+ render: () => <Skeleton className="h-9 w-[100px] rounded-lg" />,
51
+ }
52
+
53
+ export const Image: Story = {
54
+ render: () => <Skeleton className="h-[200px] w-[300px] rounded-lg" />,
55
+ }
56
+
57
+ export const AllVariants: Story = {
58
+ render: () => (
59
+ <Flex gap={8}>
60
+ <Typography variant="h4" className="text-white">Skeleton Loading States</Typography>
61
+
62
+ <Flex gap={4}>
63
+ <Typography variant="body2" className="text-grey-400">User Card</Typography>
64
+ <div className="flex items-center space-x-4 bg-white p-4 rounded-lg w-[350px]">
65
+ <Skeleton className="h-12 w-12 rounded-full" />
66
+ <div className="space-y-2 flex-1">
67
+ <Skeleton className="h-4 w-3/4" />
68
+ <Skeleton className="h-3 w-1/2" />
69
+ </div>
70
+ </div>
71
+ </Flex>
72
+
73
+ <Flex gap={4}>
74
+ <Typography variant="body2" className="text-grey-400">Article Preview</Typography>
75
+ <div className="space-y-3 bg-white p-4 rounded-lg w-[350px]">
76
+ <Skeleton className="h-[150px] w-full rounded-md" />
77
+ <Skeleton className="h-5 w-3/4" />
78
+ <Skeleton className="h-4 w-full" />
79
+ <Skeleton className="h-4 w-5/6" />
80
+ <div className="flex items-center space-x-4 pt-2">
81
+ <Skeleton className="h-8 w-8 rounded-full" />
82
+ <Skeleton className="h-3 w-24" />
83
+ </div>
84
+ </div>
85
+ </Flex>
86
+
87
+ <Flex gap={4}>
88
+ <Typography variant="body2" className="text-grey-400">Table Row</Typography>
89
+ <div className="space-y-2 bg-white p-4 rounded-lg w-[400px]">
90
+ {Array.from({ length: 3 }).map((_, i) => (
91
+ <div key={i} className="flex items-center space-x-4">
92
+ <Skeleton className="h-4 w-4" />
93
+ <Skeleton className="h-4 w-[120px]" />
94
+ <Skeleton className="h-4 w-[80px]" />
95
+ <Skeleton className="h-4 w-[60px]" />
96
+ </div>
97
+ ))}
98
+ </div>
99
+ </Flex>
100
+
101
+ <Flex gap={4}>
102
+ <Typography variant="body2" className="text-grey-400">Form</Typography>
103
+ <div className="space-y-4 bg-white p-4 rounded-lg w-[300px]">
104
+ <div className="space-y-2">
105
+ <Skeleton className="h-4 w-16" />
106
+ <Skeleton className="h-9 w-full rounded-lg" />
107
+ </div>
108
+ <div className="space-y-2">
109
+ <Skeleton className="h-4 w-20" />
110
+ <Skeleton className="h-9 w-full rounded-lg" />
111
+ </div>
112
+ <Skeleton className="h-9 w-full rounded-lg" />
113
+ </div>
114
+ </Flex>
115
+ </Flex>
116
+ ),
117
+ }
@@ -0,0 +1,16 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "../lib/utils"
4
+
5
+ export type SkeletonProps = React.HTMLAttributes<HTMLDivElement>
6
+
7
+ function Skeleton({ className, ...props }: SkeletonProps) {
8
+ return (
9
+ <div
10
+ className={cn("animate-pulse rounded-md bg-grey-100", className)}
11
+ {...props}
12
+ />
13
+ )
14
+ }
15
+
16
+ export { Skeleton }