@gentleduck/registry-ui 0.2.1

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 (175) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/index.css +3 -0
  3. package/package.json +59 -0
  4. package/src/_old/_table/index.ts +5 -0
  5. package/src/_old/_table/table-advanced.constants.tsx +24 -0
  6. package/src/_old/_table/table-advanced.tsx +311 -0
  7. package/src/_old/_table/table-advanced.types.ts +272 -0
  8. package/src/_old/_table/table.constants.ts +2 -0
  9. package/src/_old/_table/table.hook.tsx +115 -0
  10. package/src/_old/_table/table.lib.ts +85 -0
  11. package/src/_old/_table/table.tsx +916 -0
  12. package/src/_old/_table/table.types.ts +118 -0
  13. package/src/_old/_table/todo.md +11 -0
  14. package/src/_old/_upload/index.ts +9 -0
  15. package/src/_old/_upload/todo.md +38 -0
  16. package/src/_old/_upload/upload-advanced-chunks.tsx +1624 -0
  17. package/src/_old/_upload/upload-advanced.tsx +507 -0
  18. package/src/_old/_upload/upload-sonner.tsx +58 -0
  19. package/src/_old/_upload/upload.assets.tsx +239 -0
  20. package/src/_old/_upload/upload.constants.tsx +75 -0
  21. package/src/_old/_upload/upload.dto.ts +19 -0
  22. package/src/_old/_upload/upload.lib.tsx +630 -0
  23. package/src/_old/_upload/upload.tsx +491 -0
  24. package/src/_old/_upload/upload.types.ts +436 -0
  25. package/src/accordion/accordion.tsx +247 -0
  26. package/src/accordion/index.ts +1 -0
  27. package/src/alert/alert.constants.ts +17 -0
  28. package/src/alert/alert.tsx +52 -0
  29. package/src/alert/index.ts +2 -0
  30. package/src/alert-dialog/alert-dialog.tsx +107 -0
  31. package/src/alert-dialog/index.ts +1 -0
  32. package/src/aspect-ratio/aspect-ratio.tsx +33 -0
  33. package/src/aspect-ratio/index.ts +1 -0
  34. package/src/audio/audio-record.tsx +776 -0
  35. package/src/audio/audio-visualizer.tsx +377 -0
  36. package/src/audio/audio.libs.ts +5 -0
  37. package/src/audio/audio.types.ts +50 -0
  38. package/src/audio/index.ts +2 -0
  39. package/src/avatar/avatar.tsx +78 -0
  40. package/src/avatar/index.ts +1 -0
  41. package/src/badge/badge.constants.ts +38 -0
  42. package/src/badge/badge.tsx +19 -0
  43. package/src/badge/index.ts +2 -0
  44. package/src/breadcrumb/breadcrumb.tsx +119 -0
  45. package/src/breadcrumb/index.ts +1 -0
  46. package/src/button/button.constants.ts +44 -0
  47. package/src/button/button.tsx +79 -0
  48. package/src/button/button.types.ts +38 -0
  49. package/src/button/index.ts +3 -0
  50. package/src/button-group/button-group.constants.ts +26 -0
  51. package/src/button-group/button-group.tsx +65 -0
  52. package/src/button-group/index.ts +2 -0
  53. package/src/calendar/calendar.tsx +191 -0
  54. package/src/calendar/index.ts +1 -0
  55. package/src/card/card.tsx +81 -0
  56. package/src/card/index.ts +1 -0
  57. package/src/carousel/carousel.tsx +211 -0
  58. package/src/carousel/carousel.types.ts +23 -0
  59. package/src/carousel/index.ts +2 -0
  60. package/src/chart/chart.libs.ts +27 -0
  61. package/src/chart/chart.tsx +260 -0
  62. package/src/chart/chart.types.ts +38 -0
  63. package/src/chart/index.ts +3 -0
  64. package/src/checkbox/checkbox.tsx +144 -0
  65. package/src/checkbox/checkbox.types.ts +24 -0
  66. package/src/checkbox/index.ts +2 -0
  67. package/src/collapsible/collapsible.tsx +151 -0
  68. package/src/collapsible/index.ts +1 -0
  69. package/src/combobox/combobox.tsx +132 -0
  70. package/src/combobox/index.ts +1 -0
  71. package/src/command/command.tsx +192 -0
  72. package/src/command/command.types.ts +11 -0
  73. package/src/command/index.ts +2 -0
  74. package/src/context-menu/context-menu.tsx +178 -0
  75. package/src/context-menu/index.ts +1 -0
  76. package/src/dialog/dialog-responsive.tsx +137 -0
  77. package/src/dialog/dialog.tsx +97 -0
  78. package/src/dialog/index.ts +2 -0
  79. package/src/direction/direction.tsx +13 -0
  80. package/src/direction/index.ts +1 -0
  81. package/src/drawer/drawer.tsx +185 -0
  82. package/src/drawer/index.ts +1 -0
  83. package/src/dropdown-menu/dropdown-menu.tsx +181 -0
  84. package/src/dropdown-menu/index.ts +1 -0
  85. package/src/empty/empty.constants.ts +15 -0
  86. package/src/empty/empty.tsx +73 -0
  87. package/src/empty/index.ts +2 -0
  88. package/src/field/field.constants.ts +22 -0
  89. package/src/field/field.tsx +203 -0
  90. package/src/field/index.ts +2 -0
  91. package/src/hover-card/hover-card.tsx +79 -0
  92. package/src/hover-card/index.ts +1 -0
  93. package/src/input/index.ts +1 -0
  94. package/src/input/input.tsx +45 -0
  95. package/src/input-group/index.ts +1 -0
  96. package/src/input-group/input-group.tsx +170 -0
  97. package/src/input-otp/index.ts +1 -0
  98. package/src/input-otp/input-otp.tsx +66 -0
  99. package/src/item/index.ts +2 -0
  100. package/src/item/item.constants.ts +22 -0
  101. package/src/item/item.tsx +185 -0
  102. package/src/json-editor/index.ts +4 -0
  103. package/src/json-editor/json-editor.hooks.ts +21 -0
  104. package/src/json-editor/json-editor.libs.ts +34 -0
  105. package/src/json-editor/json-editor.tsx +425 -0
  106. package/src/json-editor/json-editor.types.ts +80 -0
  107. package/src/json-editor/json-editor.view.tsx +110 -0
  108. package/src/json-editor/json-text-area.tsx +7 -0
  109. package/src/kbd/index.ts +1 -0
  110. package/src/kbd/kbd.tsx +39 -0
  111. package/src/label/index.ts +1 -0
  112. package/src/label/label.tsx +28 -0
  113. package/src/menubar/index.ts +1 -0
  114. package/src/menubar/menubar.tsx +213 -0
  115. package/src/navigation-menu/index.ts +1 -0
  116. package/src/navigation-menu/navigation-menu.tsx +152 -0
  117. package/src/pagination/index.ts +2 -0
  118. package/src/pagination/pagination.tsx +191 -0
  119. package/src/pagination/pagination.types.ts +17 -0
  120. package/src/popover/index.ts +1 -0
  121. package/src/popover/popover.tsx +35 -0
  122. package/src/preview-panel/index.ts +3 -0
  123. package/src/preview-panel/preview-panel-dialog.tsx +99 -0
  124. package/src/preview-panel/preview-panel.tsx +389 -0
  125. package/src/preview-panel/preview-panel.types.ts +49 -0
  126. package/src/progress/index.ts +1 -0
  127. package/src/progress/progress.tsx +32 -0
  128. package/src/radio-group/index.ts +1 -0
  129. package/src/radio-group/radio-group.tsx +92 -0
  130. package/src/resizable/index.ts +1 -0
  131. package/src/resizable/resizable.tsx +52 -0
  132. package/src/scroll-area/index.ts +1 -0
  133. package/src/scroll-area/scroll-area.tsx +30 -0
  134. package/src/select/index.ts +1 -0
  135. package/src/select/select.tsx +138 -0
  136. package/src/separator/index.ts +1 -0
  137. package/src/separator/separator.tsx +28 -0
  138. package/src/sheet/index.ts +2 -0
  139. package/src/sheet/sheet.constants.tsx +20 -0
  140. package/src/sheet/sheet.tsx +92 -0
  141. package/src/sidebar/index.ts +4 -0
  142. package/src/sidebar/sidebar.constants.ts +30 -0
  143. package/src/sidebar/sidebar.hooks.ts +13 -0
  144. package/src/sidebar/sidebar.tsx +676 -0
  145. package/src/sidebar/sidebar.types.ts +28 -0
  146. package/src/skeleton/index.ts +1 -0
  147. package/src/skeleton/skeleton.tsx +22 -0
  148. package/src/slider/index.ts +1 -0
  149. package/src/slider/slider.tsx +57 -0
  150. package/src/sonner/index.ts +4 -0
  151. package/src/sonner/sonner.chunks.tsx +80 -0
  152. package/src/sonner/sonner.libs.ts +13 -0
  153. package/src/sonner/sonner.tsx +31 -0
  154. package/src/sonner/sonner.types.ts +9 -0
  155. package/src/switch/index.ts +1 -0
  156. package/src/switch/switch.tsx +63 -0
  157. package/src/table/index.ts +1 -0
  158. package/src/table/table.tsx +95 -0
  159. package/src/tabs/index.ts +1 -0
  160. package/src/tabs/tabs.tsx +151 -0
  161. package/src/textarea/index.ts +1 -0
  162. package/src/textarea/textarea.tsx +24 -0
  163. package/src/toggle/index.ts +2 -0
  164. package/src/toggle/toggle.constants.ts +22 -0
  165. package/src/toggle/toggle.tsx +24 -0
  166. package/src/toggle-group/index.ts +1 -0
  167. package/src/toggle-group/toggle-group.tsx +69 -0
  168. package/src/tooltip/index.ts +1 -0
  169. package/src/tooltip/tooltip.tsx +32 -0
  170. package/src/upload/index.ts +1 -0
  171. package/src/upload/upload.constants.tsx +19 -0
  172. package/src/upload/upload.libs.ts +97 -0
  173. package/src/upload/upload.tsx +340 -0
  174. package/src/upload/upload.types.ts +44 -0
  175. package/tsconfig.json +25 -0
@@ -0,0 +1,52 @@
1
+ 'use client'
2
+
3
+ import { cn } from '@gentleduck/libs/cn'
4
+ import { type Direction, useDirection } from '@gentleduck/primitives/direction'
5
+ import { GripVertical } from 'lucide-react'
6
+ import type * as React from 'react'
7
+ import * as ResizablePrimitive from 'react-resizable-panels'
8
+
9
+ const ResizablePanelGroup = ({
10
+ className,
11
+ dir,
12
+ ...props
13
+ }: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => {
14
+ const direction = useDirection(dir as Direction)
15
+ return (
16
+ <ResizablePrimitive.PanelGroup
17
+ className={cn('flex h-full w-full data-[panel-group-direction=vertical]:flex-col', className)}
18
+ data-slot="panel-group"
19
+ dir={direction}
20
+ {...props}
21
+ />
22
+ )
23
+ }
24
+
25
+ const ResizablePanel = ResizablePrimitive.Panel
26
+
27
+ const ResizableHandle = ({
28
+ withHandle,
29
+ className,
30
+ ...props
31
+ }: React.ComponentProps<typeof ResizablePrimitive.PanelResizeHandle> & {
32
+ withHandle?: boolean
33
+ }) => (
34
+ <ResizablePrimitive.PanelResizeHandle
35
+ aria-label="Resize panels"
36
+ className={cn(
37
+ 'relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:translate-x-0 data-[panel-group-direction=vertical]:after:-translate-y-1/2 [&[data-panel-group-direction=vertical]>div]:rotate-90',
38
+ className,
39
+ )}
40
+ data-slot="panel-resize-handle"
41
+ {...props}>
42
+ {withHandle && (
43
+ <div
44
+ className="z-10 flex h-4 w-3 items-center justify-center rounded-xs border bg-border"
45
+ data-slot="panel-handle">
46
+ <GripVertical aria-hidden="true" className="h-2.5 w-2.5" />
47
+ </div>
48
+ )}
49
+ </ResizablePrimitive.PanelResizeHandle>
50
+ )
51
+
52
+ export { ResizablePanelGroup, ResizablePanel, ResizableHandle }
@@ -0,0 +1 @@
1
+ export * from './scroll-area'
@@ -0,0 +1,30 @@
1
+ import { cn } from '@gentleduck/libs/cn'
2
+ import { type Direction, useDirection } from '@gentleduck/primitives/direction'
3
+ import * as React from 'react'
4
+
5
+ interface ScrollAreaProps extends React.HTMLAttributes<HTMLDivElement> {
6
+ viewportClassName?: string
7
+ viewportRef?: React.Ref<HTMLDivElement>
8
+ }
9
+
10
+ const ScrollArea = React.forwardRef<HTMLDivElement, ScrollAreaProps>(
11
+ ({ children, className, viewportClassName, viewportRef, style, dir, ...props }, ref) => {
12
+ const direction = useDirection(dir as Direction)
13
+ return (
14
+ <div
15
+ className={cn('relative overflow-hidden', className)}
16
+ dir={direction}
17
+ style={style}
18
+ ref={ref}
19
+ {...props}
20
+ data-slot="scroll-area">
21
+ <div ref={viewportRef} className={cn('scrollbar-none h-full w-full overflow-auto', viewportClassName)}>
22
+ {children}
23
+ </div>
24
+ </div>
25
+ )
26
+ },
27
+ )
28
+ ScrollArea.displayName = 'ScrollArea'
29
+
30
+ export { ScrollArea }
@@ -0,0 +1 @@
1
+ export * from './select'
@@ -0,0 +1,138 @@
1
+ 'use client'
2
+
3
+ import { cn } from '@gentleduck/libs/cn'
4
+ import * as SelectPrimitive from '@gentleduck/primitives/select'
5
+ import { Check, ChevronDown, ChevronUp } from 'lucide-react'
6
+ import * as React from 'react'
7
+
8
+ const Select = SelectPrimitive.Root
9
+
10
+ const SelectGroup = SelectPrimitive.Group
11
+
12
+ const SelectValue = SelectPrimitive.Value
13
+
14
+ const SelectTrigger = React.forwardRef<
15
+ React.ComponentRef<typeof SelectPrimitive.Trigger>,
16
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
17
+ >(({ className, children, ...props }, ref) => (
18
+ <SelectPrimitive.Trigger
19
+ ref={ref}
20
+ data-slot="select-trigger"
21
+ className={cn(
22
+ 'flex h-9 min-w-32 items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-placeholder:text-muted-foreground [&>span]:line-clamp-1',
23
+ className,
24
+ )}
25
+ {...props}>
26
+ {children}
27
+ <SelectPrimitive.Icon asChild>
28
+ <ChevronDown aria-hidden="true" className="size-4 opacity-50" />
29
+ </SelectPrimitive.Icon>
30
+ </SelectPrimitive.Trigger>
31
+ ))
32
+ SelectTrigger.displayName = SelectPrimitive.Trigger.displayName
33
+
34
+ const SelectScrollUpButton = React.forwardRef<
35
+ React.ComponentRef<typeof SelectPrimitive.ScrollUpButton>,
36
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollUpButton>
37
+ >(({ className, ...props }, ref) => (
38
+ <SelectPrimitive.ScrollUpButton
39
+ ref={ref}
40
+ className={cn('flex cursor-default items-center justify-center py-1', className)}
41
+ {...props}>
42
+ <ChevronUp aria-hidden="true" className="size-4" />
43
+ </SelectPrimitive.ScrollUpButton>
44
+ ))
45
+ SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName
46
+
47
+ const SelectScrollDownButton = React.forwardRef<
48
+ React.ComponentRef<typeof SelectPrimitive.ScrollDownButton>,
49
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.ScrollDownButton>
50
+ >(({ className, ...props }, ref) => (
51
+ <SelectPrimitive.ScrollDownButton
52
+ ref={ref}
53
+ className={cn('flex cursor-default items-center justify-center py-1', className)}
54
+ {...props}>
55
+ <ChevronDown aria-hidden="true" className="size-4" />
56
+ </SelectPrimitive.ScrollDownButton>
57
+ ))
58
+ SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName
59
+
60
+ const SelectContent = React.forwardRef<
61
+ React.ComponentRef<typeof SelectPrimitive.Content>,
62
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
63
+ >(({ className, children, position = 'popper', ...props }, ref) => (
64
+ <SelectPrimitive.Portal>
65
+ <SelectPrimitive.Content
66
+ ref={ref}
67
+ className={cn(
68
+ '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 relative z-50 max-h-(--gentleduck-select-content-available-height) min-w-32 origin-(--gentleduck-select-content-transform-origin) overflow-y-auto overflow-x-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=closed]:animate-out data-[state=open]:animate-in',
69
+ position === 'popper' &&
70
+ 'data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=bottom]:translate-y-1 data-[side=top]:-translate-y-1',
71
+ 'transition-all transition-discrete duration-[200ms,150ms] ease-(--duck-motion-ease)',
72
+ className,
73
+ )}
74
+ position={position}
75
+ {...props}>
76
+ <SelectScrollUpButton />
77
+ <SelectPrimitive.Viewport
78
+ className={cn(
79
+ 'p-1',
80
+ position === 'popper' &&
81
+ 'h-(--gentleduck-select-trigger-height) w-full min-w-(--gentleduck-select-trigger-width)',
82
+ )}>
83
+ {children}
84
+ </SelectPrimitive.Viewport>
85
+ <SelectScrollDownButton />
86
+ </SelectPrimitive.Content>
87
+ </SelectPrimitive.Portal>
88
+ ))
89
+ SelectContent.displayName = SelectPrimitive.Content.displayName
90
+
91
+ const SelectLabel = React.forwardRef<
92
+ React.ComponentRef<typeof SelectPrimitive.Label>,
93
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
94
+ >(({ className, ...props }, ref) => (
95
+ <SelectPrimitive.Label ref={ref} className={cn('px-2 py-1.5 font-semibold text-sm', className)} {...props} />
96
+ ))
97
+ SelectLabel.displayName = SelectPrimitive.Label.displayName
98
+
99
+ const SelectItem = React.forwardRef<HTMLDivElement, SelectPrimitive.SelectItemProps>(
100
+ ({ className, children, ...props }, ref) => (
101
+ <SelectPrimitive.Item
102
+ ref={ref}
103
+ className={cn(
104
+ 'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 ps-2 pe-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50',
105
+ className,
106
+ )}
107
+ {...props}>
108
+ <span className="absolute end-2 flex size-3.5 items-center justify-center">
109
+ <SelectPrimitive.ItemIndicator>
110
+ <Check aria-hidden="true" className="size-4" />
111
+ </SelectPrimitive.ItemIndicator>
112
+ </span>
113
+ <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
114
+ </SelectPrimitive.Item>
115
+ ),
116
+ )
117
+ SelectItem.displayName = SelectPrimitive.Item.displayName
118
+
119
+ const SelectSeparator = React.forwardRef<
120
+ React.ComponentRef<typeof SelectPrimitive.Separator>,
121
+ React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator>
122
+ >(({ className, ...props }, ref) => (
123
+ <SelectPrimitive.Separator ref={ref} className={cn('-mx-1 my-1 h-px bg-muted', className)} {...props} />
124
+ ))
125
+ SelectSeparator.displayName = SelectPrimitive.Separator.displayName
126
+
127
+ export {
128
+ Select,
129
+ SelectGroup,
130
+ SelectValue,
131
+ SelectTrigger,
132
+ SelectContent,
133
+ SelectLabel,
134
+ SelectItem,
135
+ SelectSeparator,
136
+ SelectScrollUpButton,
137
+ SelectScrollDownButton,
138
+ }
@@ -0,0 +1 @@
1
+ export * from './separator'
@@ -0,0 +1,28 @@
1
+ 'use client'
2
+
3
+ import { cn } from '@gentleduck/libs/cn'
4
+ import { type Direction, useDirection } from '@gentleduck/primitives/direction'
5
+ import * as React from 'react'
6
+
7
+ const Separator = React.forwardRef<
8
+ HTMLHRElement,
9
+ React.HTMLAttributes<HTMLHRElement> & {
10
+ orientation?: 'horizontal' | 'vertical'
11
+ }
12
+ >(({ className, orientation = 'horizontal', dir, ...props }, ref) => {
13
+ const direction = useDirection(dir as Direction)
14
+ return (
15
+ <hr
16
+ ref={ref}
17
+ aria-orientation={orientation}
18
+ className={cn('shrink-0 bg-border', orientation === 'horizontal' ? 'h-px w-full' : 'min-h-full w-px', className)}
19
+ dir={direction}
20
+ role="separator"
21
+ {...props}
22
+ data-slot="separator"
23
+ />
24
+ )
25
+ })
26
+ Separator.displayName = 'Separator'
27
+
28
+ export { Separator }
@@ -0,0 +1,2 @@
1
+ export * from './sheet'
2
+ export * from './sheet.constants'
@@ -0,0 +1,20 @@
1
+ import { cva } from '@gentleduck/variants'
2
+
3
+ export const sheetVariants = cva(
4
+ 'fixed z-50 gap-4 bg-background p-6 shadow-lg transition-all transition-discrete duration-[200ms,150ms] ease-(--duck-motion-ease) data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:duration-300 data-[state=open]:duration-500',
5
+ {
6
+ variants: {
7
+ side: {
8
+ top: 'data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 border-b',
9
+ bottom:
10
+ 'data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 border-t',
11
+ left: 'data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm',
12
+ right:
13
+ 'data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm',
14
+ },
15
+ },
16
+ defaultVariants: {
17
+ side: 'right',
18
+ },
19
+ },
20
+ )
@@ -0,0 +1,92 @@
1
+ 'use client'
2
+
3
+ import { cn } from '@gentleduck/libs/cn'
4
+ import * as SheetPrimitive from '@gentleduck/primitives/sheet'
5
+ import type { VariantProps } from '@gentleduck/variants'
6
+ import { X } from 'lucide-react'
7
+ import * as React from 'react'
8
+ import { sheetVariants } from './sheet.constants'
9
+
10
+ const Sheet = SheetPrimitive.Root
11
+
12
+ const SheetTrigger = SheetPrimitive.Trigger
13
+
14
+ const SheetClose = SheetPrimitive.Close
15
+
16
+ const SheetPortal = SheetPrimitive.Portal
17
+
18
+ const SheetOverlay = React.forwardRef<
19
+ React.ComponentRef<typeof SheetPrimitive.Overlay>,
20
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
21
+ >(({ className, ...props }, ref) => (
22
+ <SheetPrimitive.Overlay
23
+ className={cn(
24
+ 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80 data-[state=closed]:animate-out data-[state=open]:animate-in',
25
+ 'transition-all transition-discrete duration-[200ms,150ms] ease-(--duck-motion-ease)',
26
+ className,
27
+ )}
28
+ {...props}
29
+ ref={ref}
30
+ />
31
+ ))
32
+ SheetOverlay.displayName = SheetPrimitive.Overlay.displayName
33
+
34
+ interface SheetContentProps
35
+ extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
36
+ VariantProps<typeof sheetVariants> {}
37
+
38
+ const SheetContent = React.forwardRef<
39
+ React.ComponentRef<typeof SheetPrimitive.Content>,
40
+ SheetContentProps & { closeText?: string }
41
+ >(({ side = 'right', className, children, closeText = 'Close', ...props }, ref) => (
42
+ <SheetPortal>
43
+ <SheetOverlay />
44
+ <SheetPrimitive.Content ref={ref} className={cn(sheetVariants({ side }), className)} {...props}>
45
+ <SheetPrimitive.Close className="absolute end-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
46
+ <X aria-hidden="true" className="h-4 w-4" />
47
+ <span className="sr-only">{closeText}</span>
48
+ </SheetPrimitive.Close>
49
+ {children}
50
+ </SheetPrimitive.Content>
51
+ </SheetPortal>
52
+ ))
53
+ SheetContent.displayName = SheetPrimitive.Content.displayName
54
+
55
+ const SheetHeader = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
56
+ <div className={cn('flex flex-col space-y-2 text-center sm:text-start', className)} {...props} />
57
+ )
58
+ SheetHeader.displayName = 'SheetHeader'
59
+
60
+ const SheetFooter = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) => (
61
+ <div className={cn('flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2', className)} {...props} />
62
+ )
63
+ SheetFooter.displayName = 'SheetFooter'
64
+
65
+ const SheetTitle = React.forwardRef<
66
+ React.ComponentRef<typeof SheetPrimitive.Title>,
67
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
68
+ >(({ className, ...props }, ref) => (
69
+ <SheetPrimitive.Title ref={ref} className={cn('font-semibold text-foreground text-lg', className)} {...props} />
70
+ ))
71
+ SheetTitle.displayName = SheetPrimitive.Title.displayName
72
+
73
+ const SheetDescription = React.forwardRef<
74
+ React.ComponentRef<typeof SheetPrimitive.Description>,
75
+ React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
76
+ >(({ className, ...props }, ref) => (
77
+ <SheetPrimitive.Description ref={ref} className={cn('text-muted-foreground text-sm', className)} {...props} />
78
+ ))
79
+ SheetDescription.displayName = SheetPrimitive.Description.displayName
80
+
81
+ export {
82
+ Sheet,
83
+ SheetPortal,
84
+ SheetOverlay,
85
+ SheetTrigger,
86
+ SheetClose,
87
+ SheetContent,
88
+ SheetHeader,
89
+ SheetFooter,
90
+ SheetTitle,
91
+ SheetDescription,
92
+ }
@@ -0,0 +1,4 @@
1
+ export * from './sidebar'
2
+ export * from './sidebar.constants'
3
+ export * from './sidebar.hooks'
4
+ export * from './sidebar.types'
@@ -0,0 +1,30 @@
1
+ import { cva } from '@gentleduck/variants'
2
+
3
+ export const SIDEBAR_COOKIE_NAME = 'sidebar_state'
4
+ export const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7
5
+ export const SIDEBAR_WIDTH = '16rem'
6
+ export const SIDEBAR_WIDTH_MOBILE = '18rem'
7
+ export const SIDEBAR_WIDTH_ICON = '3rem'
8
+ export const SIDEBAR_KEYBOARD_SHORTCUT = 'b'
9
+
10
+ export const sidebarMenuButtonVariants = cva(
11
+ 'peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-start text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pe-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-active:bg-sidebar-accent data-active:font-medium data-active:text-sidebar-accent-foreground data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&_svg]:size-4 [&_svg]:shrink-0',
12
+ {
13
+ defaultVariants: {
14
+ size: 'default',
15
+ variant: 'default',
16
+ },
17
+ variants: {
18
+ size: {
19
+ default: 'h-8 text-sm',
20
+ lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!',
21
+ sm: 'h-7 text-xs',
22
+ },
23
+ variant: {
24
+ default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',
25
+ outline:
26
+ 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',
27
+ },
28
+ },
29
+ },
30
+ )
@@ -0,0 +1,13 @@
1
+ import React from 'react'
2
+ import type { SidebarContextProps } from './sidebar.types'
3
+
4
+ export const SidebarContext = React.createContext<SidebarContextProps | null>(null)
5
+
6
+ export function useSidebar() {
7
+ const context = React.useContext(SidebarContext)
8
+ if (!context) {
9
+ throw new Error('useSidebar must be used within a SidebarProvider.')
10
+ }
11
+
12
+ return context
13
+ }