@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,148 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import { SearchIcon } from 'lucide-react'
|
|
5
|
+
import { cn } from '@/lib/utils'
|
|
6
|
+
|
|
7
|
+
interface CommandContextValue {
|
|
8
|
+
query: string
|
|
9
|
+
setQuery: (q: string) => void
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const CommandContext = React.createContext<CommandContextValue>({
|
|
13
|
+
query: '',
|
|
14
|
+
setQuery: () => {},
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
function Command({ className, children, ...props }: React.ComponentProps<'div'>) {
|
|
18
|
+
const [query, setQuery] = React.useState('')
|
|
19
|
+
return (
|
|
20
|
+
<CommandContext.Provider value={{ query, setQuery }}>
|
|
21
|
+
<div
|
|
22
|
+
data-slot="command"
|
|
23
|
+
className={cn(
|
|
24
|
+
'flex flex-col rounded-[var(--radius)] border-[length:var(--border-width)] border-foreground bg-popover text-popover-foreground',
|
|
25
|
+
className,
|
|
26
|
+
)}
|
|
27
|
+
{...props}
|
|
28
|
+
>
|
|
29
|
+
{children}
|
|
30
|
+
</div>
|
|
31
|
+
</CommandContext.Provider>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function CommandInput({ className, ...props }: React.ComponentProps<'input'>) {
|
|
36
|
+
const { setQuery } = React.useContext(CommandContext)
|
|
37
|
+
return (
|
|
38
|
+
<div
|
|
39
|
+
data-slot="command-input-wrapper"
|
|
40
|
+
className="flex items-center border-b-[length:var(--border-width)] border-foreground px-2"
|
|
41
|
+
>
|
|
42
|
+
<SearchIcon className="size-3.5 shrink-0 text-muted-foreground" />
|
|
43
|
+
<input
|
|
44
|
+
data-slot="command-input"
|
|
45
|
+
type="text"
|
|
46
|
+
role="combobox"
|
|
47
|
+
autoComplete="off"
|
|
48
|
+
autoCorrect="off"
|
|
49
|
+
spellCheck={false}
|
|
50
|
+
onChange={(e) => setQuery(e.target.value)}
|
|
51
|
+
className={cn(
|
|
52
|
+
'h-9 w-full bg-transparent px-2 text-xs placeholder:text-muted-foreground outline-none disabled:cursor-not-allowed disabled:opacity-50',
|
|
53
|
+
className,
|
|
54
|
+
)}
|
|
55
|
+
{...props}
|
|
56
|
+
/>
|
|
57
|
+
</div>
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function CommandList({ className, ...props }: React.ComponentProps<'div'>) {
|
|
62
|
+
return (
|
|
63
|
+
<div
|
|
64
|
+
data-slot="command-list"
|
|
65
|
+
role="listbox"
|
|
66
|
+
className={cn('max-h-64 overflow-y-auto overflow-x-hidden', className)}
|
|
67
|
+
{...props}
|
|
68
|
+
/>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function CommandEmpty({ className, ...props }: React.ComponentProps<'div'>) {
|
|
73
|
+
return (
|
|
74
|
+
<div
|
|
75
|
+
data-slot="command-empty"
|
|
76
|
+
className={cn('py-6 text-center text-xs text-muted-foreground', className)}
|
|
77
|
+
{...props}
|
|
78
|
+
/>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function CommandGroup({ className, heading, children, ...props }: React.ComponentProps<'div'> & { heading?: string }) {
|
|
83
|
+
return (
|
|
84
|
+
<div data-slot="command-group" className={cn('py-1', className)} {...props}>
|
|
85
|
+
{heading && (
|
|
86
|
+
<div className="px-2 py-1 text-[10px] font-medium uppercase tracking-wider text-muted-foreground">
|
|
87
|
+
{heading}
|
|
88
|
+
</div>
|
|
89
|
+
)}
|
|
90
|
+
{children}
|
|
91
|
+
</div>
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function CommandItem({ className, onSelect, children, ...props }: React.ComponentProps<'div'> & { onSelect?: () => void }) {
|
|
96
|
+
return (
|
|
97
|
+
<div
|
|
98
|
+
data-slot="command-item"
|
|
99
|
+
role="option"
|
|
100
|
+
onClick={onSelect}
|
|
101
|
+
onKeyDown={(e) => {
|
|
102
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
103
|
+
e.preventDefault()
|
|
104
|
+
onSelect?.()
|
|
105
|
+
}
|
|
106
|
+
}}
|
|
107
|
+
tabIndex={0}
|
|
108
|
+
className={cn(
|
|
109
|
+
'flex cursor-default select-none items-center gap-2 rounded-[var(--radius)] px-2 py-1.5 text-xs outline-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
|
110
|
+
className,
|
|
111
|
+
)}
|
|
112
|
+
{...props}
|
|
113
|
+
>
|
|
114
|
+
{children}
|
|
115
|
+
</div>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function CommandSeparator({ className, ...props }: React.ComponentProps<'div'>) {
|
|
120
|
+
return (
|
|
121
|
+
<div
|
|
122
|
+
data-slot="command-separator"
|
|
123
|
+
className={cn('-mx-1 h-[length:var(--border-width)] bg-border', className)}
|
|
124
|
+
{...props}
|
|
125
|
+
/>
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function CommandShortcut({ className, ...props }: React.ComponentProps<'span'>) {
|
|
130
|
+
return (
|
|
131
|
+
<span
|
|
132
|
+
data-slot="command-shortcut"
|
|
133
|
+
className={cn('ml-auto text-[10px] tracking-widest text-muted-foreground', className)}
|
|
134
|
+
{...props}
|
|
135
|
+
/>
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export {
|
|
140
|
+
Command,
|
|
141
|
+
CommandInput,
|
|
142
|
+
CommandList,
|
|
143
|
+
CommandEmpty,
|
|
144
|
+
CommandGroup,
|
|
145
|
+
CommandItem,
|
|
146
|
+
CommandSeparator,
|
|
147
|
+
CommandShortcut,
|
|
148
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { Menu as MenuPrimitive } from '@base-ui/react/menu'
|
|
4
|
+
import { CheckIcon, ChevronRightIcon } from 'lucide-react'
|
|
5
|
+
import * as React from 'react'
|
|
6
|
+
import { cn } from '@/lib/utils'
|
|
7
|
+
|
|
8
|
+
function ContextMenu({ ...props }: MenuPrimitive.Root.Props) {
|
|
9
|
+
return <MenuPrimitive.Root data-slot="context-menu" {...props} />
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function ContextMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {
|
|
13
|
+
return <MenuPrimitive.Trigger data-slot="context-menu-trigger" {...props} />
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function ContextMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {
|
|
17
|
+
return <MenuPrimitive.Portal data-slot="context-menu-portal" {...props} />
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function ContextMenuContent({
|
|
21
|
+
className,
|
|
22
|
+
side = 'bottom',
|
|
23
|
+
align = 'start',
|
|
24
|
+
sideOffset = 4,
|
|
25
|
+
...props
|
|
26
|
+
}: MenuPrimitive.Popup.Props &
|
|
27
|
+
Pick<MenuPrimitive.Positioner.Props, 'align' | 'side' | 'sideOffset'>) {
|
|
28
|
+
return (
|
|
29
|
+
<MenuPrimitive.Portal>
|
|
30
|
+
<MenuPrimitive.Positioner
|
|
31
|
+
side={side}
|
|
32
|
+
align={align}
|
|
33
|
+
sideOffset={sideOffset}
|
|
34
|
+
className="isolate z-50 outline-none"
|
|
35
|
+
>
|
|
36
|
+
<MenuPrimitive.Popup
|
|
37
|
+
data-slot="context-menu-content"
|
|
38
|
+
className={cn(
|
|
39
|
+
'z-50 min-w-32 origin-(--transform-origin) overflow-hidden rounded-[var(--radius)] border-[length:var(--border-width)] border-foreground bg-popover text-popover-foreground shadow-none duration-100 outline-none 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',
|
|
40
|
+
className,
|
|
41
|
+
)}
|
|
42
|
+
{...props}
|
|
43
|
+
/>
|
|
44
|
+
</MenuPrimitive.Positioner>
|
|
45
|
+
</MenuPrimitive.Portal>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function ContextMenuItem({
|
|
50
|
+
className,
|
|
51
|
+
inset,
|
|
52
|
+
variant = 'default',
|
|
53
|
+
...props
|
|
54
|
+
}: MenuPrimitive.Item.Props & {
|
|
55
|
+
inset?: boolean
|
|
56
|
+
variant?: 'default' | 'destructive'
|
|
57
|
+
}) {
|
|
58
|
+
return (
|
|
59
|
+
<MenuPrimitive.Item
|
|
60
|
+
data-slot="context-menu-item"
|
|
61
|
+
data-inset={inset}
|
|
62
|
+
data-variant={variant}
|
|
63
|
+
className={cn(
|
|
64
|
+
"relative flex cursor-default items-center gap-2 rounded-[var(--radius)] px-2 py-2 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
65
|
+
className,
|
|
66
|
+
)}
|
|
67
|
+
{...props}
|
|
68
|
+
/>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function ContextMenuCheckboxItem({
|
|
73
|
+
className,
|
|
74
|
+
children,
|
|
75
|
+
checked,
|
|
76
|
+
...props
|
|
77
|
+
}: MenuPrimitive.CheckboxItem.Props) {
|
|
78
|
+
return (
|
|
79
|
+
<MenuPrimitive.CheckboxItem
|
|
80
|
+
data-slot="context-menu-checkbox-item"
|
|
81
|
+
className={cn(
|
|
82
|
+
"relative flex 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 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
83
|
+
className,
|
|
84
|
+
)}
|
|
85
|
+
checked={checked}
|
|
86
|
+
{...props}
|
|
87
|
+
>
|
|
88
|
+
<span className="pointer-events-none absolute right-2 flex items-center justify-center">
|
|
89
|
+
<MenuPrimitive.CheckboxItemIndicator>
|
|
90
|
+
<CheckIcon className="size-3" />
|
|
91
|
+
</MenuPrimitive.CheckboxItemIndicator>
|
|
92
|
+
</span>
|
|
93
|
+
{children}
|
|
94
|
+
</MenuPrimitive.CheckboxItem>
|
|
95
|
+
)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function ContextMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {
|
|
99
|
+
return <MenuPrimitive.RadioGroup data-slot="context-menu-radio-group" {...props} />
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function ContextMenuRadioItem({
|
|
103
|
+
className,
|
|
104
|
+
children,
|
|
105
|
+
...props
|
|
106
|
+
}: MenuPrimitive.RadioItem.Props) {
|
|
107
|
+
return (
|
|
108
|
+
<MenuPrimitive.RadioItem
|
|
109
|
+
data-slot="context-menu-radio-item"
|
|
110
|
+
className={cn(
|
|
111
|
+
"relative flex 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 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
112
|
+
className,
|
|
113
|
+
)}
|
|
114
|
+
{...props}
|
|
115
|
+
>
|
|
116
|
+
<span className="pointer-events-none absolute right-2 flex items-center justify-center">
|
|
117
|
+
<MenuPrimitive.RadioItemIndicator>
|
|
118
|
+
<CheckIcon className="size-3" />
|
|
119
|
+
</MenuPrimitive.RadioItemIndicator>
|
|
120
|
+
</span>
|
|
121
|
+
{children}
|
|
122
|
+
</MenuPrimitive.RadioItem>
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function ContextMenuLabel({
|
|
127
|
+
className,
|
|
128
|
+
inset,
|
|
129
|
+
...props
|
|
130
|
+
}: React.ComponentProps<'div'> & { inset?: boolean }) {
|
|
131
|
+
return (
|
|
132
|
+
<div
|
|
133
|
+
data-slot="context-menu-label"
|
|
134
|
+
data-inset={inset}
|
|
135
|
+
className={cn('px-2 py-2 text-xs text-muted-foreground data-inset:pl-7', className)}
|
|
136
|
+
{...props}
|
|
137
|
+
/>
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function ContextMenuSeparator({ className, ...props }: MenuPrimitive.Separator.Props) {
|
|
142
|
+
return (
|
|
143
|
+
<MenuPrimitive.Separator
|
|
144
|
+
data-slot="context-menu-separator"
|
|
145
|
+
className={cn('-mx-1 h-[length:var(--border-width)] bg-border', className)}
|
|
146
|
+
{...props}
|
|
147
|
+
/>
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function ContextMenuShortcut({ className, ...props }: React.ComponentProps<'span'>) {
|
|
152
|
+
return (
|
|
153
|
+
<span
|
|
154
|
+
data-slot="context-menu-shortcut"
|
|
155
|
+
className={cn('ml-auto text-xs tracking-widest text-muted-foreground', className)}
|
|
156
|
+
{...props}
|
|
157
|
+
/>
|
|
158
|
+
)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function ContextMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {
|
|
162
|
+
return <MenuPrimitive.SubmenuRoot data-slot="context-menu-sub" {...props} />
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function ContextMenuSubTrigger({
|
|
166
|
+
className,
|
|
167
|
+
children,
|
|
168
|
+
inset,
|
|
169
|
+
...props
|
|
170
|
+
}: MenuPrimitive.SubmenuTrigger.Props & { inset?: boolean }) {
|
|
171
|
+
return (
|
|
172
|
+
<MenuPrimitive.SubmenuTrigger
|
|
173
|
+
data-slot="context-menu-sub-trigger"
|
|
174
|
+
data-inset={inset}
|
|
175
|
+
className={cn(
|
|
176
|
+
"flex cursor-default items-center gap-2 rounded-[var(--radius)] px-2 py-2 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-inset:pl-7 data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
177
|
+
className,
|
|
178
|
+
)}
|
|
179
|
+
{...props}
|
|
180
|
+
>
|
|
181
|
+
{children}
|
|
182
|
+
<ChevronRightIcon className="ml-auto" />
|
|
183
|
+
</MenuPrimitive.SubmenuTrigger>
|
|
184
|
+
)
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function ContextMenuSubContent({ className, ...props }: React.ComponentProps<typeof ContextMenuContent>) {
|
|
188
|
+
return (
|
|
189
|
+
<ContextMenuContent
|
|
190
|
+
data-slot="context-menu-sub-content"
|
|
191
|
+
className={cn('w-auto min-w-[96px]', className)}
|
|
192
|
+
{...props}
|
|
193
|
+
/>
|
|
194
|
+
)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export {
|
|
198
|
+
ContextMenu,
|
|
199
|
+
ContextMenuTrigger,
|
|
200
|
+
ContextMenuPortal,
|
|
201
|
+
ContextMenuContent,
|
|
202
|
+
ContextMenuItem,
|
|
203
|
+
ContextMenuCheckboxItem,
|
|
204
|
+
ContextMenuRadioGroup,
|
|
205
|
+
ContextMenuRadioItem,
|
|
206
|
+
ContextMenuLabel,
|
|
207
|
+
ContextMenuSeparator,
|
|
208
|
+
ContextMenuShortcut,
|
|
209
|
+
ContextMenuSub,
|
|
210
|
+
ContextMenuSubTrigger,
|
|
211
|
+
ContextMenuSubContent,
|
|
212
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import { Dialog as DialogPrimitive } from '@base-ui/react/dialog'
|
|
4
|
+
import { XIcon } from 'lucide-react'
|
|
5
|
+
import type * as React from 'react'
|
|
6
|
+
import { Button } from '@/components/ui/button'
|
|
7
|
+
import { cn } from '@/lib/utils'
|
|
8
|
+
|
|
9
|
+
function Dialog({ ...props }: DialogPrimitive.Root.Props) {
|
|
10
|
+
return <DialogPrimitive.Root data-slot="dialog" {...props} />
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function DialogTrigger({ ...props }: DialogPrimitive.Trigger.Props) {
|
|
14
|
+
return <DialogPrimitive.Trigger data-slot="dialog-trigger" {...props} />
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function DialogPortal({ ...props }: DialogPrimitive.Portal.Props) {
|
|
18
|
+
return <DialogPrimitive.Portal data-slot="dialog-portal" {...props} />
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function DialogClose({ ...props }: DialogPrimitive.Close.Props) {
|
|
22
|
+
return <DialogPrimitive.Close data-slot="dialog-close" {...props} />
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function DialogOverlay({ className, ...props }: DialogPrimitive.Backdrop.Props) {
|
|
26
|
+
return (
|
|
27
|
+
<DialogPrimitive.Backdrop
|
|
28
|
+
data-slot="dialog-overlay"
|
|
29
|
+
className={cn(
|
|
30
|
+
'fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0',
|
|
31
|
+
className,
|
|
32
|
+
)}
|
|
33
|
+
{...props}
|
|
34
|
+
/>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function DialogContent({
|
|
39
|
+
className,
|
|
40
|
+
children,
|
|
41
|
+
showCloseButton = true,
|
|
42
|
+
...props
|
|
43
|
+
}: DialogPrimitive.Popup.Props & {
|
|
44
|
+
showCloseButton?: boolean
|
|
45
|
+
}) {
|
|
46
|
+
return (
|
|
47
|
+
<DialogPortal>
|
|
48
|
+
<DialogOverlay />
|
|
49
|
+
<DialogPrimitive.Popup
|
|
50
|
+
data-slot="dialog-content"
|
|
51
|
+
className={cn(
|
|
52
|
+
'fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-[var(--radius)] border-[length:var(--border-width)] border-foreground bg-card p-4 text-xs/relaxed text-card-foreground duration-100 outline-none sm:max-w-sm 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',
|
|
53
|
+
className,
|
|
54
|
+
)}
|
|
55
|
+
{...props}
|
|
56
|
+
>
|
|
57
|
+
{children}
|
|
58
|
+
{showCloseButton && (
|
|
59
|
+
<DialogPrimitive.Close
|
|
60
|
+
data-slot="dialog-close"
|
|
61
|
+
render={<Button variant="ghost" className="absolute top-2 right-2" size="icon" />}
|
|
62
|
+
>
|
|
63
|
+
<XIcon />
|
|
64
|
+
<span className="sr-only">Close</span>
|
|
65
|
+
</DialogPrimitive.Close>
|
|
66
|
+
)}
|
|
67
|
+
</DialogPrimitive.Popup>
|
|
68
|
+
</DialogPortal>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function DialogHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
73
|
+
return (
|
|
74
|
+
<div
|
|
75
|
+
data-slot="dialog-header"
|
|
76
|
+
className={cn('flex flex-col gap-1 text-left', className)}
|
|
77
|
+
{...props}
|
|
78
|
+
/>
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function DialogFooter({
|
|
83
|
+
className,
|
|
84
|
+
showCloseButton = false,
|
|
85
|
+
children,
|
|
86
|
+
...props
|
|
87
|
+
}: React.ComponentProps<'div'> & {
|
|
88
|
+
showCloseButton?: boolean
|
|
89
|
+
}) {
|
|
90
|
+
return (
|
|
91
|
+
<div
|
|
92
|
+
data-slot="dialog-footer"
|
|
93
|
+
className={cn('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end', className)}
|
|
94
|
+
{...props}
|
|
95
|
+
>
|
|
96
|
+
{children}
|
|
97
|
+
{showCloseButton && (
|
|
98
|
+
<DialogPrimitive.Close render={<Button variant="outline" />}>Close</DialogPrimitive.Close>
|
|
99
|
+
)}
|
|
100
|
+
</div>
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {
|
|
105
|
+
return (
|
|
106
|
+
<DialogPrimitive.Title
|
|
107
|
+
data-slot="dialog-title"
|
|
108
|
+
className={cn('text-sm font-medium', className)}
|
|
109
|
+
{...props}
|
|
110
|
+
/>
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function DialogDescription({ className, ...props }: DialogPrimitive.Description.Props) {
|
|
115
|
+
return (
|
|
116
|
+
<DialogPrimitive.Description
|
|
117
|
+
data-slot="dialog-description"
|
|
118
|
+
className={cn(
|
|
119
|
+
'text-xs/relaxed text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground',
|
|
120
|
+
className,
|
|
121
|
+
)}
|
|
122
|
+
{...props}
|
|
123
|
+
/>
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export {
|
|
128
|
+
Dialog,
|
|
129
|
+
DialogClose,
|
|
130
|
+
DialogContent,
|
|
131
|
+
DialogDescription,
|
|
132
|
+
DialogFooter,
|
|
133
|
+
DialogHeader,
|
|
134
|
+
DialogOverlay,
|
|
135
|
+
DialogPortal,
|
|
136
|
+
DialogTitle,
|
|
137
|
+
DialogTrigger,
|
|
138
|
+
}
|
|
@@ -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 DrawerSide = 'left' | 'right' | 'top' | 'bottom'
|
|
9
|
+
|
|
10
|
+
function Drawer({ ...props }: DialogPrimitive.Root.Props) {
|
|
11
|
+
return <DialogPrimitive.Root data-slot="drawer" {...props} />
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function DrawerTrigger({ ...props }: DialogPrimitive.Trigger.Props) {
|
|
15
|
+
return <DialogPrimitive.Trigger data-slot="drawer-trigger" {...props} />
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function DrawerClose({ ...props }: DialogPrimitive.Close.Props) {
|
|
19
|
+
return <DialogPrimitive.Close data-slot="drawer-close" {...props} />
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function DrawerPortal({ ...props }: DialogPrimitive.Portal.Props) {
|
|
23
|
+
return <DialogPrimitive.Portal data-slot="drawer-portal" {...props} />
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function DrawerOverlay({ className, ...props }: DialogPrimitive.Backdrop.Props) {
|
|
27
|
+
return (
|
|
28
|
+
<DialogPrimitive.Backdrop
|
|
29
|
+
data-slot="drawer-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 sideClasses: Record<DrawerSide, string> = {
|
|
40
|
+
left: 'inset-y-0 left-0 h-full w-3/4 max-w-sm border-r-[length:var(--border-width)] data-open:slide-in-from-left data-closed:slide-out-to-left',
|
|
41
|
+
right: 'inset-y-0 right-0 h-full w-3/4 max-w-sm border-l-[length:var(--border-width)] data-open:slide-in-from-right data-closed:slide-out-to-right',
|
|
42
|
+
top: 'inset-x-0 top-0 w-full border-b-[length:var(--border-width)] data-open:slide-in-from-top data-closed:slide-out-to-top',
|
|
43
|
+
bottom: 'inset-x-0 bottom-0 w-full border-t-[length:var(--border-width)] data-open:slide-in-from-bottom data-closed:slide-out-to-bottom',
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function DrawerContent({
|
|
47
|
+
className,
|
|
48
|
+
children,
|
|
49
|
+
side = 'right',
|
|
50
|
+
showCloseButton = true,
|
|
51
|
+
...props
|
|
52
|
+
}: DialogPrimitive.Popup.Props & {
|
|
53
|
+
side?: DrawerSide
|
|
54
|
+
showCloseButton?: boolean
|
|
55
|
+
}) {
|
|
56
|
+
return (
|
|
57
|
+
<DrawerPortal>
|
|
58
|
+
<DrawerOverlay />
|
|
59
|
+
<DialogPrimitive.Popup
|
|
60
|
+
data-slot="drawer-content"
|
|
61
|
+
className={cn(
|
|
62
|
+
'fixed z-50 flex flex-col gap-4 rounded-[var(--radius)] border-foreground bg-card p-4 text-xs/relaxed text-card-foreground duration-200 outline-none data-open:animate-in data-closed:animate-out data-closed:duration-200',
|
|
63
|
+
sideClasses[side],
|
|
64
|
+
className,
|
|
65
|
+
)}
|
|
66
|
+
{...props}
|
|
67
|
+
>
|
|
68
|
+
{showCloseButton && (
|
|
69
|
+
<DialogPrimitive.Close
|
|
70
|
+
data-slot="drawer-close"
|
|
71
|
+
className="absolute top-3 right-3 flex size-7 items-center justify-center text-muted-foreground hover:text-foreground"
|
|
72
|
+
aria-label="Close drawer"
|
|
73
|
+
>
|
|
74
|
+
<XIcon className="size-4" />
|
|
75
|
+
</DialogPrimitive.Close>
|
|
76
|
+
)}
|
|
77
|
+
{children}
|
|
78
|
+
</DialogPrimitive.Popup>
|
|
79
|
+
</DrawerPortal>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function DrawerHeader({ className, ...props }: React.ComponentProps<'div'>) {
|
|
84
|
+
return (
|
|
85
|
+
<div
|
|
86
|
+
data-slot="drawer-header"
|
|
87
|
+
className={cn('flex flex-col gap-1', className)}
|
|
88
|
+
{...props}
|
|
89
|
+
/>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function DrawerFooter({ className, ...props }: React.ComponentProps<'div'>) {
|
|
94
|
+
return (
|
|
95
|
+
<div
|
|
96
|
+
data-slot="drawer-footer"
|
|
97
|
+
className={cn('mt-auto flex flex-col gap-2', className)}
|
|
98
|
+
{...props}
|
|
99
|
+
/>
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function DrawerTitle({ className, ...props }: DialogPrimitive.Title.Props) {
|
|
104
|
+
return (
|
|
105
|
+
<DialogPrimitive.Title
|
|
106
|
+
data-slot="drawer-title"
|
|
107
|
+
className={cn('text-sm font-medium uppercase tracking-wider', className)}
|
|
108
|
+
{...props}
|
|
109
|
+
/>
|
|
110
|
+
)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function DrawerDescription({ className, ...props }: DialogPrimitive.Description.Props) {
|
|
114
|
+
return (
|
|
115
|
+
<DialogPrimitive.Description
|
|
116
|
+
data-slot="drawer-description"
|
|
117
|
+
className={cn('text-xs/relaxed text-muted-foreground', className)}
|
|
118
|
+
{...props}
|
|
119
|
+
/>
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export {
|
|
124
|
+
Drawer,
|
|
125
|
+
DrawerTrigger,
|
|
126
|
+
DrawerClose,
|
|
127
|
+
DrawerPortal,
|
|
128
|
+
DrawerOverlay,
|
|
129
|
+
DrawerContent,
|
|
130
|
+
DrawerHeader,
|
|
131
|
+
DrawerFooter,
|
|
132
|
+
DrawerTitle,
|
|
133
|
+
DrawerDescription,
|
|
134
|
+
}
|