@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,217 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { NavigationMenu as BaseNavigationMenu } from "@base-ui/react/navigation-menu"
|
|
4
|
+
import type { ComponentProps } from "react"
|
|
5
|
+
import { IconChevronDownSmall } from "./icons"
|
|
6
|
+
import { cn } from "./lib/cn"
|
|
7
|
+
import { motion } from "./lib/motion"
|
|
8
|
+
|
|
9
|
+
export type NavigationMenuProps = ComponentProps<typeof BaseNavigationMenu.Root>
|
|
10
|
+
export type NavigationMenuListProps = ComponentProps<
|
|
11
|
+
typeof BaseNavigationMenu.List
|
|
12
|
+
>
|
|
13
|
+
export type NavigationMenuItemProps = ComponentProps<
|
|
14
|
+
typeof BaseNavigationMenu.Item
|
|
15
|
+
>
|
|
16
|
+
export type NavigationMenuTriggerProps = ComponentProps<
|
|
17
|
+
typeof BaseNavigationMenu.Trigger
|
|
18
|
+
>
|
|
19
|
+
export type NavigationMenuContentProps = ComponentProps<
|
|
20
|
+
typeof BaseNavigationMenu.Content
|
|
21
|
+
>
|
|
22
|
+
export type NavigationMenuPortalProps = ComponentProps<
|
|
23
|
+
typeof BaseNavigationMenu.Portal
|
|
24
|
+
>
|
|
25
|
+
export type NavigationMenuPositionerProps = ComponentProps<
|
|
26
|
+
typeof BaseNavigationMenu.Positioner
|
|
27
|
+
>
|
|
28
|
+
export type NavigationMenuViewportProps = ComponentProps<
|
|
29
|
+
typeof BaseNavigationMenu.Viewport
|
|
30
|
+
>
|
|
31
|
+
export type NavigationMenuBackdropProps = ComponentProps<
|
|
32
|
+
typeof BaseNavigationMenu.Backdrop
|
|
33
|
+
>
|
|
34
|
+
export type NavigationMenuPopupProps = ComponentProps<
|
|
35
|
+
typeof BaseNavigationMenu.Popup
|
|
36
|
+
>
|
|
37
|
+
export type NavigationMenuArrowProps = ComponentProps<
|
|
38
|
+
typeof BaseNavigationMenu.Arrow
|
|
39
|
+
>
|
|
40
|
+
export type NavigationMenuLinkProps = ComponentProps<
|
|
41
|
+
typeof BaseNavigationMenu.Link
|
|
42
|
+
>
|
|
43
|
+
export type NavigationMenuIconProps = ComponentProps<
|
|
44
|
+
typeof BaseNavigationMenu.Icon
|
|
45
|
+
>
|
|
46
|
+
|
|
47
|
+
const navigationMenuTriggerClassName = cn(
|
|
48
|
+
"inline-flex h-9 cursor-pointer items-center gap-1 rounded-md px-3 text-sm text-fg-secondary outline-none",
|
|
49
|
+
motion.colors,
|
|
50
|
+
"hover:bg-background-tertiary hover:text-fg-primary focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-ring/20 data-popup-open:bg-background-tertiary data-popup-open:text-fg-primary",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
export const NavigationMenu = ({
|
|
54
|
+
className,
|
|
55
|
+
...props
|
|
56
|
+
}: NavigationMenuProps) => (
|
|
57
|
+
<BaseNavigationMenu.Root
|
|
58
|
+
className={cn("relative isolate z-10 flex max-w-max flex-1 items-center justify-center", className)}
|
|
59
|
+
{...props}
|
|
60
|
+
/>
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
export const NavigationMenuList = ({
|
|
64
|
+
className,
|
|
65
|
+
...props
|
|
66
|
+
}: NavigationMenuListProps) => (
|
|
67
|
+
<BaseNavigationMenu.List
|
|
68
|
+
className={cn(
|
|
69
|
+
"group flex flex-1 list-none items-center justify-center gap-0.5",
|
|
70
|
+
className,
|
|
71
|
+
)}
|
|
72
|
+
{...props}
|
|
73
|
+
/>
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
export const NavigationMenuItem = ({
|
|
77
|
+
className,
|
|
78
|
+
...props
|
|
79
|
+
}: NavigationMenuItemProps) => (
|
|
80
|
+
<BaseNavigationMenu.Item className={cn(className)} {...props} />
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
export const NavigationMenuTrigger = ({
|
|
84
|
+
className,
|
|
85
|
+
children,
|
|
86
|
+
...props
|
|
87
|
+
}: NavigationMenuTriggerProps) => (
|
|
88
|
+
<BaseNavigationMenu.Trigger
|
|
89
|
+
className={cn(navigationMenuTriggerClassName, className)}
|
|
90
|
+
{...props}
|
|
91
|
+
>
|
|
92
|
+
{children}
|
|
93
|
+
<NavigationMenuIcon />
|
|
94
|
+
</BaseNavigationMenu.Trigger>
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
export const NavigationMenuIcon = ({
|
|
98
|
+
className,
|
|
99
|
+
children,
|
|
100
|
+
...props
|
|
101
|
+
}: NavigationMenuIconProps) => (
|
|
102
|
+
<BaseNavigationMenu.Icon
|
|
103
|
+
className={cn(
|
|
104
|
+
"inline-flex text-fg-tertiary transition-transform duration-150 ease-out motion-reduce:transition-none data-popup-open:rotate-180",
|
|
105
|
+
className,
|
|
106
|
+
)}
|
|
107
|
+
{...props}
|
|
108
|
+
>
|
|
109
|
+
{children ?? (
|
|
110
|
+
<IconChevronDownSmall size={14} className="size-3.5" aria-hidden />
|
|
111
|
+
)}
|
|
112
|
+
</BaseNavigationMenu.Icon>
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
export const NavigationMenuContent = ({
|
|
116
|
+
className,
|
|
117
|
+
...props
|
|
118
|
+
}: NavigationMenuContentProps) => (
|
|
119
|
+
<BaseNavigationMenu.Content
|
|
120
|
+
className={cn(
|
|
121
|
+
"w-auto p-2 data-ending-style:opacity-0 data-starting-style:opacity-0",
|
|
122
|
+
motion.colors,
|
|
123
|
+
className,
|
|
124
|
+
)}
|
|
125
|
+
{...props}
|
|
126
|
+
/>
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
export const NavigationMenuLink = ({
|
|
130
|
+
className,
|
|
131
|
+
...props
|
|
132
|
+
}: NavigationMenuLinkProps) => (
|
|
133
|
+
<BaseNavigationMenu.Link
|
|
134
|
+
className={cn(
|
|
135
|
+
"flex cursor-pointer flex-col gap-0.5 rounded-md p-2.5 text-sm text-fg-primary outline-none",
|
|
136
|
+
motion.colors,
|
|
137
|
+
"hover:bg-background-tertiary focus-visible:bg-background-tertiary focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-ring/20 data-active:bg-background-tertiary",
|
|
138
|
+
className,
|
|
139
|
+
)}
|
|
140
|
+
{...props}
|
|
141
|
+
/>
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
export const NavigationMenuPortal = (props: NavigationMenuPortalProps) => (
|
|
145
|
+
<BaseNavigationMenu.Portal {...props} />
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
export const NavigationMenuBackdrop = ({
|
|
149
|
+
className,
|
|
150
|
+
...props
|
|
151
|
+
}: NavigationMenuBackdropProps) => (
|
|
152
|
+
<BaseNavigationMenu.Backdrop
|
|
153
|
+
className={cn(
|
|
154
|
+
"fixed inset-0 z-40 bg-transparent",
|
|
155
|
+
motion.backdrop,
|
|
156
|
+
className,
|
|
157
|
+
)}
|
|
158
|
+
{...props}
|
|
159
|
+
/>
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
export const NavigationMenuPositioner = ({
|
|
163
|
+
sideOffset = 8,
|
|
164
|
+
className,
|
|
165
|
+
...props
|
|
166
|
+
}: NavigationMenuPositionerProps) => (
|
|
167
|
+
<BaseNavigationMenu.Positioner
|
|
168
|
+
sideOffset={sideOffset}
|
|
169
|
+
className={cn("z-50 outline-none", className)}
|
|
170
|
+
{...props}
|
|
171
|
+
/>
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
export const NavigationMenuPopup = ({
|
|
175
|
+
className,
|
|
176
|
+
...props
|
|
177
|
+
}: NavigationMenuPopupProps) => (
|
|
178
|
+
<BaseNavigationMenu.Popup
|
|
179
|
+
className={cn(
|
|
180
|
+
"relative z-50 w-[var(--popup-width)] overflow-hidden rounded-xl border border-border-primary bg-surface shadow-md outline-none",
|
|
181
|
+
"h-[var(--popup-height)] transition-[width,height,opacity] duration-200 ease-out motion-reduce:transition-none",
|
|
182
|
+
"data-starting-style:opacity-0 data-ending-style:opacity-0",
|
|
183
|
+
className,
|
|
184
|
+
)}
|
|
185
|
+
{...props}
|
|
186
|
+
/>
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
export const NavigationMenuViewport = ({
|
|
190
|
+
className,
|
|
191
|
+
...props
|
|
192
|
+
}: NavigationMenuViewportProps) => (
|
|
193
|
+
<BaseNavigationMenu.Viewport
|
|
194
|
+
className={cn("relative size-full overflow-hidden", className)}
|
|
195
|
+
{...props}
|
|
196
|
+
/>
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
export const NavigationMenuArrow = ({
|
|
200
|
+
className,
|
|
201
|
+
...props
|
|
202
|
+
}: NavigationMenuArrowProps) => (
|
|
203
|
+
<BaseNavigationMenu.Arrow
|
|
204
|
+
className={cn(
|
|
205
|
+
"data-[side=bottom]:top-[-6px] data-[side=left]:right-[-6px] data-[side=right]:left-[-6px] data-[side=top]:bottom-[-6px]",
|
|
206
|
+
"size-2.5 rotate-45 border border-border-primary bg-surface",
|
|
207
|
+
"data-[side=bottom]:border-r-0 data-[side=bottom]:border-b-0",
|
|
208
|
+
"data-[side=top]:border-t-0 data-[side=top]:border-l-0",
|
|
209
|
+
"data-[side=left]:border-b-0 data-[side=left]:border-l-0",
|
|
210
|
+
"data-[side=right]:border-t-0 data-[side=right]:border-r-0",
|
|
211
|
+
className,
|
|
212
|
+
)}
|
|
213
|
+
{...props}
|
|
214
|
+
/>
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
export { navigationMenuTriggerClassName }
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { NumberField as BaseNumberField } from "@base-ui/react/number-field"
|
|
4
|
+
import type { ComponentProps } from "react"
|
|
5
|
+
import { IconMinus, IconPlus } from "./icons"
|
|
6
|
+
import { cn } from "./lib/cn"
|
|
7
|
+
import { motion } from "./lib/motion"
|
|
8
|
+
|
|
9
|
+
export type NumberFieldProps = ComponentProps<typeof BaseNumberField.Root>
|
|
10
|
+
export type NumberFieldGroupProps = ComponentProps<typeof BaseNumberField.Group>
|
|
11
|
+
export type NumberFieldInputProps = ComponentProps<typeof BaseNumberField.Input>
|
|
12
|
+
export type NumberFieldIncrementProps = ComponentProps<
|
|
13
|
+
typeof BaseNumberField.Increment
|
|
14
|
+
>
|
|
15
|
+
export type NumberFieldDecrementProps = ComponentProps<
|
|
16
|
+
typeof BaseNumberField.Decrement
|
|
17
|
+
>
|
|
18
|
+
export type NumberFieldScrubAreaProps = ComponentProps<
|
|
19
|
+
typeof BaseNumberField.ScrubArea
|
|
20
|
+
>
|
|
21
|
+
export type NumberFieldScrubAreaCursorProps = ComponentProps<
|
|
22
|
+
typeof BaseNumberField.ScrubAreaCursor
|
|
23
|
+
>
|
|
24
|
+
|
|
25
|
+
export const NumberField = ({ className, ...props }: NumberFieldProps) => (
|
|
26
|
+
<BaseNumberField.Root
|
|
27
|
+
className={cn("flex flex-col gap-1.5", className)}
|
|
28
|
+
{...props}
|
|
29
|
+
/>
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
export const NumberFieldGroup = ({
|
|
33
|
+
className,
|
|
34
|
+
...props
|
|
35
|
+
}: NumberFieldGroupProps) => (
|
|
36
|
+
<BaseNumberField.Group
|
|
37
|
+
className={cn(
|
|
38
|
+
"flex h-9 w-full items-stretch overflow-hidden rounded-md border border-border-secondary bg-surface inset-shadow-outline-top outline-none transition-[color,box-shadow]",
|
|
39
|
+
"focus-within:border-ring focus-within:ring-[3px] focus-within:ring-offset-1 focus-within:ring-offset-background-primary focus-within:ring-ring/20",
|
|
40
|
+
"aria-invalid:border-destructive aria-invalid:focus-within:border-destructive aria-invalid:focus-within:ring-destructive/20",
|
|
41
|
+
"has-[[aria-invalid=true]]:border-destructive has-[[aria-invalid=true]]:focus-within:border-destructive has-[[aria-invalid=true]]:focus-within:ring-destructive/20",
|
|
42
|
+
"has-[:disabled]:opacity-50",
|
|
43
|
+
className,
|
|
44
|
+
)}
|
|
45
|
+
{...props}
|
|
46
|
+
/>
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
export const NumberFieldInput = ({
|
|
50
|
+
className,
|
|
51
|
+
...props
|
|
52
|
+
}: NumberFieldInputProps) => (
|
|
53
|
+
<BaseNumberField.Input
|
|
54
|
+
className={cn(
|
|
55
|
+
"h-full min-w-0 flex-1 cursor-text border-x border-border-primary bg-transparent px-2 text-center text-sm tabular-nums text-fg-primary outline-none focus-visible:outline-none",
|
|
56
|
+
className,
|
|
57
|
+
)}
|
|
58
|
+
{...props}
|
|
59
|
+
/>
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
const stepperClassName = cn(
|
|
63
|
+
"inline-flex size-9 shrink-0 cursor-pointer items-center justify-center text-fg-tertiary outline-none",
|
|
64
|
+
motion.colors,
|
|
65
|
+
"hover:bg-background-tertiary hover:text-fg-primary focus-visible:bg-background-tertiary focus-visible:text-fg-primary focus-visible:outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50",
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
export const NumberFieldDecrement = ({
|
|
69
|
+
className,
|
|
70
|
+
children,
|
|
71
|
+
"aria-label": ariaLabel = "Decrease",
|
|
72
|
+
...props
|
|
73
|
+
}: NumberFieldDecrementProps) => (
|
|
74
|
+
<BaseNumberField.Decrement
|
|
75
|
+
aria-label={ariaLabel}
|
|
76
|
+
className={cn(stepperClassName, className)}
|
|
77
|
+
{...props}
|
|
78
|
+
>
|
|
79
|
+
{children ?? <IconMinus size={16} className="size-4" aria-hidden />}
|
|
80
|
+
</BaseNumberField.Decrement>
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
export const NumberFieldIncrement = ({
|
|
84
|
+
className,
|
|
85
|
+
children,
|
|
86
|
+
"aria-label": ariaLabel = "Increase",
|
|
87
|
+
...props
|
|
88
|
+
}: NumberFieldIncrementProps) => (
|
|
89
|
+
<BaseNumberField.Increment
|
|
90
|
+
aria-label={ariaLabel}
|
|
91
|
+
className={cn(stepperClassName, className)}
|
|
92
|
+
{...props}
|
|
93
|
+
>
|
|
94
|
+
{children ?? <IconPlus size={16} className="size-4" aria-hidden />}
|
|
95
|
+
</BaseNumberField.Increment>
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
export const NumberFieldScrubArea = ({
|
|
99
|
+
className,
|
|
100
|
+
...props
|
|
101
|
+
}: NumberFieldScrubAreaProps) => (
|
|
102
|
+
<BaseNumberField.ScrubArea
|
|
103
|
+
className={cn(
|
|
104
|
+
"inline-flex cursor-ew-resize items-center gap-1 text-sm text-fg-secondary select-none",
|
|
105
|
+
className,
|
|
106
|
+
)}
|
|
107
|
+
{...props}
|
|
108
|
+
/>
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
export const NumberFieldScrubAreaCursor = ({
|
|
112
|
+
className,
|
|
113
|
+
...props
|
|
114
|
+
}: NumberFieldScrubAreaCursorProps) => (
|
|
115
|
+
<BaseNumberField.ScrubAreaCursor
|
|
116
|
+
className={cn(className)}
|
|
117
|
+
{...props}
|
|
118
|
+
/>
|
|
119
|
+
)
|
package/src/orb.tsx
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
2
|
+
import type { ComponentProps } from "react";
|
|
3
|
+
import { cn } from "./lib/cn";
|
|
4
|
+
|
|
5
|
+
const orbVariants = cva(
|
|
6
|
+
"relative inline-flex shrink-0 animate-pulse rounded-full border border-brand-primary-border bg-brand-primary after:absolute after:inset-1/4 after:rounded-full after:bg-surface/70 after:blur-sm motion-reduce:animate-none",
|
|
7
|
+
{
|
|
8
|
+
variants: {
|
|
9
|
+
size: {
|
|
10
|
+
sm: "size-6",
|
|
11
|
+
md: "size-10",
|
|
12
|
+
lg: "size-16",
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
defaultVariants: {
|
|
16
|
+
size: "md",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
export type OrbProps = ComponentProps<"span"> &
|
|
22
|
+
VariantProps<typeof orbVariants>;
|
|
23
|
+
|
|
24
|
+
export const Orb = ({ className, size, ...props }: OrbProps) => (
|
|
25
|
+
<span
|
|
26
|
+
role="status"
|
|
27
|
+
aria-label="Loading"
|
|
28
|
+
className={cn(orbVariants({ size }), className)}
|
|
29
|
+
{...props}
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
export { orbVariants };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { OTPField as BaseOTPField } from "@base-ui/react/otp-field"
|
|
4
|
+
import type { ComponentProps } from "react"
|
|
5
|
+
import { cn } from "./lib/cn"
|
|
6
|
+
import { motion } from "./lib/motion"
|
|
7
|
+
|
|
8
|
+
export type OTPFieldProps = ComponentProps<typeof BaseOTPField.Root>
|
|
9
|
+
export type OTPFieldInputProps = ComponentProps<typeof BaseOTPField.Input>
|
|
10
|
+
export type OTPFieldSeparatorProps = ComponentProps<typeof BaseOTPField.Separator>
|
|
11
|
+
|
|
12
|
+
export const OTPField = ({ className, ...props }: OTPFieldProps) => (
|
|
13
|
+
<BaseOTPField.Root
|
|
14
|
+
className={cn("flex items-center gap-2", className)}
|
|
15
|
+
{...props}
|
|
16
|
+
/>
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
export const OTPFieldInput = ({ className, ...props }: OTPFieldInputProps) => (
|
|
20
|
+
<BaseOTPField.Input
|
|
21
|
+
className={cn(
|
|
22
|
+
"size-10 rounded-md border border-border-secondary bg-surface text-center text-sm tabular-nums text-fg-primary inset-shadow-outline-top outline-none",
|
|
23
|
+
motion.colors,
|
|
24
|
+
"focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-ring/20",
|
|
25
|
+
"aria-invalid:border-destructive aria-invalid:focus-visible:border-destructive aria-invalid:focus-visible:ring-destructive/20",
|
|
26
|
+
"data-disabled:cursor-not-allowed data-disabled:opacity-50",
|
|
27
|
+
"data-filled:border-border-secondary",
|
|
28
|
+
className,
|
|
29
|
+
)}
|
|
30
|
+
{...props}
|
|
31
|
+
/>
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
export const OTPFieldSeparator = ({
|
|
35
|
+
className,
|
|
36
|
+
...props
|
|
37
|
+
}: OTPFieldSeparatorProps) => (
|
|
38
|
+
<BaseOTPField.Separator
|
|
39
|
+
className={cn(
|
|
40
|
+
"mx-0.5 h-px w-3 shrink-0 self-center bg-border-secondary",
|
|
41
|
+
className,
|
|
42
|
+
)}
|
|
43
|
+
{...props}
|
|
44
|
+
/>
|
|
45
|
+
)
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { ComponentProps } from "react";
|
|
2
|
+
import { IconChevronRightSmall } from "./icons";
|
|
3
|
+
import { cn } from "./lib/cn";
|
|
4
|
+
import { motion } from "./lib/motion";
|
|
5
|
+
|
|
6
|
+
export type PaginationProps = ComponentProps<"nav">;
|
|
7
|
+
export type PaginationContentProps = ComponentProps<"ul">;
|
|
8
|
+
export type PaginationItemProps = ComponentProps<"li">;
|
|
9
|
+
export type PaginationLinkProps = ComponentProps<"button"> & {
|
|
10
|
+
active?: boolean;
|
|
11
|
+
};
|
|
12
|
+
export type PaginationPreviousProps = PaginationLinkProps;
|
|
13
|
+
export type PaginationNextProps = PaginationLinkProps;
|
|
14
|
+
export type PaginationEllipsisProps = ComponentProps<"span">;
|
|
15
|
+
|
|
16
|
+
export const Pagination = ({ className, ...props }: PaginationProps) => (
|
|
17
|
+
<nav
|
|
18
|
+
aria-label="Pagination"
|
|
19
|
+
className={cn("flex w-full justify-center", className)}
|
|
20
|
+
{...props}
|
|
21
|
+
/>
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
export const PaginationContent = ({
|
|
25
|
+
className,
|
|
26
|
+
...props
|
|
27
|
+
}: PaginationContentProps) => (
|
|
28
|
+
<ul className={cn("flex items-center gap-1", className)} {...props} />
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
export const PaginationItem = ({
|
|
32
|
+
className,
|
|
33
|
+
...props
|
|
34
|
+
}: PaginationItemProps) => <li className={cn("flex", className)} {...props} />;
|
|
35
|
+
|
|
36
|
+
export const PaginationLink = ({
|
|
37
|
+
className,
|
|
38
|
+
active = false,
|
|
39
|
+
type = "button",
|
|
40
|
+
...props
|
|
41
|
+
}: PaginationLinkProps) => (
|
|
42
|
+
<button
|
|
43
|
+
type={type}
|
|
44
|
+
aria-current={active ? "page" : undefined}
|
|
45
|
+
data-active={active || undefined}
|
|
46
|
+
className={cn(
|
|
47
|
+
"inline-flex size-9 cursor-pointer items-center justify-center rounded-md border border-transparent text-sm text-fg-secondary outline-none hover:bg-background-tertiary hover:text-fg-primary focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary focus-visible:ring-ring/20 disabled:cursor-not-allowed disabled:opacity-50 data-[active]:border-border-primary data-[active]:bg-surface data-[active]:text-fg-primary",
|
|
48
|
+
motion.colors,
|
|
49
|
+
className,
|
|
50
|
+
)}
|
|
51
|
+
{...props}
|
|
52
|
+
/>
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
export const PaginationPrevious = ({
|
|
56
|
+
children = "Previous",
|
|
57
|
+
className,
|
|
58
|
+
...props
|
|
59
|
+
}: PaginationPreviousProps) => (
|
|
60
|
+
<PaginationLink className={cn("w-auto gap-1 px-3", className)} {...props}>
|
|
61
|
+
<IconChevronRightSmall className="rotate-180" aria-hidden />
|
|
62
|
+
{children}
|
|
63
|
+
</PaginationLink>
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
export const PaginationNext = ({
|
|
67
|
+
children = "Next",
|
|
68
|
+
className,
|
|
69
|
+
...props
|
|
70
|
+
}: PaginationNextProps) => (
|
|
71
|
+
<PaginationLink className={cn("w-auto gap-1 px-3", className)} {...props}>
|
|
72
|
+
{children}
|
|
73
|
+
<IconChevronRightSmall aria-hidden />
|
|
74
|
+
</PaginationLink>
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
export const PaginationEllipsis = ({
|
|
78
|
+
className,
|
|
79
|
+
...props
|
|
80
|
+
}: PaginationEllipsisProps) => (
|
|
81
|
+
<span
|
|
82
|
+
aria-hidden
|
|
83
|
+
className={cn(
|
|
84
|
+
"flex size-9 items-center justify-center text-sm text-fg-tertiary",
|
|
85
|
+
className,
|
|
86
|
+
)}
|
|
87
|
+
{...props}
|
|
88
|
+
>
|
|
89
|
+
…
|
|
90
|
+
</span>
|
|
91
|
+
);
|
package/src/popover.tsx
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { Popover as BasePopover } from "@base-ui/react/popover"
|
|
4
|
+
import type { ComponentProps } from "react"
|
|
5
|
+
import { cn } from "./lib/cn"
|
|
6
|
+
import { motion } from "./lib/motion"
|
|
7
|
+
|
|
8
|
+
export type PopoverProps = ComponentProps<typeof BasePopover.Root>
|
|
9
|
+
export type PopoverTriggerProps = ComponentProps<typeof BasePopover.Trigger>
|
|
10
|
+
export type PopoverPortalProps = ComponentProps<typeof BasePopover.Portal>
|
|
11
|
+
export type PopoverPositionerProps = ComponentProps<
|
|
12
|
+
typeof BasePopover.Positioner
|
|
13
|
+
>
|
|
14
|
+
export type PopoverPopupProps = ComponentProps<typeof BasePopover.Popup>
|
|
15
|
+
export type PopoverTitleProps = ComponentProps<typeof BasePopover.Title>
|
|
16
|
+
export type PopoverDescriptionProps = ComponentProps<
|
|
17
|
+
typeof BasePopover.Description
|
|
18
|
+
>
|
|
19
|
+
export type PopoverCloseProps = ComponentProps<typeof BasePopover.Close>
|
|
20
|
+
export type PopoverArrowProps = ComponentProps<typeof BasePopover.Arrow>
|
|
21
|
+
|
|
22
|
+
export const Popover = (props: PopoverProps) => <BasePopover.Root {...props} />
|
|
23
|
+
|
|
24
|
+
export const PopoverTrigger = ({
|
|
25
|
+
className,
|
|
26
|
+
...props
|
|
27
|
+
}: PopoverTriggerProps) => (
|
|
28
|
+
<BasePopover.Trigger className={cn("cursor-pointer", className)} {...props} />
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
export const PopoverPortal = (props: PopoverPortalProps) => (
|
|
32
|
+
<BasePopover.Portal {...props} />
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
export const PopoverPositioner = ({
|
|
36
|
+
sideOffset = 4,
|
|
37
|
+
className,
|
|
38
|
+
...props
|
|
39
|
+
}: PopoverPositionerProps) => (
|
|
40
|
+
<BasePopover.Positioner
|
|
41
|
+
sideOffset={sideOffset}
|
|
42
|
+
className={cn("z-50 outline-none", className)}
|
|
43
|
+
{...props}
|
|
44
|
+
/>
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
export const PopoverPopup = ({ className, ...props }: PopoverPopupProps) => (
|
|
48
|
+
<BasePopover.Popup
|
|
49
|
+
className={cn(
|
|
50
|
+
"z-50 flex w-72 flex-col gap-1 rounded-xl border border-border-primary bg-surface p-4 shadow-md outline-none",
|
|
51
|
+
motion.popupAnchor,
|
|
52
|
+
className,
|
|
53
|
+
)}
|
|
54
|
+
{...props}
|
|
55
|
+
/>
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
export const PopoverTitle = ({ className, ...props }: PopoverTitleProps) => (
|
|
59
|
+
<BasePopover.Title
|
|
60
|
+
className={cn("text-sm-strong text-fg-primary", className)}
|
|
61
|
+
{...props}
|
|
62
|
+
/>
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
export const PopoverDescription = ({
|
|
66
|
+
className,
|
|
67
|
+
...props
|
|
68
|
+
}: PopoverDescriptionProps) => (
|
|
69
|
+
<BasePopover.Description
|
|
70
|
+
className={cn("text-sm leading-relaxed text-fg-secondary", className)}
|
|
71
|
+
{...props}
|
|
72
|
+
/>
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
export const PopoverClose = ({ className, ...props }: PopoverCloseProps) => (
|
|
76
|
+
<BasePopover.Close className={cn("cursor-pointer", className)} {...props} />
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
export const PopoverArrow = ({ className, ...props }: PopoverArrowProps) => (
|
|
80
|
+
<BasePopover.Arrow
|
|
81
|
+
className={cn(
|
|
82
|
+
"data-[side=bottom]:top-[-6px] data-[side=left]:right-[-6px] data-[side=right]:left-[-6px] data-[side=top]:bottom-[-6px]",
|
|
83
|
+
"size-2.5 rotate-45 border border-border-primary bg-surface",
|
|
84
|
+
"data-[side=bottom]:border-r-0 data-[side=bottom]:border-b-0",
|
|
85
|
+
"data-[side=top]:border-t-0 data-[side=top]:border-l-0",
|
|
86
|
+
"data-[side=left]:border-b-0 data-[side=left]:border-l-0",
|
|
87
|
+
"data-[side=right]:border-t-0 data-[side=right]:border-r-0",
|
|
88
|
+
className,
|
|
89
|
+
)}
|
|
90
|
+
{...props}
|
|
91
|
+
/>
|
|
92
|
+
)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card"
|
|
4
|
+
import type { ComponentProps } from "react"
|
|
5
|
+
import { cn } from "./lib/cn"
|
|
6
|
+
import { motion } from "./lib/motion"
|
|
7
|
+
|
|
8
|
+
export type PreviewCardProps = ComponentProps<typeof BasePreviewCard.Root>
|
|
9
|
+
export type PreviewCardTriggerProps = ComponentProps<
|
|
10
|
+
typeof BasePreviewCard.Trigger
|
|
11
|
+
>
|
|
12
|
+
export type PreviewCardPortalProps = ComponentProps<
|
|
13
|
+
typeof BasePreviewCard.Portal
|
|
14
|
+
>
|
|
15
|
+
export type PreviewCardBackdropProps = ComponentProps<
|
|
16
|
+
typeof BasePreviewCard.Backdrop
|
|
17
|
+
>
|
|
18
|
+
export type PreviewCardPositionerProps = ComponentProps<
|
|
19
|
+
typeof BasePreviewCard.Positioner
|
|
20
|
+
>
|
|
21
|
+
export type PreviewCardPopupProps = ComponentProps<typeof BasePreviewCard.Popup>
|
|
22
|
+
export type PreviewCardArrowProps = ComponentProps<typeof BasePreviewCard.Arrow>
|
|
23
|
+
export type PreviewCardViewportProps = ComponentProps<
|
|
24
|
+
typeof BasePreviewCard.Viewport
|
|
25
|
+
>
|
|
26
|
+
|
|
27
|
+
export const PreviewCard = (props: PreviewCardProps) => (
|
|
28
|
+
<BasePreviewCard.Root {...props} />
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
export const PreviewCardTrigger = ({
|
|
32
|
+
className,
|
|
33
|
+
...props
|
|
34
|
+
}: PreviewCardTriggerProps) => (
|
|
35
|
+
<BasePreviewCard.Trigger
|
|
36
|
+
className={cn("cursor-pointer", className)}
|
|
37
|
+
{...props}
|
|
38
|
+
/>
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
export const PreviewCardPortal = (props: PreviewCardPortalProps) => (
|
|
42
|
+
<BasePreviewCard.Portal {...props} />
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
export const PreviewCardBackdrop = ({
|
|
46
|
+
className,
|
|
47
|
+
...props
|
|
48
|
+
}: PreviewCardBackdropProps) => (
|
|
49
|
+
<BasePreviewCard.Backdrop className={cn(className)} {...props} />
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
export const PreviewCardPositioner = ({
|
|
53
|
+
sideOffset = 8,
|
|
54
|
+
className,
|
|
55
|
+
...props
|
|
56
|
+
}: PreviewCardPositionerProps) => (
|
|
57
|
+
<BasePreviewCard.Positioner
|
|
58
|
+
sideOffset={sideOffset}
|
|
59
|
+
className={cn("z-50 outline-none", className)}
|
|
60
|
+
{...props}
|
|
61
|
+
/>
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
export const PreviewCardPopup = ({
|
|
65
|
+
className,
|
|
66
|
+
...props
|
|
67
|
+
}: PreviewCardPopupProps) => (
|
|
68
|
+
<BasePreviewCard.Popup
|
|
69
|
+
className={cn(
|
|
70
|
+
"z-50 w-72 overflow-hidden rounded-xl border border-border-primary bg-surface p-4 shadow-md outline-none",
|
|
71
|
+
motion.popupAnchor,
|
|
72
|
+
className,
|
|
73
|
+
)}
|
|
74
|
+
{...props}
|
|
75
|
+
/>
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
export const PreviewCardArrow = ({
|
|
79
|
+
className,
|
|
80
|
+
...props
|
|
81
|
+
}: PreviewCardArrowProps) => (
|
|
82
|
+
<BasePreviewCard.Arrow
|
|
83
|
+
className={cn(
|
|
84
|
+
"data-[side=bottom]:top-[-6px] data-[side=left]:right-[-6px] data-[side=right]:left-[-6px] data-[side=top]:bottom-[-6px]",
|
|
85
|
+
"size-2.5 rotate-45 border border-border-primary bg-surface",
|
|
86
|
+
"data-[side=bottom]:border-r-0 data-[side=bottom]:border-b-0",
|
|
87
|
+
"data-[side=top]:border-t-0 data-[side=top]:border-l-0",
|
|
88
|
+
"data-[side=left]:border-b-0 data-[side=left]:border-l-0",
|
|
89
|
+
"data-[side=right]:border-t-0 data-[side=right]:border-r-0",
|
|
90
|
+
className,
|
|
91
|
+
)}
|
|
92
|
+
{...props}
|
|
93
|
+
/>
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
export const PreviewCardViewport = ({
|
|
97
|
+
className,
|
|
98
|
+
...props
|
|
99
|
+
}: PreviewCardViewportProps) => (
|
|
100
|
+
<BasePreviewCard.Viewport className={cn(className)} {...props} />
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
export const createPreviewCardHandle = BasePreviewCard.createHandle
|