@boyernick/standard-ui-react 0.1.1-canary.2 → 0.1.1-canary.20

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 (55) hide show
  1. package/package.json +5 -3
  2. package/src/accordion.tsx +1 -1
  3. package/src/alert-dialog.tsx +1 -1
  4. package/src/autocomplete.tsx +12 -11
  5. package/src/badge.tsx +73 -9
  6. package/src/brand.tsx +2 -2
  7. package/src/breadcrumb.tsx +38 -20
  8. package/src/button.tsx +2 -2
  9. package/src/calendar.tsx +22 -11
  10. package/src/card.tsx +57 -14
  11. package/src/carousel.tsx +163 -6
  12. package/src/checkbox.tsx +35 -13
  13. package/src/collapsible.tsx +4 -2
  14. package/src/combobox.tsx +13 -12
  15. package/src/command.tsx +38 -14
  16. package/src/context-menu.tsx +6 -3
  17. package/src/date-picker.tsx +174 -0
  18. package/src/dialog.tsx +33 -10
  19. package/src/drawer.tsx +1 -1
  20. package/src/empty.tsx +4 -4
  21. package/src/field.tsx +1 -1
  22. package/src/filter-group.tsx +139 -0
  23. package/src/icons.tsx +39 -0
  24. package/src/illustrations.tsx +219 -141
  25. package/src/image-modal.tsx +440 -49
  26. package/src/index.ts +163 -0
  27. package/src/input.tsx +1 -1
  28. package/src/kbd.tsx +49 -0
  29. package/src/lib/motion.ts +128 -18
  30. package/src/lib/popup.ts +45 -0
  31. package/src/menu.tsx +7 -4
  32. package/src/menubar.tsx +5 -0
  33. package/src/meter.tsx +1 -1
  34. package/src/minimap.tsx +267 -0
  35. package/src/navigation-menu.tsx +336 -67
  36. package/src/number-field.tsx +327 -61
  37. package/src/pagination.tsx +258 -42
  38. package/src/popover.tsx +3 -1
  39. package/src/preview-card.tsx +3 -1
  40. package/src/progress.tsx +6 -1
  41. package/src/questionnaire.tsx +279 -0
  42. package/src/scroll-area.tsx +1 -1
  43. package/src/select.tsx +8 -6
  44. package/src/sidebar.tsx +109 -28
  45. package/src/slider.tsx +64 -6
  46. package/src/sounds.tsx +6 -10
  47. package/src/spinner.tsx +105 -32
  48. package/src/switch.tsx +2 -2
  49. package/src/table.tsx +82 -15
  50. package/src/tabs.tsx +184 -38
  51. package/src/text-animate.tsx +71 -28
  52. package/src/textarea.tsx +1 -1
  53. package/src/toast.tsx +156 -23
  54. package/src/tooltip.tsx +43 -3
  55. package/src/video-player.tsx +296 -120
@@ -1,21 +1,184 @@
1
1
  "use client"
2
2
 
3
3
  import { NavigationMenu as BaseNavigationMenu } from "@base-ui/react/navigation-menu"
4
- import type { ComponentProps } from "react"
4
+ import { cva, type VariantProps } from "class-variance-authority"
5
+ import { createContext, useContext, useMemo, type ComponentProps } from "react"
5
6
  import { IconChevronDownSmall } from "./icons"
6
7
  import { cn } from "./lib/cn"
7
8
  import { motion } from "./lib/motion"
9
+ import { popupSurface } from "./lib/popup"
8
10
 
9
- export type NavigationMenuProps = ComponentProps<typeof BaseNavigationMenu.Root>
11
+ export type NavigationMenuVariant = "plain" | "pill" | "underline"
12
+ export type NavigationMenuSize = "sm" | "md" | "lg"
13
+ type NavigationMenuOrientation = "horizontal" | "vertical"
14
+
15
+ type NavigationMenuStyleContextValue = {
16
+ orientation: NavigationMenuOrientation
17
+ size: NavigationMenuSize
18
+ variant: NavigationMenuVariant
19
+ }
20
+
21
+ const NavigationMenuStyleContext =
22
+ createContext<NavigationMenuStyleContextValue>({
23
+ orientation: "horizontal",
24
+ size: "md",
25
+ variant: "plain",
26
+ })
27
+
28
+ const navigationMenuRootVariants = cva("relative isolate z-10 flex", {
29
+ variants: {
30
+ orientation: {
31
+ horizontal: "max-w-max flex-1 items-center justify-center",
32
+ vertical: "w-full max-w-56 flex-col items-stretch",
33
+ },
34
+ },
35
+ defaultVariants: {
36
+ orientation: "horizontal",
37
+ },
38
+ })
39
+
40
+ const navigationMenuListVariants = cva("group list-none", {
41
+ variants: {
42
+ orientation: {
43
+ horizontal: "flex flex-1 items-center justify-center gap-0.5",
44
+ vertical: "flex w-full flex-col items-stretch gap-0.5",
45
+ },
46
+ variant: {
47
+ plain: "",
48
+ pill: "bg-background-secondary p-1",
49
+ underline: "border-border-primary",
50
+ },
51
+ },
52
+ compoundVariants: [
53
+ {
54
+ orientation: "horizontal",
55
+ variant: "pill",
56
+ className: "rounded-full",
57
+ },
58
+ {
59
+ orientation: "vertical",
60
+ variant: "pill",
61
+ className: "rounded-lg",
62
+ },
63
+ {
64
+ orientation: "horizontal",
65
+ variant: "underline",
66
+ className: "border-b",
67
+ },
68
+ {
69
+ orientation: "vertical",
70
+ variant: "underline",
71
+ className: "border-l",
72
+ },
73
+ ],
74
+ defaultVariants: {
75
+ orientation: "horizontal",
76
+ variant: "plain",
77
+ },
78
+ })
79
+
80
+ const navigationMenuBarItemVariants = cva(
81
+ cn(
82
+ "inline-flex cursor-pointer items-center gap-1 border border-transparent text-fg-secondary outline-none",
83
+ motion.colors,
84
+ "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-active:font-medium data-active:text-fg-primary data-popup-open:text-fg-primary",
85
+ ),
86
+ {
87
+ variants: {
88
+ orientation: {
89
+ horizontal: "justify-center",
90
+ vertical: "w-full justify-between",
91
+ },
92
+ size: {
93
+ sm: "h-8 px-2.5 text-xs",
94
+ md: "h-9 px-3 text-sm",
95
+ lg: "h-10 px-3.5 text-sm",
96
+ },
97
+ variant: {
98
+ plain:
99
+ "rounded-md hover:bg-background-tertiary data-active:bg-background-tertiary data-popup-open:bg-background-tertiary",
100
+ pill: "rounded-full hover:bg-surface data-active:border-brand-primary-border data-active:bg-brand-primary data-active:text-brand-foreground data-popup-open:bg-surface data-popup-open:shadow-sm",
101
+ underline: "rounded-none hover:bg-transparent",
102
+ },
103
+ },
104
+ compoundVariants: [
105
+ {
106
+ orientation: "horizontal",
107
+ variant: "underline",
108
+ className:
109
+ "h-auto border-x-0 border-t-0 border-b-2 border-b-transparent px-2 py-2.5 data-active:border-b-brand-primary data-popup-open:border-b-brand-primary",
110
+ },
111
+ {
112
+ orientation: "vertical",
113
+ variant: "underline",
114
+ className:
115
+ "border-y-0 border-r-0 border-l-2 border-l-transparent data-active:border-l-brand-primary data-popup-open:border-l-brand-primary",
116
+ },
117
+ ],
118
+ defaultVariants: {
119
+ orientation: "horizontal",
120
+ size: "md",
121
+ variant: "plain",
122
+ },
123
+ },
124
+ )
125
+
126
+ const navigationMenuLinkVariants = cva(
127
+ cn(
128
+ "group/navigation-link flex cursor-pointer rounded-md text-fg-primary outline-none",
129
+ motion.colors,
130
+ "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",
131
+ ),
132
+ {
133
+ variants: {
134
+ variant: {
135
+ default: "flex-col gap-0.5",
136
+ featured:
137
+ "min-h-32 flex-col justify-end gap-1 bg-background-secondary",
138
+ },
139
+ size: {
140
+ sm: "p-2 text-xs",
141
+ md: "p-2.5 text-sm",
142
+ lg: "p-3 text-sm",
143
+ },
144
+ },
145
+ defaultVariants: {
146
+ variant: "default",
147
+ size: "md",
148
+ },
149
+ },
150
+ )
151
+
152
+ type NavigationMenuBarItemVariantProps = Omit<
153
+ VariantProps<typeof navigationMenuBarItemVariants>,
154
+ "orientation"
155
+ >
156
+
157
+ export type NavigationMenuProps = Omit<
158
+ ComponentProps<typeof BaseNavigationMenu.Root>,
159
+ "size"
160
+ > & {
161
+ size?: NavigationMenuSize
162
+ variant?: NavigationMenuVariant
163
+ }
10
164
  export type NavigationMenuListProps = ComponentProps<
11
165
  typeof BaseNavigationMenu.List
12
166
  >
13
167
  export type NavigationMenuItemProps = ComponentProps<
14
168
  typeof BaseNavigationMenu.Item
15
169
  >
16
- export type NavigationMenuTriggerProps = ComponentProps<
17
- typeof BaseNavigationMenu.Trigger
18
- >
170
+ export type NavigationMenuTriggerProps = Omit<
171
+ ComponentProps<typeof BaseNavigationMenu.Trigger>,
172
+ "size"
173
+ > &
174
+ NavigationMenuBarItemVariantProps & {
175
+ showIcon?: boolean
176
+ }
177
+ export type NavigationMenuBarLinkProps = Omit<
178
+ ComponentProps<typeof BaseNavigationMenu.Link>,
179
+ "size"
180
+ > &
181
+ NavigationMenuBarItemVariantProps
19
182
  export type NavigationMenuContentProps = ComponentProps<
20
183
  typeof BaseNavigationMenu.Content
21
184
  >
@@ -37,41 +200,59 @@ export type NavigationMenuPopupProps = ComponentProps<
37
200
  export type NavigationMenuArrowProps = ComponentProps<
38
201
  typeof BaseNavigationMenu.Arrow
39
202
  >
40
- export type NavigationMenuLinkProps = ComponentProps<
41
- typeof BaseNavigationMenu.Link
42
- >
203
+ export type NavigationMenuLinkProps = Omit<
204
+ ComponentProps<typeof BaseNavigationMenu.Link>,
205
+ "size"
206
+ > &
207
+ VariantProps<typeof navigationMenuLinkVariants>
208
+ export type NavigationMenuLinkIconProps = ComponentProps<"span">
209
+ export type NavigationMenuLinkTitleProps = ComponentProps<"span">
210
+ export type NavigationMenuLinkDescriptionProps = ComponentProps<"span">
43
211
  export type NavigationMenuIconProps = ComponentProps<
44
212
  typeof BaseNavigationMenu.Icon
45
213
  >
46
214
 
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
215
  export const NavigationMenu = ({
54
216
  className,
217
+ orientation = "horizontal",
218
+ size = "md",
219
+ variant = "plain",
55
220
  ...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
- )
221
+ }: NavigationMenuProps) => {
222
+ const styleContext = useMemo(
223
+ () => ({ orientation, size, variant }),
224
+ [orientation, size, variant],
225
+ )
226
+
227
+ return (
228
+ <NavigationMenuStyleContext.Provider value={styleContext}>
229
+ <BaseNavigationMenu.Root
230
+ orientation={orientation}
231
+ data-orientation={orientation}
232
+ data-variant={variant}
233
+ className={cn(navigationMenuRootVariants({ orientation }), className)}
234
+ {...props}
235
+ />
236
+ </NavigationMenuStyleContext.Provider>
237
+ )
238
+ }
62
239
 
63
240
  export const NavigationMenuList = ({
64
241
  className,
65
242
  ...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
- )
243
+ }: NavigationMenuListProps) => {
244
+ const { orientation, variant } = useContext(NavigationMenuStyleContext)
245
+
246
+ return (
247
+ <BaseNavigationMenu.List
248
+ className={cn(
249
+ navigationMenuListVariants({ orientation, variant }),
250
+ className,
251
+ )}
252
+ {...props}
253
+ />
254
+ )
255
+ }
75
256
 
76
257
  export const NavigationMenuItem = ({
77
258
  className,
@@ -83,34 +264,79 @@ export const NavigationMenuItem = ({
83
264
  export const NavigationMenuTrigger = ({
84
265
  className,
85
266
  children,
267
+ showIcon = true,
268
+ size,
269
+ variant,
86
270
  ...props
87
- }: NavigationMenuTriggerProps) => (
88
- <BaseNavigationMenu.Trigger
89
- className={cn(navigationMenuTriggerClassName, className)}
90
- {...props}
91
- >
92
- {children}
93
- <NavigationMenuIcon />
94
- </BaseNavigationMenu.Trigger>
95
- )
271
+ }: NavigationMenuTriggerProps) => {
272
+ const styles = useContext(NavigationMenuStyleContext)
273
+
274
+ return (
275
+ <BaseNavigationMenu.Trigger
276
+ className={cn(
277
+ navigationMenuBarItemVariants({
278
+ orientation: styles.orientation,
279
+ size: size ?? styles.size,
280
+ variant: variant ?? styles.variant,
281
+ }),
282
+ className,
283
+ )}
284
+ {...props}
285
+ >
286
+ {children}
287
+ {showIcon ? <NavigationMenuIcon /> : null}
288
+ </BaseNavigationMenu.Trigger>
289
+ )
290
+ }
291
+
292
+ export const NavigationMenuBarLink = ({
293
+ className,
294
+ size,
295
+ variant,
296
+ ...props
297
+ }: NavigationMenuBarLinkProps) => {
298
+ const styles = useContext(NavigationMenuStyleContext)
299
+
300
+ return (
301
+ <BaseNavigationMenu.Link
302
+ className={cn(
303
+ navigationMenuBarItemVariants({
304
+ orientation: styles.orientation,
305
+ size: size ?? styles.size,
306
+ variant: variant ?? styles.variant,
307
+ }),
308
+ className,
309
+ )}
310
+ {...props}
311
+ />
312
+ )
313
+ }
96
314
 
97
315
  export const NavigationMenuIcon = ({
98
316
  className,
99
317
  children,
100
318
  ...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
- )
319
+ }: NavigationMenuIconProps) => {
320
+ const { orientation } = useContext(NavigationMenuStyleContext)
321
+
322
+ return (
323
+ <BaseNavigationMenu.Icon
324
+ className={cn(
325
+ "inline-flex text-fg-tertiary",
326
+ motion.transform,
327
+ orientation === "horizontal"
328
+ ? "data-popup-open:rotate-180"
329
+ : "-rotate-90 data-popup-open:rotate-0",
330
+ className,
331
+ )}
332
+ {...props}
333
+ >
334
+ {children ?? (
335
+ <IconChevronDownSmall size={14} className="size-3.5" aria-hidden />
336
+ )}
337
+ </BaseNavigationMenu.Icon>
338
+ )
339
+ }
114
340
 
115
341
  export const NavigationMenuContent = ({
116
342
  className,
@@ -118,8 +344,7 @@ export const NavigationMenuContent = ({
118
344
  }: NavigationMenuContentProps) => (
119
345
  <BaseNavigationMenu.Content
120
346
  className={cn(
121
- "w-auto p-2 data-ending-style:opacity-0 data-starting-style:opacity-0",
122
- motion.colors,
347
+ "w-auto p-2 transition-[opacity,transform] duration-[var(--duration-sm)] ease-enter motion-reduce:transition-none data-starting-style:translate-y-1 data-starting-style:opacity-0 data-ending-style:translate-y-1 data-ending-style:opacity-0",
123
348
  className,
124
349
  )}
125
350
  {...props}
@@ -128,19 +353,49 @@ export const NavigationMenuContent = ({
128
353
 
129
354
  export const NavigationMenuLink = ({
130
355
  className,
356
+ variant,
357
+ size,
131
358
  ...props
132
359
  }: NavigationMenuLinkProps) => (
133
360
  <BaseNavigationMenu.Link
361
+ className={cn(navigationMenuLinkVariants({ variant, size }), className)}
362
+ {...props}
363
+ />
364
+ )
365
+
366
+ export const NavigationMenuLinkIcon = ({
367
+ className,
368
+ ...props
369
+ }: NavigationMenuLinkIconProps) => (
370
+ <span
134
371
  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",
372
+ "mb-1 flex size-9 shrink-0 items-center justify-center rounded-md border border-border-primary bg-surface text-fg-secondary transition-colors duration-[var(--duration-sm)] ease-enter group-hover/navigation-link:border-border-secondary group-hover/navigation-link:bg-background-quaternary group-hover/navigation-link:text-fg-primary [&_svg]:size-4",
138
373
  className,
139
374
  )}
140
375
  {...props}
141
376
  />
142
377
  )
143
378
 
379
+ export const NavigationMenuLinkTitle = ({
380
+ className,
381
+ ...props
382
+ }: NavigationMenuLinkTitleProps) => (
383
+ <span
384
+ className={cn("text-sm-strong text-fg-primary", className)}
385
+ {...props}
386
+ />
387
+ )
388
+
389
+ export const NavigationMenuLinkDescription = ({
390
+ className,
391
+ ...props
392
+ }: NavigationMenuLinkDescriptionProps) => (
393
+ <span
394
+ className={cn("text-xs leading-relaxed text-fg-tertiary", className)}
395
+ {...props}
396
+ />
397
+ )
398
+
144
399
  export const NavigationMenuPortal = (props: NavigationMenuPortalProps) => (
145
400
  <BaseNavigationMenu.Portal {...props} />
146
401
  )
@@ -161,12 +416,17 @@ export const NavigationMenuBackdrop = ({
161
416
 
162
417
  export const NavigationMenuPositioner = ({
163
418
  sideOffset = 8,
419
+ collisionPadding = 16,
164
420
  className,
165
421
  ...props
166
422
  }: NavigationMenuPositionerProps) => (
167
423
  <BaseNavigationMenu.Positioner
168
424
  sideOffset={sideOffset}
169
- className={cn("z-50 outline-none", className)}
425
+ collisionPadding={collisionPadding}
426
+ className={cn(
427
+ "z-50 h-[var(--positioner-height)] w-[var(--positioner-width)] max-w-[var(--available-width)] outline-none transition-[top,left,right,bottom] duration-[var(--duration-md)] ease-move data-instant:transition-none before:absolute before:content-[''] data-[side=bottom]:before:top-[-8px] data-[side=bottom]:before:right-0 data-[side=bottom]:before:left-0 data-[side=bottom]:before:h-2 data-[side=left]:before:top-0 data-[side=left]:before:right-[-8px] data-[side=left]:before:bottom-0 data-[side=left]:before:w-2 data-[side=right]:before:top-0 data-[side=right]:before:bottom-0 data-[side=right]:before:left-[-8px] data-[side=right]:before:w-2 data-[side=top]:before:right-0 data-[side=top]:before:bottom-[-8px] data-[side=top]:before:left-0 data-[side=top]:before:h-2",
428
+ className,
429
+ )}
170
430
  {...props}
171
431
  />
172
432
  )
@@ -177,9 +437,10 @@ export const NavigationMenuPopup = ({
177
437
  }: NavigationMenuPopupProps) => (
178
438
  <BaseNavigationMenu.Popup
179
439
  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",
440
+ "relative z-50 h-[var(--popup-height)] w-[var(--popup-width)] max-w-[calc(100vw-2rem)]",
441
+ popupSurface,
442
+ motion.popupAnchor,
443
+ "transition-[width,height,transform,scale,opacity] duration-[var(--duration-md)]",
183
444
  className,
184
445
  )}
185
446
  {...props}
@@ -202,16 +463,24 @@ export const NavigationMenuArrow = ({
202
463
  }: NavigationMenuArrowProps) => (
203
464
  <BaseNavigationMenu.Arrow
204
465
  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",
466
+ "relative block h-1.5 w-3 overflow-clip transition-[top,right,bottom,left] duration-[var(--duration-md)] ease-move before:absolute before:bottom-0 before:left-1/2 before:block before:size-[calc(6px*1.414)] before:-translate-x-1/2 before:translate-y-1/2 before:rotate-45 before:border before:border-border-primary before:bg-surface before:content-['']",
467
+ "data-[side=bottom]:top-[-6px] data-[side=left]:right-[-9px] data-[side=left]:rotate-90 data-[side=right]:left-[-9px] data-[side=right]:-rotate-90 data-[side=top]:bottom-[-6px] data-[side=top]:rotate-180",
211
468
  className,
212
469
  )}
213
470
  {...props}
214
471
  />
215
472
  )
216
473
 
217
- export { navigationMenuTriggerClassName }
474
+ const navigationMenuTriggerClassName = navigationMenuBarItemVariants({
475
+ orientation: "horizontal",
476
+ size: "md",
477
+ variant: "plain",
478
+ })
479
+
480
+ export {
481
+ navigationMenuBarItemVariants,
482
+ navigationMenuLinkVariants,
483
+ navigationMenuListVariants,
484
+ navigationMenuRootVariants,
485
+ navigationMenuTriggerClassName,
486
+ }