@betterstart/cli 0.1.28 → 0.1.30

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 (65) hide show
  1. package/dist/{chunk-SAPJG4NO.js → chunk-6JCWMKSY.js} +7 -4
  2. package/dist/{chunk-SAPJG4NO.js.map → chunk-6JCWMKSY.js.map} +1 -1
  3. package/dist/cli.js +749 -866
  4. package/dist/cli.js.map +1 -1
  5. package/dist/drizzle-config-EDKOEZ6G.js +7 -0
  6. package/package.json +1 -1
  7. package/templates/ui/accordion.tsx +73 -42
  8. package/templates/ui/alert-dialog.tsx +155 -90
  9. package/templates/ui/alert.tsx +46 -26
  10. package/templates/ui/aspect-ratio.tsx +4 -2
  11. package/templates/ui/avatar.tsx +92 -43
  12. package/templates/ui/badge.tsx +27 -12
  13. package/templates/ui/breadcrumb.tsx +63 -60
  14. package/templates/ui/button-group.tsx +8 -8
  15. package/templates/ui/button.tsx +44 -26
  16. package/templates/ui/calendar.tsx +43 -34
  17. package/templates/ui/card.tsx +71 -34
  18. package/templates/ui/carousel.tsx +111 -115
  19. package/templates/ui/chart.tsx +197 -207
  20. package/templates/ui/checkbox.tsx +21 -20
  21. package/templates/ui/collapsible.tsx +14 -4
  22. package/templates/ui/combobox.tsx +272 -0
  23. package/templates/ui/command.tsx +139 -101
  24. package/templates/ui/context-menu.tsx +214 -156
  25. package/templates/ui/dialog.tsx +118 -77
  26. package/templates/ui/direction.tsx +20 -0
  27. package/templates/ui/drawer.tsx +89 -69
  28. package/templates/ui/dropdown-menu.tsx +228 -164
  29. package/templates/ui/empty.tsx +8 -5
  30. package/templates/ui/field.tsx +25 -32
  31. package/templates/ui/hover-card.tsx +29 -20
  32. package/templates/ui/input-group.tsx +20 -37
  33. package/templates/ui/input-otp.tsx +57 -42
  34. package/templates/ui/input.tsx +14 -17
  35. package/templates/ui/item.tsx +27 -17
  36. package/templates/ui/kbd.tsx +1 -3
  37. package/templates/ui/label.tsx +14 -14
  38. package/templates/ui/markdown-editor.tsx +1 -1
  39. package/templates/ui/menubar.tsx +220 -188
  40. package/templates/ui/native-select.tsx +42 -0
  41. package/templates/ui/navigation-menu.tsx +130 -90
  42. package/templates/ui/pagination.tsx +88 -73
  43. package/templates/ui/popover.tsx +67 -26
  44. package/templates/ui/progress.tsx +24 -18
  45. package/templates/ui/radio-group.tsx +26 -20
  46. package/templates/ui/resizable.tsx +29 -29
  47. package/templates/ui/scroll-area.tsx +47 -38
  48. package/templates/ui/select.tsx +158 -125
  49. package/templates/ui/separator.tsx +21 -19
  50. package/templates/ui/sheet.tsx +104 -95
  51. package/templates/ui/sidebar.tsx +77 -183
  52. package/templates/ui/skeleton.tsx +8 -2
  53. package/templates/ui/slider.tsx +46 -17
  54. package/templates/ui/sonner.tsx +19 -9
  55. package/templates/ui/spinner.tsx +2 -2
  56. package/templates/ui/switch.tsx +24 -20
  57. package/templates/ui/table.tsx +68 -73
  58. package/templates/ui/tabs.tsx +71 -46
  59. package/templates/ui/textarea.tsx +13 -16
  60. package/templates/ui/toggle-group.tsx +57 -28
  61. package/templates/ui/toggle.tsx +21 -20
  62. package/templates/ui/tooltip.tsx +44 -23
  63. package/dist/drizzle-config-KISB26BA.js +0 -7
  64. package/templates/ui/use-mobile.tsx +0 -19
  65. /package/dist/{drizzle-config-KISB26BA.js.map → drizzle-config-EDKOEZ6G.js.map} +0 -0
@@ -1,46 +1,95 @@
1
1
  'use client'
2
2
 
3
3
  import { cn } from '@cms/utils/cn'
4
- import * as AvatarPrimitive from '@radix-ui/react-avatar'
5
- import * as React from 'react'
6
-
7
- const Avatar = React.forwardRef<
8
- React.ElementRef<typeof AvatarPrimitive.Root>,
9
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Root>
10
- >(({ className, ...props }, ref) => (
11
- <AvatarPrimitive.Root
12
- ref={ref}
13
- className={cn('relative flex h-10 w-10 shrink-0 overflow-hidden rounded-full', className)}
14
- {...props}
15
- />
16
- ))
17
- Avatar.displayName = AvatarPrimitive.Root.displayName
18
-
19
- const AvatarImage = React.forwardRef<
20
- React.ElementRef<typeof AvatarPrimitive.Image>,
21
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Image>
22
- >(({ className, ...props }, ref) => (
23
- <AvatarPrimitive.Image
24
- ref={ref}
25
- className={cn('aspect-square h-full w-full', className)}
26
- {...props}
27
- />
28
- ))
29
- AvatarImage.displayName = AvatarPrimitive.Image.displayName
30
-
31
- const AvatarFallback = React.forwardRef<
32
- React.ElementRef<typeof AvatarPrimitive.Fallback>,
33
- React.ComponentPropsWithoutRef<typeof AvatarPrimitive.Fallback>
34
- >(({ className, ...props }, ref) => (
35
- <AvatarPrimitive.Fallback
36
- ref={ref}
37
- className={cn(
38
- 'flex h-full w-full items-center justify-center rounded-full bg-muted',
39
- className
40
- )}
41
- {...props}
42
- />
43
- ))
44
- AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName
45
-
46
- export { Avatar, AvatarImage, AvatarFallback }
4
+ import { Avatar as AvatarPrimitive } from 'radix-ui'
5
+ import type * as React from 'react'
6
+
7
+ function Avatar({
8
+ className,
9
+ size = 'default',
10
+ ...props
11
+ }: React.ComponentProps<typeof AvatarPrimitive.Root> & {
12
+ size?: 'default' | 'sm' | 'lg'
13
+ }) {
14
+ return (
15
+ <AvatarPrimitive.Root
16
+ data-slot="avatar"
17
+ data-size={size}
18
+ className={cn(
19
+ 'after:border-border group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten',
20
+ className
21
+ )}
22
+ {...props}
23
+ />
24
+ )
25
+ }
26
+
27
+ function AvatarImage({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Image>) {
28
+ return (
29
+ <AvatarPrimitive.Image
30
+ data-slot="avatar-image"
31
+ className={cn('aspect-square size-full rounded-full object-cover', className)}
32
+ {...props}
33
+ />
34
+ )
35
+ }
36
+
37
+ function AvatarFallback({
38
+ className,
39
+ ...props
40
+ }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {
41
+ return (
42
+ <AvatarPrimitive.Fallback
43
+ data-slot="avatar-fallback"
44
+ className={cn(
45
+ 'bg-muted text-muted-foreground flex size-full items-center justify-center rounded-full text-sm group-data-[size=sm]/avatar:text-xs',
46
+ className
47
+ )}
48
+ {...props}
49
+ />
50
+ )
51
+ }
52
+
53
+ function AvatarBadge({ className, ...props }: React.ComponentProps<'span'>) {
54
+ return (
55
+ <span
56
+ data-slot="avatar-badge"
57
+ className={cn(
58
+ 'bg-primary text-primary-foreground ring-background absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-blend-color ring-2 select-none',
59
+ 'group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden',
60
+ 'group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2',
61
+ 'group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2',
62
+ className
63
+ )}
64
+ {...props}
65
+ />
66
+ )
67
+ }
68
+
69
+ function AvatarGroup({ className, ...props }: React.ComponentProps<'div'>) {
70
+ return (
71
+ <div
72
+ data-slot="avatar-group"
73
+ className={cn(
74
+ '*:data-[slot=avatar]:ring-background group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2',
75
+ className
76
+ )}
77
+ {...props}
78
+ />
79
+ )
80
+ }
81
+
82
+ function AvatarGroupCount({ className, ...props }: React.ComponentProps<'div'>) {
83
+ return (
84
+ <div
85
+ data-slot="avatar-group-count"
86
+ className={cn(
87
+ 'bg-muted text-muted-foreground ring-background relative flex size-8 shrink-0 items-center justify-center rounded-full text-sm ring-2 group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3',
88
+ className
89
+ )}
90
+ {...props}
91
+ />
92
+ )
93
+ }
94
+
95
+ export { Avatar, AvatarImage, AvatarFallback, AvatarGroup, AvatarGroupCount, AvatarBadge }
@@ -1,18 +1,20 @@
1
1
  import { cn } from '@cms/utils/cn'
2
2
  import { cva, type VariantProps } from 'class-variance-authority'
3
+ import { Slot } from 'radix-ui'
3
4
  import type * as React from 'react'
4
5
 
5
6
  const badgeVariants = cva(
6
- 'inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
7
+ 'h-5 gap-1 rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium transition-all has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:size-3! inline-flex items-center justify-center w-fit whitespace-nowrap shrink-0 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive overflow-hidden group/badge',
7
8
  {
8
9
  variants: {
9
10
  variant: {
10
- default: 'border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80',
11
- secondary:
12
- 'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',
11
+ default: 'bg-primary text-primary-foreground [a]:hover:bg-primary/80',
12
+ secondary: 'bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80',
13
13
  destructive:
14
- 'border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80',
15
- outline: 'text-foreground'
14
+ 'bg-destructive/10 [a]:hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 text-destructive dark:bg-destructive/20',
15
+ outline: 'border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground',
16
+ ghost: 'hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50',
17
+ link: 'text-primary underline-offset-4 hover:underline'
16
18
  }
17
19
  },
18
20
  defaultVariants: {
@@ -21,12 +23,25 @@ const badgeVariants = cva(
21
23
  }
22
24
  )
23
25
 
24
- export interface BadgeProps
25
- extends React.HTMLAttributes<HTMLDivElement>,
26
- VariantProps<typeof badgeVariants> {}
26
+ function Badge({
27
+ className,
28
+ variant = 'default',
29
+ asChild = false,
30
+ ...props
31
+ }: React.ComponentProps<'span'> & VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
32
+ const Comp = asChild ? Slot.Root : 'span'
27
33
 
28
- function Badge({ className, variant, ...props }: BadgeProps) {
29
- return <div className={cn(badgeVariants({ variant }), className)} {...props} />
34
+ return (
35
+ <Comp
36
+ data-slot="badge"
37
+ data-variant={variant}
38
+ className={cn(badgeVariants({ variant }), className)}
39
+ {...props}
40
+ />
41
+ )
30
42
  }
31
43
 
32
- export { Badge, badgeVariants }
44
+ type BadgeProps = React.ComponentProps<'span'> &
45
+ VariantProps<typeof badgeVariants> & { asChild?: boolean }
46
+
47
+ export { Badge, badgeVariants, type BadgeProps }
@@ -1,91 +1,94 @@
1
1
  import { cn } from '@cms/utils/cn'
2
- import { Slot } from '@radix-ui/react-slot'
3
2
  import { ChevronRight, MoreHorizontal } from 'lucide-react'
4
- import * as React from 'react'
3
+ import { Slot } from 'radix-ui'
4
+ import type * as React from 'react'
5
5
 
6
- const Breadcrumb = React.forwardRef<
7
- HTMLElement,
8
- React.ComponentPropsWithoutRef<'nav'> & {
9
- separator?: React.ReactNode
10
- }
11
- >(({ ...props }, ref) => <nav ref={ref} aria-label="breadcrumb" {...props} />)
12
- Breadcrumb.displayName = 'Breadcrumb'
6
+ function Breadcrumb({ className, ...props }: React.ComponentProps<'nav'>) {
7
+ return <nav aria-label="breadcrumb" data-slot="breadcrumb" className={cn(className)} {...props} />
8
+ }
13
9
 
14
- const BreadcrumbList = React.forwardRef<HTMLOListElement, React.ComponentPropsWithoutRef<'ol'>>(
15
- ({ className, ...props }, ref) => (
10
+ function BreadcrumbList({ className, ...props }: React.ComponentProps<'ol'>) {
11
+ return (
16
12
  <ol
17
- ref={ref}
13
+ data-slot="breadcrumb-list"
18
14
  className={cn(
19
- 'flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5',
15
+ 'text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm wrap-break-word',
20
16
  className
21
17
  )}
22
18
  {...props}
23
19
  />
24
20
  )
25
- )
26
- BreadcrumbList.displayName = 'BreadcrumbList'
21
+ }
27
22
 
28
- const BreadcrumbItem = React.forwardRef<HTMLLIElement, React.ComponentPropsWithoutRef<'li'>>(
29
- ({ className, ...props }, ref) => (
30
- <li ref={ref} className={cn('inline-flex items-center gap-1.5', className)} {...props} />
23
+ function BreadcrumbItem({ className, ...props }: React.ComponentProps<'li'>) {
24
+ return (
25
+ <li
26
+ data-slot="breadcrumb-item"
27
+ className={cn('inline-flex items-center gap-1', className)}
28
+ {...props}
29
+ />
31
30
  )
32
- )
33
- BreadcrumbItem.displayName = 'BreadcrumbItem'
31
+ }
34
32
 
35
- const BreadcrumbLink = React.forwardRef<
36
- HTMLAnchorElement,
37
- React.ComponentPropsWithoutRef<'a'> & {
38
- asChild?: boolean
39
- }
40
- >(({ asChild, className, ...props }, ref) => {
41
- const Comp = asChild ? Slot : 'a'
33
+ function BreadcrumbLink({
34
+ asChild,
35
+ className,
36
+ ...props
37
+ }: React.ComponentProps<'a'> & {
38
+ asChild?: boolean
39
+ }) {
40
+ const Comp = asChild ? Slot.Root : 'a'
42
41
 
43
42
  return (
44
43
  <Comp
45
- ref={ref}
46
- className={cn('transition-colors hover:text-foreground', className)}
44
+ data-slot="breadcrumb-link"
45
+ className={cn('hover:text-foreground transition-colors', className)}
47
46
  {...props}
48
47
  />
49
48
  )
50
- })
51
- BreadcrumbLink.displayName = 'BreadcrumbLink'
49
+ }
52
50
 
53
- const BreadcrumbPage = React.forwardRef<HTMLSpanElement, React.ComponentPropsWithoutRef<'span'>>(
54
- ({ className, ...props }, ref) => (
51
+ function BreadcrumbPage({ className, ...props }: React.ComponentProps<'span'>) {
52
+ return (
55
53
  <span
56
- ref={ref}
54
+ data-slot="breadcrumb-page"
55
+ role="link"
56
+ aria-disabled="true"
57
57
  aria-current="page"
58
- className={cn('font-normal text-foreground', className)}
58
+ className={cn('text-foreground font-normal', className)}
59
59
  {...props}
60
60
  />
61
61
  )
62
- )
63
- BreadcrumbPage.displayName = 'BreadcrumbPage'
62
+ }
64
63
 
65
- const BreadcrumbSeparator = ({ children, className, ...props }: React.ComponentProps<'li'>) => (
66
- <li
67
- role="presentation"
68
- aria-hidden="true"
69
- className={cn('[&>svg]:w-3.5 [&>svg]:h-3.5', className)}
70
- {...props}
71
- >
72
- {children ?? <ChevronRight />}
73
- </li>
74
- )
75
- BreadcrumbSeparator.displayName = 'BreadcrumbSeparator'
64
+ function BreadcrumbSeparator({ children, className, ...props }: React.ComponentProps<'li'>) {
65
+ return (
66
+ <li
67
+ data-slot="breadcrumb-separator"
68
+ role="presentation"
69
+ aria-hidden="true"
70
+ className={cn('[&>svg]:size-3.5', className)}
71
+ {...props}
72
+ >
73
+ {children ?? <ChevronRight />}
74
+ </li>
75
+ )
76
+ }
76
77
 
77
- const BreadcrumbEllipsis = ({ className, ...props }: React.ComponentProps<'span'>) => (
78
- <span
79
- role="presentation"
80
- aria-hidden="true"
81
- className={cn('flex h-9 w-9 items-center justify-center', className)}
82
- {...props}
83
- >
84
- <MoreHorizontal className="size-4" />
85
- <span className="sr-only">More</span>
86
- </span>
87
- )
88
- BreadcrumbEllipsis.displayName = 'BreadcrumbElipssis'
78
+ function BreadcrumbEllipsis({ className, ...props }: React.ComponentProps<'span'>) {
79
+ return (
80
+ <span
81
+ data-slot="breadcrumb-ellipsis"
82
+ role="presentation"
83
+ aria-hidden="true"
84
+ className={cn('flex size-5 items-center justify-center [&>svg]:size-4', className)}
85
+ {...props}
86
+ >
87
+ <MoreHorizontal />
88
+ <span className="sr-only">More</span>
89
+ </span>
90
+ )
91
+ }
89
92
 
90
93
  export {
91
94
  Breadcrumb,
@@ -1,17 +1,17 @@
1
+ import { Separator } from '@cms/components/ui/separator'
1
2
  import { cn } from '@cms/utils/cn'
2
- import { Slot } from '@radix-ui/react-slot'
3
3
  import { cva, type VariantProps } from 'class-variance-authority'
4
- import { Separator } from './separator'
4
+ import { Slot } from 'radix-ui'
5
5
 
6
6
  const buttonGroupVariants = cva(
7
- "flex w-fit items-stretch has-[>[data-slot=button-group]]:gap-2 [&>*]:focus-visible:relative [&>*]:focus-visible:z-10 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1",
7
+ "has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-lg flex w-fit items-stretch *:focus-visible:z-10 *:focus-visible:relative [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1",
8
8
  {
9
9
  variants: {
10
10
  orientation: {
11
11
  horizontal:
12
- '[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none',
12
+ '[&>[data-slot]:not(:has(~[data-slot]))]:rounded-r-lg! [&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none',
13
13
  vertical:
14
- 'flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none'
14
+ '[&>[data-slot]:not(:has(~[data-slot]))]:rounded-b-lg! flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none'
15
15
  }
16
16
  },
17
17
  defaultVariants: {
@@ -43,12 +43,12 @@ function ButtonGroupText({
43
43
  }: React.ComponentProps<'div'> & {
44
44
  asChild?: boolean
45
45
  }) {
46
- const Comp = asChild ? Slot : 'div'
46
+ const Comp = asChild ? Slot.Root : 'div'
47
47
 
48
48
  return (
49
49
  <Comp
50
50
  className={cn(
51
- "bg-muted shadow-xs flex items-center gap-2 rounded-md border px-4 text-sm font-medium [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none",
51
+ "bg-muted flex items-center gap-2 rounded-lg border px-2.5 text-sm font-medium [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
52
52
  className
53
53
  )}
54
54
  {...props}
@@ -66,7 +66,7 @@ function ButtonGroupSeparator({
66
66
  data-slot="button-group-separator"
67
67
  orientation={orientation}
68
68
  className={cn(
69
- 'bg-input relative !m-0 self-stretch data-[orientation=vertical]:h-auto',
69
+ 'bg-input relative self-stretch data-horizontal:mx-px data-horizontal:w-auto data-vertical:my-px data-vertical:h-auto',
70
70
  className
71
71
  )}
72
72
  {...props}
@@ -1,25 +1,36 @@
1
1
  import { cn } from '@cms/utils/cn'
2
- import { Slot } from '@radix-ui/react-slot'
3
2
  import { cva, type VariantProps } from 'class-variance-authority'
4
- import * as React from 'react'
3
+ import { Slot } from 'radix-ui'
4
+ import type * as React from 'react'
5
5
 
6
6
  const buttonVariants = cva(
7
- 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
7
+ "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-lg border border-transparent bg-clip-padding text-sm font-medium focus-visible:ring-3 aria-invalid:ring-3 [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none",
8
8
  {
9
9
  variants: {
10
10
  variant: {
11
- default: 'bg-primary text-primary-foreground hover:bg-primary/90',
12
- destructive: 'bg-destructive text-white hover:bg-destructive/90',
13
- outline: 'border border-border bg-background hover:bg-accent hover:text-accent-foreground',
14
- secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
15
- ghost: 'hover:bg-accent hover:text-accent-foreground',
11
+ default: 'bg-primary text-primary-foreground [a]:hover:bg-primary/80',
12
+ outline:
13
+ 'border-border bg-background hover:bg-muted hover:text-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 aria-expanded:bg-muted aria-expanded:text-foreground',
14
+ secondary:
15
+ 'bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground',
16
+ ghost:
17
+ 'hover:bg-muted hover:text-foreground dark:hover:bg-muted/50 aria-expanded:bg-muted aria-expanded:text-foreground',
18
+ destructive:
19
+ 'bg-destructive/10 hover:bg-destructive/20 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/20 text-destructive focus-visible:border-destructive/40 dark:hover:bg-destructive/30',
16
20
  link: 'text-primary underline-offset-4 hover:underline'
17
21
  },
18
22
  size: {
19
- default: 'h-9 px-4 py-2',
20
- sm: 'h-8 rounded-md px-3 text-xs',
21
- lg: 'h-10 rounded-md px-8',
22
- icon: 'h-9 w-9'
23
+ default:
24
+ 'h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2',
25
+ xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
26
+ sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
27
+ lg: 'h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3',
28
+ icon: 'size-8',
29
+ 'icon-xs':
30
+ "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
31
+ 'icon-sm':
32
+ 'size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg',
33
+ 'icon-lg': 'size-9'
23
34
  }
24
35
  },
25
36
  defaultVariants: {
@@ -29,20 +40,27 @@ const buttonVariants = cva(
29
40
  }
30
41
  )
31
42
 
32
- export interface ButtonProps
33
- extends React.ButtonHTMLAttributes<HTMLButtonElement>,
34
- VariantProps<typeof buttonVariants> {
35
- asChild?: boolean
36
- }
43
+ function Button({
44
+ className,
45
+ variant = 'default',
46
+ size = 'default',
47
+ asChild = false,
48
+ ...props
49
+ }: React.ComponentProps<'button'> &
50
+ VariantProps<typeof buttonVariants> & {
51
+ asChild?: boolean
52
+ }) {
53
+ const Comp = asChild ? Slot.Root : 'button'
37
54
 
38
- const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
39
- ({ className, variant, size, asChild = false, ...props }, ref) => {
40
- const Comp = asChild ? Slot : 'button'
41
- return (
42
- <Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />
43
- )
44
- }
45
- )
46
- Button.displayName = 'Button'
55
+ return (
56
+ <Comp
57
+ data-slot="button"
58
+ data-variant={variant}
59
+ data-size={size}
60
+ className={cn(buttonVariants({ variant, size, className }))}
61
+ {...props}
62
+ />
63
+ )
64
+ }
47
65
 
48
66
  export { Button, buttonVariants }