@autono/create-open-pages 0.4.0 → 0.6.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 (63) hide show
  1. package/dist/cli.js +30 -2
  2. package/package.json +1 -1
  3. package/template/.agents/skills/create-page/SKILL.md +1 -1
  4. package/template/.agents/skills/page-authoring/SKILL.md +2 -2
  5. package/template/.agents/skills/page-authoring/references/interactivity.md +13 -21
  6. package/template/README.md +2 -1
  7. package/template/components.json +19 -3
  8. package/template/package.json +7 -7
  9. package/template/styles/globals.css +83 -66
  10. package/template/ui/accordion.tsx +22 -7
  11. package/template/ui/alert-dialog.tsx +22 -21
  12. package/template/ui/alert.tsx +15 -5
  13. package/template/ui/avatar.tsx +7 -4
  14. package/template/ui/badge.tsx +8 -7
  15. package/template/ui/breadcrumb.tsx +21 -8
  16. package/template/ui/button-group.tsx +5 -5
  17. package/template/ui/button.tsx +18 -15
  18. package/template/ui/calendar.tsx +28 -24
  19. package/template/ui/card.tsx +17 -6
  20. package/template/ui/carousel.tsx +10 -11
  21. package/template/ui/chart.tsx +1 -2
  22. package/template/ui/checkbox.tsx +5 -6
  23. package/template/ui/collapsible.tsx +2 -0
  24. package/template/ui/combobox.tsx +9 -20
  25. package/template/ui/command.tsx +39 -26
  26. package/template/ui/context-menu.tsx +69 -60
  27. package/template/ui/dialog.tsx +26 -14
  28. package/template/ui/drawer.tsx +8 -9
  29. package/template/ui/dropdown-menu.tsx +34 -22
  30. package/template/ui/empty.tsx +8 -8
  31. package/template/ui/field.tsx +15 -25
  32. package/template/ui/hover-card.tsx +1 -1
  33. package/template/ui/input-group.tsx +10 -24
  34. package/template/ui/input-otp.tsx +16 -6
  35. package/template/ui/input.tsx +1 -3
  36. package/template/ui/item.tsx +17 -14
  37. package/template/ui/kbd.tsx +1 -3
  38. package/template/ui/menubar.tsx +28 -24
  39. package/template/ui/message-scroller.tsx +5 -4
  40. package/template/ui/native-select.tsx +13 -14
  41. package/template/ui/navigation-menu.tsx +8 -12
  42. package/template/ui/pagination.tsx +35 -33
  43. package/template/ui/popover.tsx +5 -5
  44. package/template/ui/progress.tsx +2 -2
  45. package/template/ui/radio-group.tsx +4 -5
  46. package/template/ui/resizable.tsx +2 -5
  47. package/template/ui/scroll-area.tsx +2 -5
  48. package/template/ui/select.tsx +26 -24
  49. package/template/ui/separator.tsx +1 -1
  50. package/template/ui/sheet.tsx +20 -16
  51. package/template/ui/sidebar.tsx +39 -63
  52. package/template/ui/skeleton.tsx +1 -1
  53. package/template/ui/slider.tsx +6 -8
  54. package/template/ui/sonner.tsx +21 -14
  55. package/template/ui/spinner.tsx +2 -8
  56. package/template/ui/switch.tsx +4 -4
  57. package/template/ui/table.tsx +2 -4
  58. package/template/ui/tabs.tsx +9 -8
  59. package/template/ui/textarea.tsx +1 -1
  60. package/template/ui/toggle-group.tsx +14 -8
  61. package/template/ui/toggle.tsx +8 -10
  62. package/template/ui/tooltip.tsx +4 -2
  63. package/template/ui/form.tsx +0 -167
@@ -15,7 +15,7 @@ function Avatar({
15
15
  data-slot="avatar"
16
16
  data-size={size}
17
17
  className={cn(
18
- "group/avatar relative flex size-8 shrink-0 overflow-hidden rounded-full select-none data-[size=lg]:size-10 data-[size=sm]:size-6",
18
+ "group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:border-border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten",
19
19
  className
20
20
  )}
21
21
  {...props}
@@ -30,7 +30,10 @@ function AvatarImage({
30
30
  return (
31
31
  <AvatarPrimitive.Image
32
32
  data-slot="avatar-image"
33
- className={cn("aspect-square size-full", className)}
33
+ className={cn(
34
+ "aspect-square size-full rounded-full object-cover",
35
+ className
36
+ )}
34
37
  {...props}
35
38
  />
36
39
  )
@@ -57,7 +60,7 @@ function AvatarBadge({ className, ...props }: React.ComponentProps<"span">) {
57
60
  <span
58
61
  data-slot="avatar-badge"
59
62
  className={cn(
60
- "absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground ring-2 ring-background select-none",
63
+ "absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground bg-blend-color ring-2 ring-background select-none",
61
64
  "group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden",
62
65
  "group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
63
66
  "group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
@@ -101,7 +104,7 @@ export {
101
104
  Avatar,
102
105
  AvatarImage,
103
106
  AvatarFallback,
104
- AvatarBadge,
105
107
  AvatarGroup,
106
108
  AvatarGroupCount,
109
+ AvatarBadge,
107
110
  }
@@ -5,19 +5,20 @@ import { Slot } from "radix-ui"
5
5
  import { cn } from "@/lib/utils"
6
6
 
7
7
  const badgeVariants = cva(
8
- "inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3",
8
+ "group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!",
9
9
  {
10
10
  variants: {
11
11
  variant: {
12
- default: "bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
12
+ default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
13
13
  secondary:
14
- "bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
14
+ "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
15
15
  destructive:
16
- "bg-destructive text-white focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/90",
16
+ "bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20",
17
17
  outline:
18
- "border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
19
- ghost: "[a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
20
- link: "text-primary underline-offset-4 [a&]:hover:underline",
18
+ "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
19
+ ghost:
20
+ "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
21
+ link: "text-primary underline-offset-4 hover:underline",
21
22
  },
22
23
  },
23
24
  defaultVariants: {
@@ -1,11 +1,18 @@
1
1
  import * as React from "react"
2
- import { ChevronRight, MoreHorizontal } from "lucide-react"
3
2
  import { Slot } from "radix-ui"
4
3
 
5
4
  import { cn } from "@/lib/utils"
5
+ import { ChevronRightIcon, MoreHorizontalIcon } from "lucide-react"
6
6
 
7
- function Breadcrumb({ ...props }: React.ComponentProps<"nav">) {
8
- return <nav aria-label="breadcrumb" data-slot="breadcrumb" {...props} />
7
+ function Breadcrumb({ className, ...props }: React.ComponentProps<"nav">) {
8
+ return (
9
+ <nav
10
+ aria-label="breadcrumb"
11
+ data-slot="breadcrumb"
12
+ className={cn(className)}
13
+ {...props}
14
+ />
15
+ )
9
16
  }
10
17
 
11
18
  function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">) {
@@ -13,7 +20,7 @@ function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">) {
13
20
  <ol
14
21
  data-slot="breadcrumb-list"
15
22
  className={cn(
16
- "flex flex-wrap items-center gap-1.5 text-sm break-words text-muted-foreground sm:gap-2.5",
23
+ "flex flex-wrap items-center gap-1.5 text-sm wrap-break-word text-muted-foreground",
17
24
  className
18
25
  )}
19
26
  {...props}
@@ -25,7 +32,7 @@ function BreadcrumbItem({ className, ...props }: React.ComponentProps<"li">) {
25
32
  return (
26
33
  <li
27
34
  data-slot="breadcrumb-item"
28
- className={cn("inline-flex items-center gap-1.5", className)}
35
+ className={cn("inline-flex items-center gap-1", className)}
29
36
  {...props}
30
37
  />
31
38
  )
@@ -75,7 +82,9 @@ function BreadcrumbSeparator({
75
82
  className={cn("[&>svg]:size-3.5", className)}
76
83
  {...props}
77
84
  >
78
- {children ?? <ChevronRight />}
85
+ {children ?? (
86
+ <ChevronRightIcon />
87
+ )}
79
88
  </li>
80
89
  )
81
90
  }
@@ -89,10 +98,14 @@ function BreadcrumbEllipsis({
89
98
  data-slot="breadcrumb-ellipsis"
90
99
  role="presentation"
91
100
  aria-hidden="true"
92
- className={cn("flex size-9 items-center justify-center", className)}
101
+ className={cn(
102
+ "flex size-5 items-center justify-center [&>svg]:size-4",
103
+ className
104
+ )}
93
105
  {...props}
94
106
  >
95
- <MoreHorizontal className="size-4" />
107
+ <MoreHorizontalIcon
108
+ />
96
109
  <span className="sr-only">More</span>
97
110
  </span>
98
111
  )
@@ -5,14 +5,14 @@ import { cn } from "@/lib/utils"
5
5
  import { Separator } from "@/ui/separator"
6
6
 
7
7
  const buttonGroupVariants = cva(
8
- "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",
8
+ "group/button-group flex w-fit items-stretch *:focus-visible:relative *:focus-visible:z-10 has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-lg [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1",
9
9
  {
10
10
  variants: {
11
11
  orientation: {
12
12
  horizontal:
13
- "[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none",
13
+ "[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none [&>[data-slot]:not(:has(~[data-slot]))]:rounded-r-lg!",
14
14
  vertical:
15
- "flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none",
15
+ "flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none [&>[data-slot]:not(:has(~[data-slot]))]:rounded-b-lg!",
16
16
  },
17
17
  },
18
18
  defaultVariants: {
@@ -49,7 +49,7 @@ function ButtonGroupText({
49
49
  return (
50
50
  <Comp
51
51
  className={cn(
52
- "flex items-center gap-2 rounded-md border bg-muted px-4 text-sm font-medium shadow-xs [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
52
+ "flex items-center gap-2 rounded-lg border bg-muted px-2.5 text-sm font-medium [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
53
53
  className
54
54
  )}
55
55
  {...props}
@@ -67,7 +67,7 @@ function ButtonGroupSeparator({
67
67
  data-slot="button-group-separator"
68
68
  orientation={orientation}
69
69
  className={cn(
70
- "relative m-0! self-stretch bg-input data-[orientation=vertical]:h-auto",
70
+ "relative self-stretch bg-input data-horizontal:mx-px data-horizontal:w-auto data-vertical:my-px data-vertical:h-auto",
71
71
  className
72
72
  )}
73
73
  {...props}
@@ -5,30 +5,33 @@ import { Slot } from "radix-ui"
5
5
  import { cn } from "@/lib/utils"
6
6
 
7
7
  const buttonVariants = cva(
8
- "inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
8
+ "group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
9
9
  {
10
10
  variants: {
11
11
  variant: {
12
- default: "bg-primary text-primary-foreground hover:bg-primary/90",
13
- destructive:
14
- "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
12
+ default: "bg-primary text-primary-foreground hover:bg-primary/80",
15
13
  outline:
16
- "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
14
+ "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
17
15
  secondary:
18
- "bg-secondary text-secondary-foreground hover:bg-secondary/80",
16
+ "bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground",
19
17
  ghost:
20
- "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
18
+ "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
19
+ destructive:
20
+ "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40",
21
21
  link: "text-primary underline-offset-4 hover:underline",
22
22
  },
23
23
  size: {
24
- default: "h-9 px-4 py-2 has-[>svg]:px-3",
25
- xs: "h-6 gap-1 rounded-md px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
26
- sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
27
- lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
28
- icon: "size-9",
29
- "icon-xs": "size-6 rounded-md [&_svg:not([class*='size-'])]:size-3",
30
- "icon-sm": "size-8",
31
- "icon-lg": "size-10",
24
+ default:
25
+ "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
26
+ 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",
27
+ 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",
28
+ lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
29
+ icon: "size-8",
30
+ "icon-xs":
31
+ "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
32
+ "icon-sm":
33
+ "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
34
+ "icon-lg": "size-9",
32
35
  },
33
36
  },
34
37
  defaultVariants: {
@@ -1,17 +1,16 @@
1
+ "use client"
2
+
1
3
  import * as React from "react"
2
- import {
3
- ChevronDownIcon,
4
- ChevronLeftIcon,
5
- ChevronRightIcon,
6
- } from "lucide-react"
7
4
  import {
8
5
  DayPicker,
9
6
  getDefaultClassNames,
10
7
  type DayButton,
8
+ type Locale,
11
9
  } from "react-day-picker"
12
10
 
13
11
  import { cn } from "@/lib/utils"
14
12
  import { Button, buttonVariants } from "@/ui/button"
13
+ import { ChevronLeftIcon, ChevronRightIcon, ChevronDownIcon } from "lucide-react"
15
14
 
16
15
  function Calendar({
17
16
  className,
@@ -19,6 +18,7 @@ function Calendar({
19
18
  showOutsideDays = true,
20
19
  captionLayout = "label",
21
20
  buttonVariant = "ghost",
21
+ locale,
22
22
  formatters,
23
23
  components,
24
24
  ...props
@@ -31,15 +31,16 @@ function Calendar({
31
31
  <DayPicker
32
32
  showOutsideDays={showOutsideDays}
33
33
  className={cn(
34
- "group/calendar bg-background p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
34
+ "group/calendar bg-background p-2 [--cell-radius:var(--radius-md)] [--cell-size:--spacing(7)] in-data-[slot=card-content]:bg-transparent in-data-[slot=popover-content]:bg-transparent",
35
35
  String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
36
36
  String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
37
37
  className
38
38
  )}
39
39
  captionLayout={captionLayout}
40
+ locale={locale}
40
41
  formatters={{
41
42
  formatMonthDropdown: (date) =>
42
- date.toLocaleString("default", { month: "short" }),
43
+ date.toLocaleString(locale?.code, { month: "short" }),
43
44
  ...formatters,
44
45
  }}
45
46
  classNames={{
@@ -72,7 +73,7 @@ function Calendar({
72
73
  defaultClassNames.dropdowns
73
74
  ),
74
75
  dropdown_root: cn(
75
- "relative rounded-md border border-input shadow-xs has-focus:border-ring has-focus:ring-[3px] has-focus:ring-ring/50",
76
+ "relative rounded-(--cell-radius)",
76
77
  defaultClassNames.dropdown_root
77
78
  ),
78
79
  dropdown: cn(
@@ -83,13 +84,13 @@ function Calendar({
83
84
  "font-medium select-none",
84
85
  captionLayout === "label"
85
86
  ? "text-sm"
86
- : "flex h-8 items-center gap-1 rounded-md pr-1 pl-2 text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground",
87
+ : "flex items-center gap-1 rounded-(--cell-radius) text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground",
87
88
  defaultClassNames.caption_label
88
89
  ),
89
90
  month_grid: cn("w-full border-collapse", defaultClassNames.month_grid),
90
91
  weekdays: cn("flex", defaultClassNames.weekdays),
91
92
  weekday: cn(
92
- "flex-1 rounded-md text-[0.8rem] font-normal text-muted-foreground select-none",
93
+ "flex-1 rounded-(--cell-radius) text-[0.8rem] font-normal text-muted-foreground select-none",
93
94
  defaultClassNames.weekday
94
95
  ),
95
96
  week: cn("mt-2 flex w-full", defaultClassNames.week),
@@ -102,20 +103,23 @@ function Calendar({
102
103
  defaultClassNames.week_number
103
104
  ),
104
105
  day: cn(
105
- "group/day relative aspect-square h-full w-full p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-md",
106
+ "group/day relative aspect-square h-full w-full rounded-(--cell-radius) p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-(--cell-radius)",
106
107
  props.showWeekNumber
107
- ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-md"
108
- : "[&:first-child[data-selected=true]_button]:rounded-l-md",
108
+ ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-(--cell-radius)"
109
+ : "[&:first-child[data-selected=true]_button]:rounded-l-(--cell-radius)",
109
110
  defaultClassNames.day
110
111
  ),
111
112
  range_start: cn(
112
- "rounded-l-md bg-accent",
113
+ "relative isolate z-0 rounded-l-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:right-0 after:w-4 after:bg-muted",
113
114
  defaultClassNames.range_start
114
115
  ),
115
116
  range_middle: cn("rounded-none", defaultClassNames.range_middle),
116
- range_end: cn("rounded-r-md bg-accent", defaultClassNames.range_end),
117
+ range_end: cn(
118
+ "relative isolate z-0 rounded-r-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:left-0 after:w-4 after:bg-muted",
119
+ defaultClassNames.range_end
120
+ ),
117
121
  today: cn(
118
- "rounded-md bg-accent text-accent-foreground data-[selected=true]:rounded-none",
122
+ "rounded-(--cell-radius) bg-muted text-foreground data-[selected=true]:rounded-none",
119
123
  defaultClassNames.today
120
124
  ),
121
125
  outside: cn(
@@ -149,10 +153,7 @@ function Calendar({
149
153
 
150
154
  if (orientation === "right") {
151
155
  return (
152
- <ChevronRightIcon
153
- className={cn("size-4", className)}
154
- {...props}
155
- />
156
+ <ChevronRightIcon className={cn("size-4", className)} {...props} />
156
157
  )
157
158
  }
158
159
 
@@ -160,7 +161,9 @@ function Calendar({
160
161
  <ChevronDownIcon className={cn("size-4", className)} {...props} />
161
162
  )
162
163
  },
163
- DayButton: CalendarDayButton,
164
+ DayButton: ({ ...props }) => (
165
+ <CalendarDayButton locale={locale} {...props} />
166
+ ),
164
167
  WeekNumber: ({ children, ...props }) => {
165
168
  return (
166
169
  <td {...props}>
@@ -181,8 +184,9 @@ function CalendarDayButton({
181
184
  className,
182
185
  day,
183
186
  modifiers,
187
+ locale,
184
188
  ...props
185
- }: React.ComponentProps<typeof DayButton>) {
189
+ }: React.ComponentProps<typeof DayButton> & { locale?: Partial<Locale> }) {
186
190
  const defaultClassNames = getDefaultClassNames()
187
191
 
188
192
  const ref = React.useRef<HTMLButtonElement>(null)
@@ -195,7 +199,7 @@ function CalendarDayButton({
195
199
  ref={ref}
196
200
  variant="ghost"
197
201
  size="icon"
198
- data-day={day.date.toLocaleDateString()}
202
+ data-day={day.date.toLocaleDateString(locale?.code)}
199
203
  data-selected-single={
200
204
  modifiers.selected &&
201
205
  !modifiers.range_start &&
@@ -206,7 +210,7 @@ function CalendarDayButton({
206
210
  data-range-end={modifiers.range_end}
207
211
  data-range-middle={modifiers.range_middle}
208
212
  className={cn(
209
- "flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-accent-foreground [&>span]:text-xs [&>span]:opacity-70",
213
+ "relative isolate z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 border-0 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-(--cell-radius) data-[range-end=true]:rounded-r-(--cell-radius) data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-muted data-[range-middle=true]:text-foreground data-[range-start=true]:rounded-(--cell-radius) data-[range-start=true]:rounded-l-(--cell-radius) data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-foreground [&>span]:text-xs [&>span]:opacity-70",
210
214
  defaultClassNames.day,
211
215
  className
212
216
  )}
@@ -2,12 +2,17 @@ import * as React from "react"
2
2
 
3
3
  import { cn } from "@/lib/utils"
4
4
 
5
- function Card({ className, ...props }: React.ComponentProps<"div">) {
5
+ function Card({
6
+ className,
7
+ size = "default",
8
+ ...props
9
+ }: React.ComponentProps<"div"> & { size?: "default" | "sm" }) {
6
10
  return (
7
11
  <div
8
12
  data-slot="card"
13
+ data-size={size}
9
14
  className={cn(
10
- "flex flex-col gap-6 rounded-xl border bg-card py-6 text-card-foreground shadow-sm",
15
+ "group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl",
11
16
  className
12
17
  )}
13
18
  {...props}
@@ -20,7 +25,7 @@ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
20
25
  <div
21
26
  data-slot="card-header"
22
27
  className={cn(
23
- "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
28
+ "group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)",
24
29
  className
25
30
  )}
26
31
  {...props}
@@ -32,7 +37,10 @@ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
32
37
  return (
33
38
  <div
34
39
  data-slot="card-title"
35
- className={cn("leading-none font-semibold", className)}
40
+ className={cn(
41
+ "font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
42
+ className
43
+ )}
36
44
  {...props}
37
45
  />
38
46
  )
@@ -65,7 +73,7 @@ function CardContent({ className, ...props }: React.ComponentProps<"div">) {
65
73
  return (
66
74
  <div
67
75
  data-slot="card-content"
68
- className={cn("px-6", className)}
76
+ className={cn("px-(--card-spacing)", className)}
69
77
  {...props}
70
78
  />
71
79
  )
@@ -75,7 +83,10 @@ function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
75
83
  return (
76
84
  <div
77
85
  data-slot="card-footer"
78
- className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
86
+ className={cn(
87
+ "flex items-center rounded-b-xl border-t bg-muted/50 p-(--card-spacing)",
88
+ className
89
+ )}
79
90
  {...props}
80
91
  />
81
92
  )
@@ -1,13 +1,11 @@
1
- "use client"
2
-
3
1
  import * as React from "react"
4
2
  import useEmblaCarousel, {
5
3
  type UseEmblaCarouselType,
6
4
  } from "embla-carousel-react"
7
- import { ArrowLeft, ArrowRight } from "lucide-react"
8
5
 
9
6
  import { cn } from "@/lib/utils"
10
7
  import { Button } from "@/ui/button"
8
+ import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react"
11
9
 
12
10
  type CarouselApi = UseEmblaCarouselType[1]
13
11
  type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
@@ -174,7 +172,7 @@ function CarouselItem({ className, ...props }: React.ComponentProps<"div">) {
174
172
  function CarouselPrevious({
175
173
  className,
176
174
  variant = "outline",
177
- size = "icon",
175
+ size = "icon-sm",
178
176
  ...props
179
177
  }: React.ComponentProps<typeof Button>) {
180
178
  const { orientation, scrollPrev, canScrollPrev } = useCarousel()
@@ -185,9 +183,9 @@ function CarouselPrevious({
185
183
  variant={variant}
186
184
  size={size}
187
185
  className={cn(
188
- "absolute size-8 rounded-full",
186
+ "absolute touch-manipulation rounded-full",
189
187
  orientation === "horizontal"
190
- ? "top-1/2 -left-12 -translate-y-1/2"
188
+ ? "inset-y-0 -left-12 my-auto"
191
189
  : "-top-12 left-1/2 -translate-x-1/2 rotate-90",
192
190
  className
193
191
  )}
@@ -195,7 +193,7 @@ function CarouselPrevious({
195
193
  onClick={scrollPrev}
196
194
  {...props}
197
195
  >
198
- <ArrowLeft />
196
+ <ChevronLeftIcon />
199
197
  <span className="sr-only">Previous slide</span>
200
198
  </Button>
201
199
  )
@@ -204,7 +202,7 @@ function CarouselPrevious({
204
202
  function CarouselNext({
205
203
  className,
206
204
  variant = "outline",
207
- size = "icon",
205
+ size = "icon-sm",
208
206
  ...props
209
207
  }: React.ComponentProps<typeof Button>) {
210
208
  const { orientation, scrollNext, canScrollNext } = useCarousel()
@@ -215,9 +213,9 @@ function CarouselNext({
215
213
  variant={variant}
216
214
  size={size}
217
215
  className={cn(
218
- "absolute size-8 rounded-full",
216
+ "absolute touch-manipulation rounded-full",
219
217
  orientation === "horizontal"
220
- ? "top-1/2 -right-12 -translate-y-1/2"
218
+ ? "inset-y-0 -right-12 my-auto"
221
219
  : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
222
220
  className
223
221
  )}
@@ -225,7 +223,7 @@ function CarouselNext({
225
223
  onClick={scrollNext}
226
224
  {...props}
227
225
  >
228
- <ArrowRight />
226
+ <ChevronRightIcon />
229
227
  <span className="sr-only">Next slide</span>
230
228
  </Button>
231
229
  )
@@ -238,4 +236,5 @@ export {
238
236
  CarouselItem,
239
237
  CarouselPrevious,
240
238
  CarouselNext,
239
+ useCarousel,
241
240
  }
@@ -191,7 +191,7 @@ function ChartTooltipContent({
191
191
  return (
192
192
  <div
193
193
  className={cn(
194
- "grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl",
194
+ "grid min-w-32 items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl",
195
195
  className
196
196
  )}
197
197
  >
@@ -327,7 +327,6 @@ function ChartLegendContent({
327
327
  )
328
328
  }
329
329
 
330
- // Helper to extract item config from a payload.
331
330
  function getPayloadConfigFromPayload(
332
331
  config: ChartConfig,
333
332
  payload: unknown,
@@ -1,10 +1,8 @@
1
- "use client"
2
-
3
1
  import * as React from "react"
4
- import { CheckIcon } from "lucide-react"
5
2
  import { Checkbox as CheckboxPrimitive } from "radix-ui"
6
3
 
7
4
  import { cn } from "@/lib/utils"
5
+ import { CheckIcon } from "lucide-react"
8
6
 
9
7
  function Checkbox({
10
8
  className,
@@ -14,16 +12,17 @@ function Checkbox({
14
12
  <CheckboxPrimitive.Root
15
13
  data-slot="checkbox"
16
14
  className={cn(
17
- "peer size-4 shrink-0 rounded-[4px] border border-input shadow-xs transition-shadow outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:bg-input/30 dark:aria-invalid:ring-destructive/40 dark:data-[state=checked]:bg-primary",
15
+ "peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input transition-colors outline-none group-has-disabled/field:opacity-50 group-has-[:focus-visible]/field-label:ring-0 group-has-[:focus-visible]/field-label:not-data-checked:border-input after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground group-has-[:focus-visible]/field-label:data-checked:border-primary dark:data-checked:bg-primary",
18
16
  className
19
17
  )}
20
18
  {...props}
21
19
  >
22
20
  <CheckboxPrimitive.Indicator
23
21
  data-slot="checkbox-indicator"
24
- className="grid place-content-center text-current transition-none"
22
+ className="grid place-content-center text-current transition-none [&>svg]:size-3.5"
25
23
  >
26
- <CheckIcon className="size-3.5" />
24
+ <CheckIcon
25
+ />
27
26
  </CheckboxPrimitive.Indicator>
28
27
  </CheckboxPrimitive.Root>
29
28
  )
@@ -1,3 +1,5 @@
1
+ "use client"
2
+
1
3
  import { Collapsible as CollapsiblePrimitive } from "radix-ui"
2
4
 
3
5
  function Collapsible({