@leitware/dockets 0.1.0
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/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +18 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/add.d.ts +3 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +86 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +36 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/registry.d.ts +18 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +712 -0
- package/dist/registry.js.map +1 -0
- package/package.json +40 -0
- package/templates/accordion.tsx +77 -0
- package/templates/alert-dialog.tsx +66 -0
- package/templates/alert.tsx +41 -0
- package/templates/aspect-ratio.tsx +15 -0
- package/templates/avatar.tsx +27 -0
- package/templates/badge.tsx +1 -0
- package/templates/block-loader.tsx +1 -0
- package/templates/breadcrumb.tsx +31 -0
- package/templates/button.tsx +1 -0
- package/templates/calendar.tsx +45 -0
- package/templates/card.tsx +35 -0
- package/templates/carousel.tsx +39 -0
- package/templates/checkbox.tsx +50 -0
- package/templates/code-block.tsx +1 -0
- package/templates/collapsible.tsx +35 -0
- package/templates/combobox.tsx +154 -0
- package/templates/command.tsx +50 -0
- package/templates/contact-footer.tsx +193 -0
- package/templates/context-menu.tsx +16 -0
- package/templates/dialog.tsx +67 -0
- package/templates/drawer.tsx +12 -0
- package/templates/dropdown-menu.tsx +95 -0
- package/templates/form-input.tsx +64 -0
- package/templates/form.tsx +10 -0
- package/templates/hover-card.tsx +5 -0
- package/templates/input-otp.tsx +6 -0
- package/templates/label.tsx +1 -0
- package/templates/layout-primitives.tsx +11 -0
- package/templates/layouts.tsx +346 -0
- package/templates/lib/utils.ts +49 -0
- package/templates/list-item.tsx +1 -0
- package/templates/list-items.tsx +41 -0
- package/templates/list.tsx +89 -0
- package/templates/logo.tsx +12 -0
- package/templates/marketing-footer.tsx +33 -0
- package/templates/marketing-header.tsx +46 -0
- package/templates/menubar.tsx +16 -0
- package/templates/navigation-menu.tsx +11 -0
- package/templates/pagination.tsx +86 -0
- package/templates/popover.tsx +8 -0
- package/templates/pricing-receipt.tsx +71 -0
- package/templates/pricing-tabs.tsx +60 -0
- package/templates/progress.tsx +29 -0
- package/templates/radio-group.tsx +58 -0
- package/templates/receipt-card.tsx +1 -0
- package/templates/receipt.tsx +269 -0
- package/templates/resizable.tsx +1 -0
- package/templates/scroll-area.tsx +1 -0
- package/templates/select.tsx +110 -0
- package/templates/separator.tsx +1 -0
- package/templates/sheet.tsx +12 -0
- package/templates/sidebar.tsx +15 -0
- package/templates/simple-footer.tsx +43 -0
- package/templates/simple-header.tsx +77 -0
- package/templates/skeleton.tsx +33 -0
- package/templates/slider.tsx +55 -0
- package/templates/styles/dockets.css +104 -0
- package/templates/switch.tsx +49 -0
- package/templates/table.tsx +73 -0
- package/templates/tabs.tsx +61 -0
- package/templates/theme-toggle.tsx +46 -0
- package/templates/toast.tsx +1 -0
- package/templates/toggle-group.tsx +1 -0
- package/templates/toggle.tsx +1 -0
- package/templates/tooltip.tsx +31 -0
- package/templates/tree-view.tsx +1 -0
- package/templates/ui/accordion.tsx +73 -0
- package/templates/ui/alert-dialog.tsx +128 -0
- package/templates/ui/alert.tsx +56 -0
- package/templates/ui/aspect-ratio.tsx +19 -0
- package/templates/ui/avatar.tsx +74 -0
- package/templates/ui/badge.tsx +48 -0
- package/templates/ui/block-loader.tsx +40 -0
- package/templates/ui/button.tsx +77 -0
- package/templates/ui/calendar.tsx +160 -0
- package/templates/ui/card.tsx +73 -0
- package/templates/ui/carousel.tsx +149 -0
- package/templates/ui/checkbox.tsx +33 -0
- package/templates/ui/code-block.tsx +36 -0
- package/templates/ui/collapsible.tsx +48 -0
- package/templates/ui/combobox.tsx +295 -0
- package/templates/ui/command.tsx +148 -0
- package/templates/ui/context-menu.tsx +212 -0
- package/templates/ui/dialog.tsx +138 -0
- package/templates/ui/drawer.tsx +134 -0
- package/templates/ui/dropdown-menu.tsx +254 -0
- package/templates/ui/form.tsx +122 -0
- package/templates/ui/hover-card.tsx +44 -0
- package/templates/ui/input-group.tsx +148 -0
- package/templates/ui/input-otp.tsx +153 -0
- package/templates/ui/input.tsx +20 -0
- package/templates/ui/label.tsx +17 -0
- package/templates/ui/layout.tsx +252 -0
- package/templates/ui/list-item.tsx +50 -0
- package/templates/ui/menubar.tsx +225 -0
- package/templates/ui/navigation-menu.tsx +117 -0
- package/templates/ui/pagination.tsx +110 -0
- package/templates/ui/popover.tsx +77 -0
- package/templates/ui/progress.tsx +37 -0
- package/templates/ui/radio-group.tsx +41 -0
- package/templates/ui/receipt-card.tsx +70 -0
- package/templates/ui/resizable.tsx +140 -0
- package/templates/ui/scroll-area.tsx +64 -0
- package/templates/ui/select.tsx +186 -0
- package/templates/ui/separator.tsx +21 -0
- package/templates/ui/sheet.tsx +134 -0
- package/templates/ui/sidebar.tsx +222 -0
- package/templates/ui/skeleton.tsx +35 -0
- package/templates/ui/slider.tsx +60 -0
- package/templates/ui/switch.tsx +33 -0
- package/templates/ui/table.tsx +114 -0
- package/templates/ui/tabs.tsx +79 -0
- package/templates/ui/textarea.tsx +18 -0
- package/templates/ui/toast.tsx +139 -0
- package/templates/ui/toggle-group.tsx +68 -0
- package/templates/ui/toggle.tsx +47 -0
- package/templates/ui/tooltip.tsx +53 -0
- package/templates/ui/tree-view.tsx +76 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import { GripVerticalIcon } from 'lucide-react'
|
|
5
|
+
import { cn } from '@/lib/utils'
|
|
6
|
+
|
|
7
|
+
// Resizable panels implemented with pointer events — no heavy dependency.
|
|
8
|
+
// "Borders never stack" rule: the handle IS the border, so panels have no border of their own.
|
|
9
|
+
|
|
10
|
+
interface ResizablePanelGroupProps extends React.ComponentProps<'div'> {
|
|
11
|
+
direction?: 'horizontal' | 'vertical'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function ResizablePanelGroup({
|
|
15
|
+
className,
|
|
16
|
+
direction = 'horizontal',
|
|
17
|
+
children,
|
|
18
|
+
...props
|
|
19
|
+
}: ResizablePanelGroupProps) {
|
|
20
|
+
return (
|
|
21
|
+
<div
|
|
22
|
+
data-slot="resizable-panel-group"
|
|
23
|
+
data-direction={direction}
|
|
24
|
+
className={cn(
|
|
25
|
+
'flex w-full rounded-[var(--radius)]',
|
|
26
|
+
direction === 'horizontal' ? 'flex-row' : 'flex-col',
|
|
27
|
+
className,
|
|
28
|
+
)}
|
|
29
|
+
{...props}
|
|
30
|
+
>
|
|
31
|
+
{children}
|
|
32
|
+
</div>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface ResizablePanelProps extends React.ComponentProps<'div'> {
|
|
37
|
+
defaultSize?: number
|
|
38
|
+
minSize?: number
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function ResizablePanel({
|
|
42
|
+
className,
|
|
43
|
+
defaultSize,
|
|
44
|
+
style,
|
|
45
|
+
...props
|
|
46
|
+
}: ResizablePanelProps) {
|
|
47
|
+
return (
|
|
48
|
+
<div
|
|
49
|
+
data-slot="resizable-panel"
|
|
50
|
+
style={{ flexBasis: defaultSize ? `${defaultSize}%` : undefined, flexGrow: defaultSize ? 0 : 1, ...style }}
|
|
51
|
+
className={cn('overflow-hidden', className)}
|
|
52
|
+
{...props}
|
|
53
|
+
/>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
interface ResizableHandleProps extends React.ComponentProps<'div'> {
|
|
58
|
+
withHandle?: boolean
|
|
59
|
+
direction?: 'horizontal' | 'vertical'
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function ResizableHandle({
|
|
63
|
+
className,
|
|
64
|
+
withHandle = false,
|
|
65
|
+
direction = 'horizontal',
|
|
66
|
+
...props
|
|
67
|
+
}: ResizableHandleProps) {
|
|
68
|
+
const handleRef = React.useRef<HTMLDivElement>(null)
|
|
69
|
+
|
|
70
|
+
const onPointerDown = React.useCallback(
|
|
71
|
+
(e: React.PointerEvent<HTMLDivElement>) => {
|
|
72
|
+
e.preventDefault()
|
|
73
|
+
const handle = handleRef.current
|
|
74
|
+
if (!handle) return
|
|
75
|
+
|
|
76
|
+
const prev = handle.previousElementSibling as HTMLElement | null
|
|
77
|
+
const next = handle.nextElementSibling as HTMLElement | null
|
|
78
|
+
if (!prev || !next) return
|
|
79
|
+
|
|
80
|
+
const startX = e.clientX
|
|
81
|
+
const startY = e.clientY
|
|
82
|
+
const prevSize = direction === 'horizontal' ? prev.offsetWidth : prev.offsetHeight
|
|
83
|
+
const nextSize = direction === 'horizontal' ? next.offsetWidth : next.offsetHeight
|
|
84
|
+
const total = prevSize + nextSize
|
|
85
|
+
|
|
86
|
+
handle.setPointerCapture(e.pointerId)
|
|
87
|
+
|
|
88
|
+
const onMove = (moveEvent: PointerEvent) => {
|
|
89
|
+
const delta =
|
|
90
|
+
direction === 'horizontal'
|
|
91
|
+
? moveEvent.clientX - startX
|
|
92
|
+
: moveEvent.clientY - startY
|
|
93
|
+
const newPrev = Math.min(Math.max(prevSize + delta, 80), total - 80)
|
|
94
|
+
const newNext = total - newPrev
|
|
95
|
+
prev.style.flexBasis = `${newPrev}px`
|
|
96
|
+
next.style.flexBasis = `${newNext}px`
|
|
97
|
+
prev.style.flexGrow = '0'
|
|
98
|
+
next.style.flexGrow = '0'
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const onUp = () => {
|
|
102
|
+
handle.removeEventListener('pointermove', onMove as EventListener)
|
|
103
|
+
handle.removeEventListener('pointerup', onUp)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
handle.addEventListener('pointermove', onMove as EventListener)
|
|
107
|
+
handle.addEventListener('pointerup', onUp)
|
|
108
|
+
},
|
|
109
|
+
[direction],
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<div
|
|
114
|
+
ref={handleRef}
|
|
115
|
+
data-slot="resizable-handle"
|
|
116
|
+
onPointerDown={onPointerDown}
|
|
117
|
+
className={cn(
|
|
118
|
+
'relative flex shrink-0 items-center justify-center bg-border',
|
|
119
|
+
direction === 'horizontal'
|
|
120
|
+
? 'w-[length:var(--border-width)] cursor-col-resize'
|
|
121
|
+
: 'h-[length:var(--border-width)] cursor-row-resize',
|
|
122
|
+
'after:absolute after:z-10',
|
|
123
|
+
direction === 'horizontal'
|
|
124
|
+
? 'after:inset-y-0 after:w-3 after:-translate-x-1/2'
|
|
125
|
+
: 'after:inset-x-0 after:h-3 after:-translate-y-1/2',
|
|
126
|
+
'focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring',
|
|
127
|
+
className,
|
|
128
|
+
)}
|
|
129
|
+
{...props}
|
|
130
|
+
>
|
|
131
|
+
{withHandle && (
|
|
132
|
+
<div className="z-10 flex h-6 w-3 items-center justify-center rounded-[var(--radius)] border-[length:var(--border-width)] border-foreground bg-card">
|
|
133
|
+
<GripVerticalIcon className="size-2.5" />
|
|
134
|
+
</div>
|
|
135
|
+
)}
|
|
136
|
+
</div>
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export { ResizablePanelGroup, ResizablePanel, ResizableHandle }
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import { cn } from '@/lib/utils'
|
|
3
|
+
|
|
4
|
+
// Custom scrollbar via CSS — no heavy dependency.
|
|
5
|
+
// Uses scrollbar-width: thin + custom track/thumb colours via @layer utilities
|
|
6
|
+
// or explicit inline styles.
|
|
7
|
+
|
|
8
|
+
function ScrollArea({
|
|
9
|
+
className,
|
|
10
|
+
children,
|
|
11
|
+
orientation = 'vertical',
|
|
12
|
+
...props
|
|
13
|
+
}: React.ComponentProps<'div'> & {
|
|
14
|
+
orientation?: 'vertical' | 'horizontal' | 'both'
|
|
15
|
+
}) {
|
|
16
|
+
const overflowClass =
|
|
17
|
+
orientation === 'both'
|
|
18
|
+
? 'overflow-auto'
|
|
19
|
+
: orientation === 'horizontal'
|
|
20
|
+
? 'overflow-x-auto overflow-y-hidden'
|
|
21
|
+
: 'overflow-y-auto overflow-x-hidden'
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div
|
|
25
|
+
data-slot="scroll-area"
|
|
26
|
+
className={cn(
|
|
27
|
+
'relative rounded-[var(--radius)]',
|
|
28
|
+
overflowClass,
|
|
29
|
+
// Thin system scrollbar
|
|
30
|
+
'[scrollbar-width:thin] [scrollbar-color:hsl(var(--foreground)/0.3)_transparent]',
|
|
31
|
+
// Webkit
|
|
32
|
+
'[&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar]:h-1.5',
|
|
33
|
+
'[&::-webkit-scrollbar-track]:bg-transparent',
|
|
34
|
+
'[&::-webkit-scrollbar-thumb]:rounded-[var(--radius)] [&::-webkit-scrollbar-thumb]:bg-foreground/30 [&::-webkit-scrollbar-thumb]:hover:bg-foreground/50',
|
|
35
|
+
className,
|
|
36
|
+
)}
|
|
37
|
+
{...props}
|
|
38
|
+
>
|
|
39
|
+
{children}
|
|
40
|
+
</div>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function ScrollBar({ className, orientation = 'vertical', ...props }: React.ComponentProps<'div'> & {
|
|
45
|
+
orientation?: 'vertical' | 'horizontal'
|
|
46
|
+
}) {
|
|
47
|
+
return (
|
|
48
|
+
<div
|
|
49
|
+
data-slot="scroll-bar"
|
|
50
|
+
data-orientation={orientation}
|
|
51
|
+
className={cn(
|
|
52
|
+
'flex touch-none select-none bg-transparent',
|
|
53
|
+
orientation === 'vertical' && 'h-full w-1.5 border-l-[length:var(--border-width)] border-l-transparent p-px',
|
|
54
|
+
orientation === 'horizontal' && 'h-1.5 w-full border-t-[length:var(--border-width)] border-t-transparent p-px flex-col',
|
|
55
|
+
className,
|
|
56
|
+
)}
|
|
57
|
+
{...props}
|
|
58
|
+
>
|
|
59
|
+
<div className="relative flex-1 rounded-[var(--radius)] bg-foreground/30 hover:bg-foreground/50" />
|
|
60
|
+
</div>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { ScrollArea, ScrollBar }
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { Select as SelectPrimitive } from '@base-ui/react/select'
|
|
2
|
+
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from 'lucide-react'
|
|
3
|
+
import type * as React from 'react'
|
|
4
|
+
import { cn } from '@/lib/utils'
|
|
5
|
+
|
|
6
|
+
const Select = SelectPrimitive.Root
|
|
7
|
+
|
|
8
|
+
function SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {
|
|
9
|
+
return (
|
|
10
|
+
<SelectPrimitive.Group
|
|
11
|
+
data-slot="select-group"
|
|
12
|
+
className={cn('scroll-my-1', className)}
|
|
13
|
+
{...props}
|
|
14
|
+
/>
|
|
15
|
+
)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {
|
|
19
|
+
return (
|
|
20
|
+
<SelectPrimitive.Value
|
|
21
|
+
data-slot="select-value"
|
|
22
|
+
className={cn('flex flex-1 text-left', className)}
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function SelectTrigger({
|
|
29
|
+
className,
|
|
30
|
+
size = 'default',
|
|
31
|
+
children,
|
|
32
|
+
...props
|
|
33
|
+
}: SelectPrimitive.Trigger.Props & {
|
|
34
|
+
size?: 'sm' | 'default'
|
|
35
|
+
}) {
|
|
36
|
+
return (
|
|
37
|
+
<SelectPrimitive.Trigger
|
|
38
|
+
data-slot="select-trigger"
|
|
39
|
+
data-size={size}
|
|
40
|
+
className={cn(
|
|
41
|
+
"flex w-fit items-center justify-between gap-1.5 rounded-[var(--radius)] border-[length:var(--border-width)] border-input bg-transparent py-2 pr-2 pl-2.5 text-xs whitespace-nowrap select-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[var(--radius)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
42
|
+
className,
|
|
43
|
+
)}
|
|
44
|
+
{...props}
|
|
45
|
+
>
|
|
46
|
+
{children}
|
|
47
|
+
<SelectPrimitive.Icon
|
|
48
|
+
render={<ChevronDownIcon className="pointer-events-none size-4 text-muted-foreground" />}
|
|
49
|
+
/>
|
|
50
|
+
</SelectPrimitive.Trigger>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function SelectContent({
|
|
55
|
+
className,
|
|
56
|
+
children,
|
|
57
|
+
side = 'bottom',
|
|
58
|
+
sideOffset = 6,
|
|
59
|
+
align = 'start',
|
|
60
|
+
alignOffset = 0,
|
|
61
|
+
alignItemWithTrigger = false,
|
|
62
|
+
...props
|
|
63
|
+
}: SelectPrimitive.Popup.Props &
|
|
64
|
+
Pick<
|
|
65
|
+
SelectPrimitive.Positioner.Props,
|
|
66
|
+
'align' | 'alignOffset' | 'side' | 'sideOffset' | 'alignItemWithTrigger'
|
|
67
|
+
>) {
|
|
68
|
+
return (
|
|
69
|
+
<SelectPrimitive.Portal>
|
|
70
|
+
<SelectPrimitive.Positioner
|
|
71
|
+
side={side}
|
|
72
|
+
sideOffset={sideOffset}
|
|
73
|
+
align={align}
|
|
74
|
+
alignOffset={alignOffset}
|
|
75
|
+
alignItemWithTrigger={alignItemWithTrigger}
|
|
76
|
+
className="isolate z-50"
|
|
77
|
+
>
|
|
78
|
+
<SelectPrimitive.Popup
|
|
79
|
+
data-slot="select-content"
|
|
80
|
+
className={cn(
|
|
81
|
+
'relative isolate z-50 max-h-(--available-height) min-w-(--anchor-width) w-max origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-[var(--radius)] border-[length:var(--border-width)] border-foreground bg-popover text-popover-foreground shadow-none duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-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 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',
|
|
82
|
+
className,
|
|
83
|
+
)}
|
|
84
|
+
{...props}
|
|
85
|
+
>
|
|
86
|
+
<SelectScrollUpButton />
|
|
87
|
+
<SelectPrimitive.List>{children}</SelectPrimitive.List>
|
|
88
|
+
<SelectScrollDownButton />
|
|
89
|
+
</SelectPrimitive.Popup>
|
|
90
|
+
</SelectPrimitive.Positioner>
|
|
91
|
+
</SelectPrimitive.Portal>
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function SelectLabel({ className, ...props }: SelectPrimitive.GroupLabel.Props) {
|
|
96
|
+
return (
|
|
97
|
+
<SelectPrimitive.GroupLabel
|
|
98
|
+
data-slot="select-label"
|
|
99
|
+
className={cn('px-2 py-2 text-xs text-muted-foreground', className)}
|
|
100
|
+
{...props}
|
|
101
|
+
/>
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function SelectItem({ className, children, ...props }: SelectPrimitive.Item.Props) {
|
|
106
|
+
return (
|
|
107
|
+
<SelectPrimitive.Item
|
|
108
|
+
data-slot="select-item"
|
|
109
|
+
className={cn(
|
|
110
|
+
"relative flex w-full cursor-default items-center gap-2 rounded-[var(--radius)] py-2 pr-8 pl-2 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
|
111
|
+
className,
|
|
112
|
+
)}
|
|
113
|
+
{...props}
|
|
114
|
+
>
|
|
115
|
+
<SelectPrimitive.ItemText className="flex flex-1 shrink-0 gap-2 whitespace-nowrap">
|
|
116
|
+
{children}
|
|
117
|
+
</SelectPrimitive.ItemText>
|
|
118
|
+
<SelectPrimitive.ItemIndicator
|
|
119
|
+
render={
|
|
120
|
+
<span className="pointer-events-none absolute right-2 flex size-4 items-center justify-center" />
|
|
121
|
+
}
|
|
122
|
+
>
|
|
123
|
+
<CheckIcon className="pointer-events-none" />
|
|
124
|
+
</SelectPrimitive.ItemIndicator>
|
|
125
|
+
</SelectPrimitive.Item>
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function SelectSeparator({ className, ...props }: SelectPrimitive.Separator.Props) {
|
|
130
|
+
return (
|
|
131
|
+
<SelectPrimitive.Separator
|
|
132
|
+
data-slot="select-separator"
|
|
133
|
+
className={cn('pointer-events-none -mx-1 h-[length:var(--border-width)] bg-border', className)}
|
|
134
|
+
{...props}
|
|
135
|
+
/>
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function SelectScrollUpButton({
|
|
140
|
+
className,
|
|
141
|
+
...props
|
|
142
|
+
}: React.ComponentProps<typeof SelectPrimitive.ScrollUpArrow>) {
|
|
143
|
+
return (
|
|
144
|
+
<SelectPrimitive.ScrollUpArrow
|
|
145
|
+
data-slot="select-scroll-up-button"
|
|
146
|
+
className={cn(
|
|
147
|
+
"top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
148
|
+
className,
|
|
149
|
+
)}
|
|
150
|
+
{...props}
|
|
151
|
+
>
|
|
152
|
+
<ChevronUpIcon />
|
|
153
|
+
</SelectPrimitive.ScrollUpArrow>
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function SelectScrollDownButton({
|
|
158
|
+
className,
|
|
159
|
+
...props
|
|
160
|
+
}: React.ComponentProps<typeof SelectPrimitive.ScrollDownArrow>) {
|
|
161
|
+
return (
|
|
162
|
+
<SelectPrimitive.ScrollDownArrow
|
|
163
|
+
data-slot="select-scroll-down-button"
|
|
164
|
+
className={cn(
|
|
165
|
+
"bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4",
|
|
166
|
+
className,
|
|
167
|
+
)}
|
|
168
|
+
{...props}
|
|
169
|
+
>
|
|
170
|
+
<ChevronDownIcon />
|
|
171
|
+
</SelectPrimitive.ScrollDownArrow>
|
|
172
|
+
)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export {
|
|
176
|
+
Select,
|
|
177
|
+
SelectContent,
|
|
178
|
+
SelectGroup,
|
|
179
|
+
SelectItem,
|
|
180
|
+
SelectLabel,
|
|
181
|
+
SelectScrollDownButton,
|
|
182
|
+
SelectScrollUpButton,
|
|
183
|
+
SelectSeparator,
|
|
184
|
+
SelectTrigger,
|
|
185
|
+
SelectValue,
|
|
186
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { Separator as SeparatorPrimitive } from '@base-ui/react/separator'
|
|
4
|
+
|
|
5
|
+
import { cn } from '@/lib/utils'
|
|
6
|
+
|
|
7
|
+
function Separator({ className, orientation = 'horizontal', ...props }: SeparatorPrimitive.Props) {
|
|
8
|
+
return (
|
|
9
|
+
<SeparatorPrimitive
|
|
10
|
+
data-slot="separator"
|
|
11
|
+
orientation={orientation}
|
|
12
|
+
className={cn(
|
|
13
|
+
'shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch',
|
|
14
|
+
className,
|
|
15
|
+
)}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { Separator }
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { Dialog as DialogPrimitive } from '@base-ui/react/dialog'
|
|
4
|
+
import { XIcon } from 'lucide-react'
|
|
5
|
+
import * as React from 'react'
|
|
6
|
+
import { cn } from '@/lib/utils'
|
|
7
|
+
|
|
8
|
+
type SheetSide = 'top' | 'bottom' | 'left' | 'right'
|
|
9
|
+
|
|
10
|
+
function Sheet({ ...props }: DialogPrimitive.Root.Props) {
|
|
11
|
+
return <DialogPrimitive.Root data-slot="sheet" {...props} />
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function SheetTrigger({ ...props }: DialogPrimitive.Trigger.Props) {
|
|
15
|
+
return <DialogPrimitive.Trigger data-slot="sheet-trigger" {...props} />
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function SheetClose({ ...props }: DialogPrimitive.Close.Props) {
|
|
19
|
+
return <DialogPrimitive.Close data-slot="sheet-close" {...props} />
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function SheetPortal({ ...props }: DialogPrimitive.Portal.Props) {
|
|
23
|
+
return <DialogPrimitive.Portal data-slot="sheet-portal" {...props} />
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function SheetOverlay({ className, ...props }: DialogPrimitive.Backdrop.Props) {
|
|
27
|
+
return (
|
|
28
|
+
<DialogPrimitive.Backdrop
|
|
29
|
+
data-slot="sheet-overlay"
|
|
30
|
+
className={cn(
|
|
31
|
+
'fixed inset-0 z-50 bg-black/20 data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0',
|
|
32
|
+
className,
|
|
33
|
+
)}
|
|
34
|
+
{...props}
|
|
35
|
+
/>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const sheetSideClasses: Record<SheetSide, string> = {
|
|
40
|
+
top: 'inset-x-0 top-0 border-b-[length:var(--border-width)] data-open:slide-in-from-top data-closed:slide-out-to-top',
|
|
41
|
+
bottom: 'inset-x-0 bottom-0 border-t-[length:var(--border-width)] data-open:slide-in-from-bottom data-closed:slide-out-to-bottom',
|
|
42
|
+
left: 'inset-y-0 left-0 h-full w-3/4 sm:max-w-sm border-r-[length:var(--border-width)] data-open:slide-in-from-left data-closed:slide-out-to-left',
|
|
43
|
+
right: 'inset-y-0 right-0 h-full w-3/4 sm:max-w-sm border-l-[length:var(--border-width)] data-open:slide-in-from-right data-closed:slide-out-to-right',
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function SheetContent({
|
|
47
|
+
side = 'right',
|
|
48
|
+
className,
|
|
49
|
+
children,
|
|
50
|
+
showCloseButton = true,
|
|
51
|
+
...props
|
|
52
|
+
}: DialogPrimitive.Popup.Props & {
|
|
53
|
+
side?: SheetSide
|
|
54
|
+
showCloseButton?: boolean
|
|
55
|
+
}) {
|
|
56
|
+
return (
|
|
57
|
+
<SheetPortal>
|
|
58
|
+
<SheetOverlay />
|
|
59
|
+
<DialogPrimitive.Popup
|
|
60
|
+
data-slot="sheet-content"
|
|
61
|
+
className={cn(
|
|
62
|
+
'fixed z-50 flex flex-col gap-4 rounded-[var(--radius)] border-foreground bg-card p-6 text-xs/relaxed text-card-foreground duration-200 outline-none data-open:animate-in data-closed:animate-out',
|
|
63
|
+
sheetSideClasses[side],
|
|
64
|
+
className,
|
|
65
|
+
)}
|
|
66
|
+
{...props}
|
|
67
|
+
>
|
|
68
|
+
{showCloseButton && (
|
|
69
|
+
<DialogPrimitive.Close
|
|
70
|
+
data-slot="sheet-close"
|
|
71
|
+
className="absolute top-4 right-4 flex size-6 items-center justify-center text-muted-foreground hover:text-foreground"
|
|
72
|
+
aria-label="Close"
|
|
73
|
+
>
|
|
74
|
+
<XIcon className="size-4" />
|
|
75
|
+
</DialogPrimitive.Close>
|
|
76
|
+
)}
|
|
77
|
+
{children}
|
|
78
|
+
</DialogPrimitive.Popup>
|
|
79
|
+
</SheetPortal>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function SheetHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
84
|
+
return (
|
|
85
|
+
<div
|
|
86
|
+
data-slot="sheet-header"
|
|
87
|
+
className={cn('flex flex-col gap-1', className)}
|
|
88
|
+
{...props}
|
|
89
|
+
/>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function SheetFooter({ className, ...props }: React.ComponentProps<'div'>) {
|
|
94
|
+
return (
|
|
95
|
+
<div
|
|
96
|
+
data-slot="sheet-footer"
|
|
97
|
+
className={cn('mt-auto flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}
|
|
98
|
+
{...props}
|
|
99
|
+
/>
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function SheetTitle({ className, ...props }: DialogPrimitive.Title.Props) {
|
|
104
|
+
return (
|
|
105
|
+
<DialogPrimitive.Title
|
|
106
|
+
data-slot="sheet-title"
|
|
107
|
+
className={cn('text-sm font-medium uppercase tracking-wider', className)}
|
|
108
|
+
{...props}
|
|
109
|
+
/>
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function SheetDescription({ className, ...props }: DialogPrimitive.Description.Props) {
|
|
114
|
+
return (
|
|
115
|
+
<DialogPrimitive.Description
|
|
116
|
+
data-slot="sheet-description"
|
|
117
|
+
className={cn('text-xs/relaxed text-muted-foreground', className)}
|
|
118
|
+
{...props}
|
|
119
|
+
/>
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export {
|
|
124
|
+
Sheet,
|
|
125
|
+
SheetTrigger,
|
|
126
|
+
SheetClose,
|
|
127
|
+
SheetPortal,
|
|
128
|
+
SheetOverlay,
|
|
129
|
+
SheetContent,
|
|
130
|
+
SheetHeader,
|
|
131
|
+
SheetFooter,
|
|
132
|
+
SheetTitle,
|
|
133
|
+
SheetDescription,
|
|
134
|
+
}
|