@boyernick/standard-ui-react 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/README.md +9 -0
- package/package.json +46 -0
- package/src/accordion.tsx +84 -0
- package/src/alert-dialog.tsx +101 -0
- package/src/attachment.tsx +138 -0
- package/src/autocomplete.tsx +281 -0
- package/src/avatar.tsx +56 -0
- package/src/badge.tsx +28 -0
- package/src/brand.tsx +70 -0
- package/src/breadcrumb.tsx +81 -0
- package/src/button.tsx +129 -0
- package/src/calendar.tsx +84 -0
- package/src/card.tsx +54 -0
- package/src/carousel.tsx +253 -0
- package/src/chart.tsx +185 -0
- package/src/checkbox-group.tsx +14 -0
- package/src/checkbox.tsx +31 -0
- package/src/code-block.tsx +124 -0
- package/src/collapsible.tsx +61 -0
- package/src/combobox.tsx +324 -0
- package/src/command.tsx +377 -0
- package/src/context-menu.tsx +250 -0
- package/src/dialog.tsx +78 -0
- package/src/drawer.tsx +156 -0
- package/src/empty.tsx +52 -0
- package/src/field.tsx +75 -0
- package/src/fieldset.tsx +25 -0
- package/src/form.tsx +14 -0
- package/src/icons.tsx +91 -0
- package/src/illustrations.tsx +167 -0
- package/src/image-modal.tsx +110 -0
- package/src/index.ts +833 -0
- package/src/input.tsx +68 -0
- package/src/lib/cn.ts +3 -0
- package/src/lib/motion.ts +23 -0
- package/src/markdown-editor.tsx +302 -0
- package/src/menu.tsx +205 -0
- package/src/menubar.tsx +22 -0
- package/src/meter.tsx +61 -0
- package/src/navigation-menu.tsx +217 -0
- package/src/number-field.tsx +119 -0
- package/src/orb.tsx +33 -0
- package/src/otp-field.tsx +45 -0
- package/src/pagination.tsx +91 -0
- package/src/popover.tsx +92 -0
- package/src/preview-card.tsx +103 -0
- package/src/progress.tsx +60 -0
- package/src/radio.tsx +43 -0
- package/src/scroll-area.tsx +67 -0
- package/src/select.tsx +161 -0
- package/src/separator.tsx +17 -0
- package/src/sidebar.tsx +82 -0
- package/src/skeleton.tsx +32 -0
- package/src/slider.tsx +56 -0
- package/src/sounds.tsx +270 -0
- package/src/spinner.tsx +45 -0
- package/src/switch.tsx +19 -0
- package/src/table.tsx +81 -0
- package/src/tabs.tsx +62 -0
- package/src/text-animate.tsx +155 -0
- package/src/textarea.tsx +58 -0
- package/src/ticker.tsx +74 -0
- package/src/toast.tsx +142 -0
- package/src/toggle.tsx +32 -0
- package/src/toolbar.tsx +75 -0
- package/src/tooltip.tsx +55 -0
- package/src/video-player.tsx +241 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { ContextMenu as BaseContextMenu } from "@base-ui/react/context-menu"
|
|
4
|
+
import type { ComponentProps } from "react"
|
|
5
|
+
import { IconCheckmark1, IconChevronRightSmall } from "./icons"
|
|
6
|
+
import { cn } from "./lib/cn"
|
|
7
|
+
import { motion } from "./lib/motion"
|
|
8
|
+
|
|
9
|
+
export type ContextMenuProps = ComponentProps<typeof BaseContextMenu.Root>
|
|
10
|
+
export type ContextMenuTriggerProps = ComponentProps<
|
|
11
|
+
typeof BaseContextMenu.Trigger
|
|
12
|
+
>
|
|
13
|
+
export type ContextMenuPortalProps = ComponentProps<typeof BaseContextMenu.Portal>
|
|
14
|
+
export type ContextMenuBackdropProps = ComponentProps<
|
|
15
|
+
typeof BaseContextMenu.Backdrop
|
|
16
|
+
>
|
|
17
|
+
export type ContextMenuPositionerProps = ComponentProps<
|
|
18
|
+
typeof BaseContextMenu.Positioner
|
|
19
|
+
>
|
|
20
|
+
export type ContextMenuPopupProps = ComponentProps<typeof BaseContextMenu.Popup>
|
|
21
|
+
export type ContextMenuArrowProps = ComponentProps<typeof BaseContextMenu.Arrow>
|
|
22
|
+
export type ContextMenuItemProps = ComponentProps<typeof BaseContextMenu.Item>
|
|
23
|
+
export type ContextMenuLinkItemProps = ComponentProps<
|
|
24
|
+
typeof BaseContextMenu.LinkItem
|
|
25
|
+
>
|
|
26
|
+
export type ContextMenuSeparatorProps = ComponentProps<
|
|
27
|
+
typeof BaseContextMenu.Separator
|
|
28
|
+
>
|
|
29
|
+
export type ContextMenuGroupProps = ComponentProps<typeof BaseContextMenu.Group>
|
|
30
|
+
export type ContextMenuGroupLabelProps = ComponentProps<
|
|
31
|
+
typeof BaseContextMenu.GroupLabel
|
|
32
|
+
>
|
|
33
|
+
export type ContextMenuCheckboxItemProps = ComponentProps<
|
|
34
|
+
typeof BaseContextMenu.CheckboxItem
|
|
35
|
+
>
|
|
36
|
+
export type ContextMenuCheckboxItemIndicatorProps = ComponentProps<
|
|
37
|
+
typeof BaseContextMenu.CheckboxItemIndicator
|
|
38
|
+
>
|
|
39
|
+
export type ContextMenuRadioGroupProps = ComponentProps<
|
|
40
|
+
typeof BaseContextMenu.RadioGroup
|
|
41
|
+
>
|
|
42
|
+
export type ContextMenuRadioItemProps = ComponentProps<
|
|
43
|
+
typeof BaseContextMenu.RadioItem
|
|
44
|
+
>
|
|
45
|
+
export type ContextMenuRadioItemIndicatorProps = ComponentProps<
|
|
46
|
+
typeof BaseContextMenu.RadioItemIndicator
|
|
47
|
+
>
|
|
48
|
+
export type ContextMenuSubmenuRootProps = ComponentProps<
|
|
49
|
+
typeof BaseContextMenu.SubmenuRoot
|
|
50
|
+
>
|
|
51
|
+
export type ContextMenuSubmenuTriggerProps = ComponentProps<
|
|
52
|
+
typeof BaseContextMenu.SubmenuTrigger
|
|
53
|
+
>
|
|
54
|
+
|
|
55
|
+
const itemClassName = cn(
|
|
56
|
+
"flex min-h-8 cursor-default items-center gap-2 rounded-xs px-2.5 py-1.5 text-sm text-fg-primary outline-none select-none",
|
|
57
|
+
motion.colors,
|
|
58
|
+
"data-disabled:cursor-not-allowed data-disabled:opacity-50 data-highlighted:bg-background-tertiary",
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
const indicatorItemClassName = cn(itemClassName, "pl-2")
|
|
62
|
+
const indicatorClassName =
|
|
63
|
+
"mr-0.5 flex size-4 shrink-0 items-center justify-center text-fg-primary data-unchecked:invisible"
|
|
64
|
+
|
|
65
|
+
export const ContextMenu = (props: ContextMenuProps) => (
|
|
66
|
+
<BaseContextMenu.Root {...props} />
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
export const ContextMenuTrigger = ({
|
|
70
|
+
className,
|
|
71
|
+
...props
|
|
72
|
+
}: ContextMenuTriggerProps) => (
|
|
73
|
+
<BaseContextMenu.Trigger className={cn(className)} {...props} />
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
export const ContextMenuPortal = (props: ContextMenuPortalProps) => (
|
|
77
|
+
<BaseContextMenu.Portal {...props} />
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
export const ContextMenuBackdrop = ({
|
|
81
|
+
className,
|
|
82
|
+
...props
|
|
83
|
+
}: ContextMenuBackdropProps) => (
|
|
84
|
+
<BaseContextMenu.Backdrop className={cn(className)} {...props} />
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
export const ContextMenuPositioner = ({
|
|
88
|
+
className,
|
|
89
|
+
...props
|
|
90
|
+
}: ContextMenuPositionerProps) => (
|
|
91
|
+
<BaseContextMenu.Positioner
|
|
92
|
+
className={cn("z-50 outline-none", className)}
|
|
93
|
+
{...props}
|
|
94
|
+
/>
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
export const ContextMenuPopup = ({
|
|
98
|
+
className,
|
|
99
|
+
...props
|
|
100
|
+
}: ContextMenuPopupProps) => (
|
|
101
|
+
<BaseContextMenu.Popup
|
|
102
|
+
className={cn(
|
|
103
|
+
"z-50 min-w-40 overflow-hidden rounded-md border border-border-primary bg-surface p-1 shadow-md outline-none",
|
|
104
|
+
motion.popupAnchor,
|
|
105
|
+
className,
|
|
106
|
+
)}
|
|
107
|
+
{...props}
|
|
108
|
+
/>
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
export const ContextMenuArrow = ({
|
|
112
|
+
className,
|
|
113
|
+
...props
|
|
114
|
+
}: ContextMenuArrowProps) => (
|
|
115
|
+
<BaseContextMenu.Arrow
|
|
116
|
+
className={cn(
|
|
117
|
+
"data-[side=bottom]:top-[-6px] data-[side=left]:right-[-6px] data-[side=right]:left-[-6px] data-[side=top]:bottom-[-6px]",
|
|
118
|
+
"size-2.5 rotate-45 border border-border-primary bg-surface",
|
|
119
|
+
"data-[side=bottom]:border-r-0 data-[side=bottom]:border-b-0",
|
|
120
|
+
"data-[side=top]:border-t-0 data-[side=top]:border-l-0",
|
|
121
|
+
"data-[side=left]:border-b-0 data-[side=left]:border-l-0",
|
|
122
|
+
"data-[side=right]:border-t-0 data-[side=right]:border-r-0",
|
|
123
|
+
className,
|
|
124
|
+
)}
|
|
125
|
+
{...props}
|
|
126
|
+
/>
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
export const ContextMenuItem = ({
|
|
130
|
+
className,
|
|
131
|
+
...props
|
|
132
|
+
}: ContextMenuItemProps) => (
|
|
133
|
+
<BaseContextMenu.Item className={cn(itemClassName, className)} {...props} />
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
export const ContextMenuLinkItem = ({
|
|
137
|
+
className,
|
|
138
|
+
...props
|
|
139
|
+
}: ContextMenuLinkItemProps) => (
|
|
140
|
+
<BaseContextMenu.LinkItem
|
|
141
|
+
className={cn(itemClassName, "cursor-pointer", className)}
|
|
142
|
+
{...props}
|
|
143
|
+
/>
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
export const ContextMenuSeparator = ({
|
|
147
|
+
className,
|
|
148
|
+
...props
|
|
149
|
+
}: ContextMenuSeparatorProps) => (
|
|
150
|
+
<BaseContextMenu.Separator
|
|
151
|
+
className={cn("my-1 h-px bg-border-primary", className)}
|
|
152
|
+
{...props}
|
|
153
|
+
/>
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
export const ContextMenuGroup = ({
|
|
157
|
+
className,
|
|
158
|
+
...props
|
|
159
|
+
}: ContextMenuGroupProps) => (
|
|
160
|
+
<BaseContextMenu.Group className={cn(className)} {...props} />
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
export const ContextMenuGroupLabel = ({
|
|
164
|
+
className,
|
|
165
|
+
...props
|
|
166
|
+
}: ContextMenuGroupLabelProps) => (
|
|
167
|
+
<BaseContextMenu.GroupLabel
|
|
168
|
+
className={cn("px-2.5 py-1.5 text-xs text-fg-tertiary", className)}
|
|
169
|
+
{...props}
|
|
170
|
+
/>
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
export const ContextMenuCheckboxItem = ({
|
|
174
|
+
className,
|
|
175
|
+
...props
|
|
176
|
+
}: ContextMenuCheckboxItemProps) => (
|
|
177
|
+
<BaseContextMenu.CheckboxItem
|
|
178
|
+
className={cn(indicatorItemClassName, className)}
|
|
179
|
+
{...props}
|
|
180
|
+
/>
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
export const ContextMenuCheckboxItemIndicator = ({
|
|
184
|
+
className,
|
|
185
|
+
children,
|
|
186
|
+
keepMounted = true,
|
|
187
|
+
...props
|
|
188
|
+
}: ContextMenuCheckboxItemIndicatorProps) => (
|
|
189
|
+
<BaseContextMenu.CheckboxItemIndicator
|
|
190
|
+
keepMounted={keepMounted}
|
|
191
|
+
className={cn(indicatorClassName, className)}
|
|
192
|
+
{...props}
|
|
193
|
+
>
|
|
194
|
+
{children ?? <IconCheckmark1 size={14} className="size-3.5" aria-hidden />}
|
|
195
|
+
</BaseContextMenu.CheckboxItemIndicator>
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
export const ContextMenuRadioGroup = ({
|
|
199
|
+
className,
|
|
200
|
+
...props
|
|
201
|
+
}: ContextMenuRadioGroupProps) => (
|
|
202
|
+
<BaseContextMenu.RadioGroup className={cn(className)} {...props} />
|
|
203
|
+
)
|
|
204
|
+
|
|
205
|
+
export const ContextMenuRadioItem = ({
|
|
206
|
+
className,
|
|
207
|
+
...props
|
|
208
|
+
}: ContextMenuRadioItemProps) => (
|
|
209
|
+
<BaseContextMenu.RadioItem
|
|
210
|
+
className={cn(indicatorItemClassName, className)}
|
|
211
|
+
{...props}
|
|
212
|
+
/>
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
export const ContextMenuRadioItemIndicator = ({
|
|
216
|
+
className,
|
|
217
|
+
children,
|
|
218
|
+
keepMounted = true,
|
|
219
|
+
...props
|
|
220
|
+
}: ContextMenuRadioItemIndicatorProps) => (
|
|
221
|
+
<BaseContextMenu.RadioItemIndicator
|
|
222
|
+
keepMounted={keepMounted}
|
|
223
|
+
className={cn(indicatorClassName, className)}
|
|
224
|
+
{...props}
|
|
225
|
+
>
|
|
226
|
+
{children ?? <IconCheckmark1 size={14} className="size-3.5" aria-hidden />}
|
|
227
|
+
</BaseContextMenu.RadioItemIndicator>
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
export const ContextMenuSubmenuRoot = (props: ContextMenuSubmenuRootProps) => (
|
|
231
|
+
<BaseContextMenu.SubmenuRoot {...props} />
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
export const ContextMenuSubmenuTrigger = ({
|
|
235
|
+
className,
|
|
236
|
+
children,
|
|
237
|
+
...props
|
|
238
|
+
}: ContextMenuSubmenuTriggerProps) => (
|
|
239
|
+
<BaseContextMenu.SubmenuTrigger
|
|
240
|
+
className={cn(itemClassName, "w-full justify-between", className)}
|
|
241
|
+
{...props}
|
|
242
|
+
>
|
|
243
|
+
{children}
|
|
244
|
+
<IconChevronRightSmall
|
|
245
|
+
size={16}
|
|
246
|
+
className="size-4 text-fg-tertiary"
|
|
247
|
+
aria-hidden
|
|
248
|
+
/>
|
|
249
|
+
</BaseContextMenu.SubmenuTrigger>
|
|
250
|
+
)
|
package/src/dialog.tsx
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { Dialog as BaseDialog } from "@base-ui/react/dialog"
|
|
4
|
+
import type { ComponentProps, HTMLAttributes } from "react"
|
|
5
|
+
import { cn } from "./lib/cn"
|
|
6
|
+
import { motion } from "./lib/motion"
|
|
7
|
+
|
|
8
|
+
export type DialogProps = ComponentProps<typeof BaseDialog.Root>
|
|
9
|
+
export type DialogTriggerProps = ComponentProps<typeof BaseDialog.Trigger>
|
|
10
|
+
export type DialogPortalProps = ComponentProps<typeof BaseDialog.Portal>
|
|
11
|
+
export type DialogBackdropProps = ComponentProps<typeof BaseDialog.Backdrop>
|
|
12
|
+
export type DialogPopupProps = ComponentProps<typeof BaseDialog.Popup>
|
|
13
|
+
export type DialogTitleProps = ComponentProps<typeof BaseDialog.Title>
|
|
14
|
+
export type DialogDescriptionProps = ComponentProps<
|
|
15
|
+
typeof BaseDialog.Description
|
|
16
|
+
>
|
|
17
|
+
export type DialogCloseProps = ComponentProps<typeof BaseDialog.Close>
|
|
18
|
+
export type DialogHeaderProps = HTMLAttributes<HTMLDivElement>
|
|
19
|
+
|
|
20
|
+
export const Dialog = (props: DialogProps) => <BaseDialog.Root {...props} />
|
|
21
|
+
|
|
22
|
+
export const DialogTrigger = ({ className, ...props }: DialogTriggerProps) => (
|
|
23
|
+
<BaseDialog.Trigger className={cn(className)} {...props} />
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
export const DialogPortal = (props: DialogPortalProps) => (
|
|
27
|
+
<BaseDialog.Portal {...props} />
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
export const DialogBackdrop = ({
|
|
31
|
+
className,
|
|
32
|
+
...props
|
|
33
|
+
}: DialogBackdropProps) => (
|
|
34
|
+
<BaseDialog.Backdrop
|
|
35
|
+
className={cn(
|
|
36
|
+
"fixed inset-0 z-50 bg-black/40 dark:bg-black/60",
|
|
37
|
+
motion.backdrop,
|
|
38
|
+
className,
|
|
39
|
+
)}
|
|
40
|
+
{...props}
|
|
41
|
+
/>
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
export const DialogPopup = ({ className, ...props }: DialogPopupProps) => (
|
|
45
|
+
<BaseDialog.Popup
|
|
46
|
+
className={cn(
|
|
47
|
+
"fixed top-1/2 left-1/2 z-50 flex w-full max-w-md -translate-x-1/2 -translate-y-1/2 flex-col gap-6 rounded-xl border border-border-primary bg-surface-raised p-5 shadow-md outline-none max-sm:max-w-[calc(100vw-2rem)]",
|
|
48
|
+
motion.popupCenter,
|
|
49
|
+
className,
|
|
50
|
+
)}
|
|
51
|
+
{...props}
|
|
52
|
+
/>
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
export const DialogTitle = ({ className, ...props }: DialogTitleProps) => (
|
|
56
|
+
<BaseDialog.Title
|
|
57
|
+
className={cn("text-sm-strong text-fg-primary", className)}
|
|
58
|
+
{...props}
|
|
59
|
+
/>
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
export const DialogDescription = ({
|
|
63
|
+
className,
|
|
64
|
+
...props
|
|
65
|
+
}: DialogDescriptionProps) => (
|
|
66
|
+
<BaseDialog.Description
|
|
67
|
+
className={cn("text-sm leading-relaxed text-fg-secondary", className)}
|
|
68
|
+
{...props}
|
|
69
|
+
/>
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
export const DialogClose = ({ className, ...props }: DialogCloseProps) => (
|
|
73
|
+
<BaseDialog.Close className={cn(className)} {...props} />
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
export const DialogHeader = ({ className, ...props }: DialogHeaderProps) => (
|
|
77
|
+
<div className={cn("flex flex-col gap-1", className)} {...props} />
|
|
78
|
+
)
|
package/src/drawer.tsx
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { Drawer as BaseDrawer } from "@base-ui/react/drawer"
|
|
4
|
+
import type { ComponentProps, HTMLAttributes } from "react"
|
|
5
|
+
import { cn } from "./lib/cn"
|
|
6
|
+
import { motion } from "./lib/motion"
|
|
7
|
+
|
|
8
|
+
export type DrawerProps = ComponentProps<typeof BaseDrawer.Root>
|
|
9
|
+
export type DrawerProviderProps = ComponentProps<typeof BaseDrawer.Provider>
|
|
10
|
+
export type DrawerTriggerProps = ComponentProps<typeof BaseDrawer.Trigger>
|
|
11
|
+
export type DrawerPortalProps = ComponentProps<typeof BaseDrawer.Portal>
|
|
12
|
+
export type DrawerBackdropProps = ComponentProps<typeof BaseDrawer.Backdrop>
|
|
13
|
+
export type DrawerViewportProps = ComponentProps<typeof BaseDrawer.Viewport>
|
|
14
|
+
export type DrawerPopupProps = ComponentProps<typeof BaseDrawer.Popup>
|
|
15
|
+
export type DrawerContentProps = ComponentProps<typeof BaseDrawer.Content>
|
|
16
|
+
export type DrawerTitleProps = ComponentProps<typeof BaseDrawer.Title>
|
|
17
|
+
export type DrawerDescriptionProps = ComponentProps<
|
|
18
|
+
typeof BaseDrawer.Description
|
|
19
|
+
>
|
|
20
|
+
export type DrawerCloseProps = ComponentProps<typeof BaseDrawer.Close>
|
|
21
|
+
export type DrawerSwipeAreaProps = ComponentProps<typeof BaseDrawer.SwipeArea>
|
|
22
|
+
export type DrawerIndentProps = ComponentProps<typeof BaseDrawer.Indent>
|
|
23
|
+
export type DrawerIndentBackgroundProps = ComponentProps<
|
|
24
|
+
typeof BaseDrawer.IndentBackground
|
|
25
|
+
>
|
|
26
|
+
export type DrawerHeaderProps = HTMLAttributes<HTMLDivElement>
|
|
27
|
+
|
|
28
|
+
export const Drawer = (props: DrawerProps) => <BaseDrawer.Root {...props} />
|
|
29
|
+
|
|
30
|
+
export const DrawerProvider = (props: DrawerProviderProps) => (
|
|
31
|
+
<BaseDrawer.Provider {...props} />
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
export const DrawerTrigger = ({ className, ...props }: DrawerTriggerProps) => (
|
|
35
|
+
<BaseDrawer.Trigger className={cn("cursor-pointer", className)} {...props} />
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
export const DrawerPortal = (props: DrawerPortalProps) => (
|
|
39
|
+
<BaseDrawer.Portal {...props} />
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
export const DrawerBackdrop = ({
|
|
43
|
+
className,
|
|
44
|
+
...props
|
|
45
|
+
}: DrawerBackdropProps) => (
|
|
46
|
+
<BaseDrawer.Backdrop
|
|
47
|
+
className={cn(
|
|
48
|
+
"fixed inset-0 z-50 bg-black/40 dark:bg-black/60",
|
|
49
|
+
motion.backdrop,
|
|
50
|
+
"data-swiping:duration-0",
|
|
51
|
+
"opacity-[calc(1-var(--drawer-swipe-progress,0))]",
|
|
52
|
+
className,
|
|
53
|
+
)}
|
|
54
|
+
{...props}
|
|
55
|
+
/>
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
export const DrawerViewport = ({
|
|
59
|
+
className,
|
|
60
|
+
...props
|
|
61
|
+
}: DrawerViewportProps) => (
|
|
62
|
+
<BaseDrawer.Viewport
|
|
63
|
+
className={cn("fixed inset-0 z-50", className)}
|
|
64
|
+
{...props}
|
|
65
|
+
/>
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
export const DrawerPopup = ({ className, ...props }: DrawerPopupProps) => (
|
|
69
|
+
<BaseDrawer.Popup
|
|
70
|
+
className={cn(
|
|
71
|
+
"fixed z-50 flex flex-col border-border-primary bg-surface shadow-md outline-none",
|
|
72
|
+
"transition-[transform,opacity] duration-300 ease-[cubic-bezier(0.22,1,0.36,1)] motion-reduce:transition-none",
|
|
73
|
+
"data-swiping:duration-0",
|
|
74
|
+
// Right panel (swipeDirection="right")
|
|
75
|
+
"data-[swipe-direction=right]:top-0 data-[swipe-direction=right]:right-0 data-[swipe-direction=right]:h-full data-[swipe-direction=right]:w-full data-[swipe-direction=right]:max-w-sm data-[swipe-direction=right]:border-l",
|
|
76
|
+
"data-[swipe-direction=right]:translate-x-[var(--drawer-swipe-movement-x)]",
|
|
77
|
+
"data-[swipe-direction=right]:data-starting-style:translate-x-full",
|
|
78
|
+
"data-[swipe-direction=right]:data-ending-style:translate-x-full",
|
|
79
|
+
// Left panel
|
|
80
|
+
"data-[swipe-direction=left]:top-0 data-[swipe-direction=left]:left-0 data-[swipe-direction=left]:h-full data-[swipe-direction=left]:w-full data-[swipe-direction=left]:max-w-sm data-[swipe-direction=left]:border-r",
|
|
81
|
+
"data-[swipe-direction=left]:translate-x-[var(--drawer-swipe-movement-x)]",
|
|
82
|
+
"data-[swipe-direction=left]:data-starting-style:translate-x-[-100%]",
|
|
83
|
+
"data-[swipe-direction=left]:data-ending-style:translate-x-[-100%]",
|
|
84
|
+
// Bottom sheet (default swipeDirection="down")
|
|
85
|
+
"data-[swipe-direction=down]:right-0 data-[swipe-direction=down]:bottom-0 data-[swipe-direction=down]:left-0 data-[swipe-direction=down]:max-h-[85vh] data-[swipe-direction=down]:rounded-t-xl data-[swipe-direction=down]:border-t",
|
|
86
|
+
"data-[swipe-direction=down]:translate-y-[calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-movement-y))]",
|
|
87
|
+
"data-[swipe-direction=down]:data-starting-style:translate-y-full",
|
|
88
|
+
"data-[swipe-direction=down]:data-ending-style:translate-y-full",
|
|
89
|
+
// Top sheet
|
|
90
|
+
"data-[swipe-direction=up]:top-0 data-[swipe-direction=up]:right-0 data-[swipe-direction=up]:left-0 data-[swipe-direction=up]:max-h-[85vh] data-[swipe-direction=up]:rounded-b-xl data-[swipe-direction=up]:border-b",
|
|
91
|
+
"data-[swipe-direction=up]:translate-y-[var(--drawer-swipe-movement-y)]",
|
|
92
|
+
"data-[swipe-direction=up]:data-starting-style:translate-y-[-100%]",
|
|
93
|
+
"data-[swipe-direction=up]:data-ending-style:translate-y-[-100%]",
|
|
94
|
+
className,
|
|
95
|
+
)}
|
|
96
|
+
{...props}
|
|
97
|
+
/>
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
export const DrawerContent = ({
|
|
101
|
+
className,
|
|
102
|
+
...props
|
|
103
|
+
}: DrawerContentProps) => (
|
|
104
|
+
<BaseDrawer.Content
|
|
105
|
+
className={cn(
|
|
106
|
+
"flex min-h-0 flex-1 flex-col gap-6 overflow-y-auto p-5 outline-none",
|
|
107
|
+
className,
|
|
108
|
+
)}
|
|
109
|
+
{...props}
|
|
110
|
+
/>
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
export const DrawerTitle = ({ className, ...props }: DrawerTitleProps) => (
|
|
114
|
+
<BaseDrawer.Title
|
|
115
|
+
className={cn("text-sm-strong text-fg-primary", className)}
|
|
116
|
+
{...props}
|
|
117
|
+
/>
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
export const DrawerDescription = ({
|
|
121
|
+
className,
|
|
122
|
+
...props
|
|
123
|
+
}: DrawerDescriptionProps) => (
|
|
124
|
+
<BaseDrawer.Description
|
|
125
|
+
className={cn("text-sm leading-relaxed text-fg-secondary", className)}
|
|
126
|
+
{...props}
|
|
127
|
+
/>
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
export const DrawerClose = ({ className, ...props }: DrawerCloseProps) => (
|
|
131
|
+
<BaseDrawer.Close className={cn("cursor-pointer", className)} {...props} />
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
export const DrawerSwipeArea = ({
|
|
135
|
+
className,
|
|
136
|
+
...props
|
|
137
|
+
}: DrawerSwipeAreaProps) => (
|
|
138
|
+
<BaseDrawer.SwipeArea className={cn(className)} {...props} />
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
export const DrawerIndent = ({ className, ...props }: DrawerIndentProps) => (
|
|
142
|
+
<BaseDrawer.Indent className={cn(className)} {...props} />
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
export const DrawerIndentBackground = ({
|
|
146
|
+
className,
|
|
147
|
+
...props
|
|
148
|
+
}: DrawerIndentBackgroundProps) => (
|
|
149
|
+
<BaseDrawer.IndentBackground className={cn(className)} {...props} />
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
export const DrawerHeader = ({ className, ...props }: DrawerHeaderProps) => (
|
|
153
|
+
<div className={cn("flex flex-col gap-1", className)} {...props} />
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
export const createDrawerHandle = BaseDrawer.createHandle
|
package/src/empty.tsx
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ComponentProps } from "react";
|
|
2
|
+
import { cn } from "./lib/cn";
|
|
3
|
+
|
|
4
|
+
export type EmptyProps = ComponentProps<"div">;
|
|
5
|
+
export type EmptyIconProps = ComponentProps<"div">;
|
|
6
|
+
export type EmptyTitleProps = ComponentProps<"h3">;
|
|
7
|
+
export type EmptyDescriptionProps = ComponentProps<"p">;
|
|
8
|
+
export type EmptyActionsProps = ComponentProps<"div">;
|
|
9
|
+
|
|
10
|
+
export const Empty = ({ className, ...props }: EmptyProps) => (
|
|
11
|
+
<div
|
|
12
|
+
className={cn(
|
|
13
|
+
"flex min-h-48 flex-col items-center justify-center gap-3 rounded-xl border border-dashed border-border-primary bg-surface p-8 text-center",
|
|
14
|
+
className,
|
|
15
|
+
)}
|
|
16
|
+
{...props}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
export const EmptyIcon = ({ className, ...props }: EmptyIconProps) => (
|
|
21
|
+
<div
|
|
22
|
+
className={cn(
|
|
23
|
+
"flex size-10 items-center justify-center rounded-lg bg-background-tertiary text-fg-secondary [&_svg]:size-5",
|
|
24
|
+
className,
|
|
25
|
+
)}
|
|
26
|
+
{...props}
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
export const EmptyTitle = ({ className, ...props }: EmptyTitleProps) => (
|
|
31
|
+
<h3 className={cn("text-sm-strong text-fg-primary", className)} {...props} />
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
export const EmptyDescription = ({
|
|
35
|
+
className,
|
|
36
|
+
...props
|
|
37
|
+
}: EmptyDescriptionProps) => (
|
|
38
|
+
<p
|
|
39
|
+
className={cn("max-w-sm text-sm text-fg-secondary", className)}
|
|
40
|
+
{...props}
|
|
41
|
+
/>
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
export const EmptyActions = ({ className, ...props }: EmptyActionsProps) => (
|
|
45
|
+
<div
|
|
46
|
+
className={cn(
|
|
47
|
+
"mt-1 flex flex-wrap items-center justify-center gap-2",
|
|
48
|
+
className,
|
|
49
|
+
)}
|
|
50
|
+
{...props}
|
|
51
|
+
/>
|
|
52
|
+
);
|
package/src/field.tsx
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { Field as BaseField } from "@base-ui/react/field"
|
|
4
|
+
import type { ComponentProps } from "react"
|
|
5
|
+
import { cn } from "./lib/cn"
|
|
6
|
+
|
|
7
|
+
export type FieldProps = ComponentProps<typeof BaseField.Root>
|
|
8
|
+
export type FieldLabelProps = ComponentProps<typeof BaseField.Label>
|
|
9
|
+
export type FieldDescriptionProps = ComponentProps<typeof BaseField.Description>
|
|
10
|
+
export type FieldErrorProps = ComponentProps<typeof BaseField.Error>
|
|
11
|
+
export type FieldControlProps = ComponentProps<typeof BaseField.Control>
|
|
12
|
+
export type FieldValidityProps = ComponentProps<typeof BaseField.Validity>
|
|
13
|
+
export type FieldItemProps = ComponentProps<typeof BaseField.Item>
|
|
14
|
+
|
|
15
|
+
export const Field = ({ className, ...props }: FieldProps) => (
|
|
16
|
+
<BaseField.Root
|
|
17
|
+
className={cn("flex w-full flex-col gap-1.5", className)}
|
|
18
|
+
{...props}
|
|
19
|
+
/>
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
export const FieldLabel = ({ className, ...props }: FieldLabelProps) => (
|
|
23
|
+
<BaseField.Label
|
|
24
|
+
className={cn(
|
|
25
|
+
"text-sm text-fg-primary data-disabled:opacity-50",
|
|
26
|
+
className,
|
|
27
|
+
)}
|
|
28
|
+
{...props}
|
|
29
|
+
/>
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
export const FieldDescription = ({
|
|
33
|
+
className,
|
|
34
|
+
...props
|
|
35
|
+
}: FieldDescriptionProps) => (
|
|
36
|
+
<BaseField.Description
|
|
37
|
+
className={cn("text-xs text-fg-tertiary data-disabled:opacity-50", className)}
|
|
38
|
+
{...props}
|
|
39
|
+
/>
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
export const FieldError = ({ className, ...props }: FieldErrorProps) => (
|
|
43
|
+
<BaseField.Error
|
|
44
|
+
className={cn("text-xs text-destructive", className)}
|
|
45
|
+
{...props}
|
|
46
|
+
/>
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
export const FieldControl = ({ className, ...props }: FieldControlProps) => (
|
|
50
|
+
<BaseField.Control
|
|
51
|
+
className={cn(
|
|
52
|
+
"text-sm flex h-9 w-full cursor-text rounded-md border border-border-secondary bg-surface px-3 text-fg-primary inset-shadow-outline-top outline-none transition-[color,box-shadow] duration-150 ease-out placeholder:text-fg-quaternary",
|
|
53
|
+
"focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-ring/20",
|
|
54
|
+
"data-invalid:border-destructive data-invalid:focus-visible:border-destructive data-invalid:focus-visible:ring-destructive/20",
|
|
55
|
+
"aria-invalid:border-destructive aria-invalid:focus-visible:border-destructive aria-invalid:focus-visible:ring-destructive/20",
|
|
56
|
+
"data-disabled:cursor-not-allowed data-disabled:opacity-50",
|
|
57
|
+
className,
|
|
58
|
+
)}
|
|
59
|
+
{...props}
|
|
60
|
+
/>
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
export const FieldValidity = (props: FieldValidityProps) => (
|
|
64
|
+
<BaseField.Validity {...props} />
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
export const FieldItem = ({ className, ...props }: FieldItemProps) => (
|
|
68
|
+
<BaseField.Item
|
|
69
|
+
className={cn(
|
|
70
|
+
"flex items-center gap-2 data-disabled:opacity-50",
|
|
71
|
+
className,
|
|
72
|
+
)}
|
|
73
|
+
{...props}
|
|
74
|
+
/>
|
|
75
|
+
)
|
package/src/fieldset.tsx
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { Fieldset as BaseFieldset } from "@base-ui/react/fieldset"
|
|
4
|
+
import type { ComponentProps } from "react"
|
|
5
|
+
import { cn } from "./lib/cn"
|
|
6
|
+
|
|
7
|
+
export type FieldsetProps = ComponentProps<typeof BaseFieldset.Root>
|
|
8
|
+
export type FieldsetLegendProps = ComponentProps<typeof BaseFieldset.Legend>
|
|
9
|
+
|
|
10
|
+
export const Fieldset = ({ className, ...props }: FieldsetProps) => (
|
|
11
|
+
<BaseFieldset.Root
|
|
12
|
+
className={cn("flex w-full flex-col gap-3 border-0 p-0", className)}
|
|
13
|
+
{...props}
|
|
14
|
+
/>
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
export const FieldsetLegend = ({
|
|
18
|
+
className,
|
|
19
|
+
...props
|
|
20
|
+
}: FieldsetLegendProps) => (
|
|
21
|
+
<BaseFieldset.Legend
|
|
22
|
+
className={cn("text-sm text-fg-primary", className)}
|
|
23
|
+
{...props}
|
|
24
|
+
/>
|
|
25
|
+
)
|
package/src/form.tsx
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { Form as BaseForm } from "@base-ui/react/form"
|
|
4
|
+
import type { ComponentProps } from "react"
|
|
5
|
+
import { cn } from "./lib/cn"
|
|
6
|
+
|
|
7
|
+
export type FormProps = ComponentProps<typeof BaseForm>
|
|
8
|
+
|
|
9
|
+
export const Form = ({ className, ...props }: FormProps) => (
|
|
10
|
+
<BaseForm
|
|
11
|
+
className={cn("flex w-full flex-col gap-4", className)}
|
|
12
|
+
{...props}
|
|
13
|
+
/>
|
|
14
|
+
)
|