@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.
Files changed (67) hide show
  1. package/README.md +9 -0
  2. package/package.json +46 -0
  3. package/src/accordion.tsx +84 -0
  4. package/src/alert-dialog.tsx +101 -0
  5. package/src/attachment.tsx +138 -0
  6. package/src/autocomplete.tsx +281 -0
  7. package/src/avatar.tsx +56 -0
  8. package/src/badge.tsx +28 -0
  9. package/src/brand.tsx +70 -0
  10. package/src/breadcrumb.tsx +81 -0
  11. package/src/button.tsx +129 -0
  12. package/src/calendar.tsx +84 -0
  13. package/src/card.tsx +54 -0
  14. package/src/carousel.tsx +253 -0
  15. package/src/chart.tsx +185 -0
  16. package/src/checkbox-group.tsx +14 -0
  17. package/src/checkbox.tsx +31 -0
  18. package/src/code-block.tsx +124 -0
  19. package/src/collapsible.tsx +61 -0
  20. package/src/combobox.tsx +324 -0
  21. package/src/command.tsx +377 -0
  22. package/src/context-menu.tsx +250 -0
  23. package/src/dialog.tsx +78 -0
  24. package/src/drawer.tsx +156 -0
  25. package/src/empty.tsx +52 -0
  26. package/src/field.tsx +75 -0
  27. package/src/fieldset.tsx +25 -0
  28. package/src/form.tsx +14 -0
  29. package/src/icons.tsx +91 -0
  30. package/src/illustrations.tsx +167 -0
  31. package/src/image-modal.tsx +110 -0
  32. package/src/index.ts +833 -0
  33. package/src/input.tsx +68 -0
  34. package/src/lib/cn.ts +3 -0
  35. package/src/lib/motion.ts +23 -0
  36. package/src/markdown-editor.tsx +302 -0
  37. package/src/menu.tsx +205 -0
  38. package/src/menubar.tsx +22 -0
  39. package/src/meter.tsx +61 -0
  40. package/src/navigation-menu.tsx +217 -0
  41. package/src/number-field.tsx +119 -0
  42. package/src/orb.tsx +33 -0
  43. package/src/otp-field.tsx +45 -0
  44. package/src/pagination.tsx +91 -0
  45. package/src/popover.tsx +92 -0
  46. package/src/preview-card.tsx +103 -0
  47. package/src/progress.tsx +60 -0
  48. package/src/radio.tsx +43 -0
  49. package/src/scroll-area.tsx +67 -0
  50. package/src/select.tsx +161 -0
  51. package/src/separator.tsx +17 -0
  52. package/src/sidebar.tsx +82 -0
  53. package/src/skeleton.tsx +32 -0
  54. package/src/slider.tsx +56 -0
  55. package/src/sounds.tsx +270 -0
  56. package/src/spinner.tsx +45 -0
  57. package/src/switch.tsx +19 -0
  58. package/src/table.tsx +81 -0
  59. package/src/tabs.tsx +62 -0
  60. package/src/text-animate.tsx +155 -0
  61. package/src/textarea.tsx +58 -0
  62. package/src/ticker.tsx +74 -0
  63. package/src/toast.tsx +142 -0
  64. package/src/toggle.tsx +32 -0
  65. package/src/toolbar.tsx +75 -0
  66. package/src/tooltip.tsx +55 -0
  67. 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
+ )
@@ -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
+ )