@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.
- package/CHANGELOG.md +62 -0
- package/index.css +3 -0
- package/package.json +59 -0
- package/src/_old/_table/index.ts +5 -0
- package/src/_old/_table/table-advanced.constants.tsx +24 -0
- package/src/_old/_table/table-advanced.tsx +311 -0
- package/src/_old/_table/table-advanced.types.ts +272 -0
- package/src/_old/_table/table.constants.ts +2 -0
- package/src/_old/_table/table.hook.tsx +115 -0
- package/src/_old/_table/table.lib.ts +85 -0
- package/src/_old/_table/table.tsx +916 -0
- package/src/_old/_table/table.types.ts +118 -0
- package/src/_old/_table/todo.md +11 -0
- package/src/_old/_upload/index.ts +9 -0
- package/src/_old/_upload/todo.md +38 -0
- package/src/_old/_upload/upload-advanced-chunks.tsx +1624 -0
- package/src/_old/_upload/upload-advanced.tsx +507 -0
- package/src/_old/_upload/upload-sonner.tsx +58 -0
- package/src/_old/_upload/upload.assets.tsx +239 -0
- package/src/_old/_upload/upload.constants.tsx +75 -0
- package/src/_old/_upload/upload.dto.ts +19 -0
- package/src/_old/_upload/upload.lib.tsx +630 -0
- package/src/_old/_upload/upload.tsx +491 -0
- package/src/_old/_upload/upload.types.ts +436 -0
- package/src/accordion/accordion.tsx +247 -0
- package/src/accordion/index.ts +1 -0
- package/src/alert/alert.constants.ts +17 -0
- package/src/alert/alert.tsx +52 -0
- package/src/alert/index.ts +2 -0
- package/src/alert-dialog/alert-dialog.tsx +107 -0
- package/src/alert-dialog/index.ts +1 -0
- package/src/aspect-ratio/aspect-ratio.tsx +33 -0
- package/src/aspect-ratio/index.ts +1 -0
- package/src/audio/audio-record.tsx +776 -0
- package/src/audio/audio-visualizer.tsx +377 -0
- package/src/audio/audio.libs.ts +5 -0
- package/src/audio/audio.types.ts +50 -0
- package/src/audio/index.ts +2 -0
- package/src/avatar/avatar.tsx +78 -0
- package/src/avatar/index.ts +1 -0
- package/src/badge/badge.constants.ts +38 -0
- package/src/badge/badge.tsx +19 -0
- package/src/badge/index.ts +2 -0
- package/src/breadcrumb/breadcrumb.tsx +119 -0
- package/src/breadcrumb/index.ts +1 -0
- package/src/button/button.constants.ts +44 -0
- package/src/button/button.tsx +79 -0
- package/src/button/button.types.ts +38 -0
- package/src/button/index.ts +3 -0
- package/src/button-group/button-group.constants.ts +26 -0
- package/src/button-group/button-group.tsx +65 -0
- package/src/button-group/index.ts +2 -0
- package/src/calendar/calendar.tsx +191 -0
- package/src/calendar/index.ts +1 -0
- package/src/card/card.tsx +81 -0
- package/src/card/index.ts +1 -0
- package/src/carousel/carousel.tsx +211 -0
- package/src/carousel/carousel.types.ts +23 -0
- package/src/carousel/index.ts +2 -0
- package/src/chart/chart.libs.ts +27 -0
- package/src/chart/chart.tsx +260 -0
- package/src/chart/chart.types.ts +38 -0
- package/src/chart/index.ts +3 -0
- package/src/checkbox/checkbox.tsx +144 -0
- package/src/checkbox/checkbox.types.ts +24 -0
- package/src/checkbox/index.ts +2 -0
- package/src/collapsible/collapsible.tsx +151 -0
- package/src/collapsible/index.ts +1 -0
- package/src/combobox/combobox.tsx +132 -0
- package/src/combobox/index.ts +1 -0
- package/src/command/command.tsx +192 -0
- package/src/command/command.types.ts +11 -0
- package/src/command/index.ts +2 -0
- package/src/context-menu/context-menu.tsx +178 -0
- package/src/context-menu/index.ts +1 -0
- package/src/dialog/dialog-responsive.tsx +137 -0
- package/src/dialog/dialog.tsx +97 -0
- package/src/dialog/index.ts +2 -0
- package/src/direction/direction.tsx +13 -0
- package/src/direction/index.ts +1 -0
- package/src/drawer/drawer.tsx +185 -0
- package/src/drawer/index.ts +1 -0
- package/src/dropdown-menu/dropdown-menu.tsx +181 -0
- package/src/dropdown-menu/index.ts +1 -0
- package/src/empty/empty.constants.ts +15 -0
- package/src/empty/empty.tsx +73 -0
- package/src/empty/index.ts +2 -0
- package/src/field/field.constants.ts +22 -0
- package/src/field/field.tsx +203 -0
- package/src/field/index.ts +2 -0
- package/src/hover-card/hover-card.tsx +79 -0
- package/src/hover-card/index.ts +1 -0
- package/src/input/index.ts +1 -0
- package/src/input/input.tsx +45 -0
- package/src/input-group/index.ts +1 -0
- package/src/input-group/input-group.tsx +170 -0
- package/src/input-otp/index.ts +1 -0
- package/src/input-otp/input-otp.tsx +66 -0
- package/src/item/index.ts +2 -0
- package/src/item/item.constants.ts +22 -0
- package/src/item/item.tsx +185 -0
- package/src/json-editor/index.ts +4 -0
- package/src/json-editor/json-editor.hooks.ts +21 -0
- package/src/json-editor/json-editor.libs.ts +34 -0
- package/src/json-editor/json-editor.tsx +425 -0
- package/src/json-editor/json-editor.types.ts +80 -0
- package/src/json-editor/json-editor.view.tsx +110 -0
- package/src/json-editor/json-text-area.tsx +7 -0
- package/src/kbd/index.ts +1 -0
- package/src/kbd/kbd.tsx +39 -0
- package/src/label/index.ts +1 -0
- package/src/label/label.tsx +28 -0
- package/src/menubar/index.ts +1 -0
- package/src/menubar/menubar.tsx +213 -0
- package/src/navigation-menu/index.ts +1 -0
- package/src/navigation-menu/navigation-menu.tsx +152 -0
- package/src/pagination/index.ts +2 -0
- package/src/pagination/pagination.tsx +191 -0
- package/src/pagination/pagination.types.ts +17 -0
- package/src/popover/index.ts +1 -0
- package/src/popover/popover.tsx +35 -0
- package/src/preview-panel/index.ts +3 -0
- package/src/preview-panel/preview-panel-dialog.tsx +99 -0
- package/src/preview-panel/preview-panel.tsx +389 -0
- package/src/preview-panel/preview-panel.types.ts +49 -0
- package/src/progress/index.ts +1 -0
- package/src/progress/progress.tsx +32 -0
- package/src/radio-group/index.ts +1 -0
- package/src/radio-group/radio-group.tsx +92 -0
- package/src/resizable/index.ts +1 -0
- package/src/resizable/resizable.tsx +52 -0
- package/src/scroll-area/index.ts +1 -0
- package/src/scroll-area/scroll-area.tsx +30 -0
- package/src/select/index.ts +1 -0
- package/src/select/select.tsx +138 -0
- package/src/separator/index.ts +1 -0
- package/src/separator/separator.tsx +28 -0
- package/src/sheet/index.ts +2 -0
- package/src/sheet/sheet.constants.tsx +20 -0
- package/src/sheet/sheet.tsx +92 -0
- package/src/sidebar/index.ts +4 -0
- package/src/sidebar/sidebar.constants.ts +30 -0
- package/src/sidebar/sidebar.hooks.ts +13 -0
- package/src/sidebar/sidebar.tsx +676 -0
- package/src/sidebar/sidebar.types.ts +28 -0
- package/src/skeleton/index.ts +1 -0
- package/src/skeleton/skeleton.tsx +22 -0
- package/src/slider/index.ts +1 -0
- package/src/slider/slider.tsx +57 -0
- package/src/sonner/index.ts +4 -0
- package/src/sonner/sonner.chunks.tsx +80 -0
- package/src/sonner/sonner.libs.ts +13 -0
- package/src/sonner/sonner.tsx +31 -0
- package/src/sonner/sonner.types.ts +9 -0
- package/src/switch/index.ts +1 -0
- package/src/switch/switch.tsx +63 -0
- package/src/table/index.ts +1 -0
- package/src/table/table.tsx +95 -0
- package/src/tabs/index.ts +1 -0
- package/src/tabs/tabs.tsx +151 -0
- package/src/textarea/index.ts +1 -0
- package/src/textarea/textarea.tsx +24 -0
- package/src/toggle/index.ts +2 -0
- package/src/toggle/toggle.constants.ts +22 -0
- package/src/toggle/toggle.tsx +24 -0
- package/src/toggle-group/index.ts +1 -0
- package/src/toggle-group/toggle-group.tsx +69 -0
- package/src/tooltip/index.ts +1 -0
- package/src/tooltip/tooltip.tsx +32 -0
- package/src/upload/index.ts +1 -0
- package/src/upload/upload.constants.tsx +19 -0
- package/src/upload/upload.libs.ts +97 -0
- package/src/upload/upload.tsx +340 -0
- package/src/upload/upload.types.ts +44 -0
- 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,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,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
|
+
}
|