@blips/ui 1.0.1 → 2.0.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 (59) hide show
  1. package/dist/index.cjs +3612 -2515
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +329 -484
  4. package/dist/index.d.ts +329 -484
  5. package/dist/index.js +3602 -2513
  6. package/dist/index.js.map +1 -1
  7. package/package.json +14 -12
  8. package/src/components/accordion.tsx +56 -46
  9. package/src/components/alert-dialog.tsx +166 -109
  10. package/src/components/alert.tsx +45 -38
  11. package/src/components/aspect-ratio.tsx +7 -1
  12. package/src/components/avatar.tsx +104 -45
  13. package/src/components/badge.tsx +25 -13
  14. package/src/components/breadcrumb.tsx +76 -82
  15. package/src/components/button-group.tsx +2 -2
  16. package/src/components/button.tsx +36 -28
  17. package/src/components/calendar.tsx +35 -28
  18. package/src/components/card.tsx +83 -70
  19. package/src/components/carousel.tsx +118 -137
  20. package/src/components/chart.tsx +197 -208
  21. package/src/components/checkbox.tsx +25 -21
  22. package/src/components/collapsible.tsx +25 -3
  23. package/src/components/command.tsx +138 -105
  24. package/src/components/context-menu.tsx +215 -161
  25. package/src/components/dialog.tsx +127 -91
  26. package/src/components/drawer.tsx +102 -83
  27. package/src/components/dropdown-menu.tsx +227 -170
  28. package/src/components/form.tsx +41 -52
  29. package/src/components/hover-card.tsx +36 -19
  30. package/src/components/input-group.tsx +4 -4
  31. package/src/components/input-otp.tsx +51 -43
  32. package/src/components/input.tsx +16 -17
  33. package/src/components/kbd.tsx +1 -1
  34. package/src/components/label.tsx +16 -18
  35. package/src/components/menubar.tsx +214 -192
  36. package/src/components/navigation-menu.tsx +140 -98
  37. package/src/components/pagination.tsx +97 -87
  38. package/src/components/popover.tsx +83 -23
  39. package/src/components/progress.tsx +23 -20
  40. package/src/components/radio-group.tsx +23 -20
  41. package/src/components/resizable.tsx +39 -31
  42. package/src/components/scroll-area.tsx +51 -39
  43. package/src/components/select.tsx +161 -131
  44. package/src/components/separator.tsx +13 -14
  45. package/src/components/sheet.tsx +112 -109
  46. package/src/components/sidebar.tsx +422 -470
  47. package/src/components/skeleton.tsx +4 -6
  48. package/src/components/slider.tsx +57 -20
  49. package/src/components/sonner.tsx +19 -24
  50. package/src/components/spinner.tsx +3 -3
  51. package/src/components/switch.tsx +28 -20
  52. package/src/components/table.tsx +94 -95
  53. package/src/components/tabs.tsx +88 -50
  54. package/src/components/textarea.tsx +5 -9
  55. package/src/components/toggle-group.tsx +52 -30
  56. package/src/components/toggle.tsx +24 -20
  57. package/src/components/tooltip.tsx +46 -19
  58. package/src/globals.css +213 -96
  59. package/src/index.ts +27 -6
@@ -2,14 +2,18 @@
2
2
 
3
3
  import * as React from "react"
4
4
  import {
5
- ChevronDownIcon,
6
- ChevronLeftIcon,
7
- ChevronRightIcon,
8
- } from "lucide-react"
9
- import { type DayButton, DayPicker, getDefaultClassNames } from "react-day-picker"
5
+ CaretDown,
6
+ CaretLeft,
7
+ CaretRight,
8
+ } from "@phosphor-icons/react"
9
+ import {
10
+ DayPicker,
11
+ getDefaultClassNames,
12
+ type DayButton,
13
+ } from "react-day-picker"
10
14
 
11
- import { cn } from "@/lib/utils"
12
- import { Button, buttonVariants } from "@/components/button"
15
+ import { cn } from "../lib/utils"
16
+ import { Button, buttonVariants } from "./button"
13
17
 
14
18
  function Calendar({
15
19
  className,
@@ -29,7 +33,7 @@ function Calendar({
29
33
  <DayPicker
30
34
  showOutsideDays={showOutsideDays}
31
35
  className={cn(
32
- "bg-background group/calendar p-3 [--cell-size:2rem] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
36
+ "group/calendar bg-background p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
33
37
  String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
34
38
  String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
35
39
  className
@@ -53,64 +57,67 @@ function Calendar({
53
57
  ),
54
58
  button_previous: cn(
55
59
  buttonVariants({ variant: buttonVariant }),
56
- "h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",
60
+ "size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
57
61
  defaultClassNames.button_previous
58
62
  ),
59
63
  button_next: cn(
60
64
  buttonVariants({ variant: buttonVariant }),
61
- "h-[--cell-size] w-[--cell-size] select-none p-0 aria-disabled:opacity-50",
65
+ "size-(--cell-size) p-0 select-none aria-disabled:opacity-50",
62
66
  defaultClassNames.button_next
63
67
  ),
64
68
  month_caption: cn(
65
- "flex h-[--cell-size] w-full items-center justify-center px-[--cell-size]",
69
+ "flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)",
66
70
  defaultClassNames.month_caption
67
71
  ),
68
72
  dropdowns: cn(
69
- "flex h-[--cell-size] w-full items-center justify-center gap-1.5 text-sm font-medium",
73
+ "flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium",
70
74
  defaultClassNames.dropdowns
71
75
  ),
72
76
  dropdown_root: cn(
73
- "has-focus:border-ring border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] relative rounded-md border",
77
+ "relative rounded-md border border-input shadow-xs has-focus:border-ring has-focus:ring-[3px] has-focus:ring-ring/50",
74
78
  defaultClassNames.dropdown_root
75
79
  ),
76
80
  dropdown: cn(
77
- "bg-popover absolute inset-0 opacity-0",
81
+ "absolute inset-0 bg-popover opacity-0",
78
82
  defaultClassNames.dropdown
79
83
  ),
80
84
  caption_label: cn(
81
- "select-none font-medium",
85
+ "font-medium select-none",
82
86
  captionLayout === "label"
83
87
  ? "text-sm"
84
- : "[&>svg]:text-muted-foreground flex h-8 items-center gap-1 rounded-md pl-2 pr-1 text-sm [&>svg]:size-3.5",
88
+ : "flex h-8 items-center gap-1 rounded-md pr-1 pl-2 text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground",
85
89
  defaultClassNames.caption_label
86
90
  ),
87
91
  table: "w-full border-collapse",
88
92
  weekdays: cn("flex", defaultClassNames.weekdays),
89
93
  weekday: cn(
90
- "text-muted-foreground flex-1 select-none rounded-md text-[0.8rem] font-normal",
94
+ "flex-1 rounded-md text-[0.8rem] font-normal text-muted-foreground select-none",
91
95
  defaultClassNames.weekday
92
96
  ),
93
97
  week: cn("mt-2 flex w-full", defaultClassNames.week),
94
98
  week_number_header: cn(
95
- "w-[--cell-size] select-none",
99
+ "w-(--cell-size) select-none",
96
100
  defaultClassNames.week_number_header
97
101
  ),
98
102
  week_number: cn(
99
- "text-muted-foreground select-none text-[0.8rem]",
103
+ "text-[0.8rem] text-muted-foreground select-none",
100
104
  defaultClassNames.week_number
101
105
  ),
102
106
  day: cn(
103
- "group/day relative aspect-square h-full w-full select-none p-0 text-center [&:first-child[data-selected=true]_button]:rounded-l-md [&:last-child[data-selected=true]_button]:rounded-r-md",
107
+ "group/day relative aspect-square h-full w-full p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-md",
108
+ props.showWeekNumber
109
+ ? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-md"
110
+ : "[&:first-child[data-selected=true]_button]:rounded-l-md",
104
111
  defaultClassNames.day
105
112
  ),
106
113
  range_start: cn(
107
- "bg-accent rounded-l-md",
114
+ "rounded-l-md bg-accent",
108
115
  defaultClassNames.range_start
109
116
  ),
110
117
  range_middle: cn("rounded-none", defaultClassNames.range_middle),
111
- range_end: cn("bg-accent rounded-r-md", defaultClassNames.range_end),
118
+ range_end: cn("rounded-r-md bg-accent", defaultClassNames.range_end),
112
119
  today: cn(
113
- "bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",
120
+ "rounded-md bg-accent text-accent-foreground data-[selected=true]:rounded-none",
114
121
  defaultClassNames.today
115
122
  ),
116
123
  outside: cn(
@@ -138,13 +145,13 @@ function Calendar({
138
145
  Chevron: ({ className, orientation, ...props }) => {
139
146
  if (orientation === "left") {
140
147
  return (
141
- <ChevronLeftIcon className={cn("size-4", className)} {...props} />
148
+ <CaretLeft className={cn("size-4", className)} {...props} />
142
149
  )
143
150
  }
144
151
 
145
152
  if (orientation === "right") {
146
153
  return (
147
- <ChevronRightIcon
154
+ <CaretRight
148
155
  className={cn("size-4", className)}
149
156
  {...props}
150
157
  />
@@ -152,14 +159,14 @@ function Calendar({
152
159
  }
153
160
 
154
161
  return (
155
- <ChevronDownIcon className={cn("size-4", className)} {...props} />
162
+ <CaretDown className={cn("size-4", className)} {...props} />
156
163
  )
157
164
  },
158
165
  DayButton: CalendarDayButton,
159
166
  WeekNumber: ({ children, ...props }) => {
160
167
  return (
161
168
  <td {...props}>
162
- <div className="flex size-[--cell-size] items-center justify-center text-center">
169
+ <div className="flex size-(--cell-size) items-center justify-center text-center">
163
170
  {children}
164
171
  </div>
165
172
  </td>
@@ -201,7 +208,7 @@ function CalendarDayButton({
201
208
  data-range-end={modifiers.range_end}
202
209
  data-range-middle={modifiers.range_middle}
203
210
  className={cn(
204
- "data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 flex aspect-square h-auto w-full min-w-[--cell-size] flex-col gap-1 font-normal leading-none data-[range-end=true]:rounded-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] [&>span]:text-xs [&>span]:opacity-70",
211
+ "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",
205
212
  defaultClassNames.day,
206
213
  className
207
214
  )}
@@ -1,79 +1,92 @@
1
1
  import * as React from "react"
2
2
 
3
- import { cn } from "@/lib/utils"
3
+ import { cn } from "../lib/utils"
4
4
 
5
- const Card = React.forwardRef<
6
- HTMLDivElement,
7
- React.HTMLAttributes<HTMLDivElement>
8
- >(({ className, ...props }, ref) => (
9
- <div
10
- ref={ref}
11
- className={cn(
12
- "rounded-lg border bg-card text-card-foreground shadow-sm",
13
- className
14
- )}
15
- {...props}
16
- />
17
- ))
18
- Card.displayName = "Card"
5
+ function Card({ className, ...props }: React.ComponentProps<"div">) {
6
+ return (
7
+ <div
8
+ data-slot="card"
9
+ className={cn(
10
+ "flex flex-col gap-6 rounded-xl border bg-card py-6 text-card-foreground shadow-sm",
11
+ className
12
+ )}
13
+ {...props}
14
+ />
15
+ )
16
+ }
19
17
 
20
- const CardHeader = React.forwardRef<
21
- HTMLDivElement,
22
- React.HTMLAttributes<HTMLDivElement>
23
- >(({ className, ...props }, ref) => (
24
- <div
25
- ref={ref}
26
- className={cn("flex flex-col space-y-1.5 p-6", className)}
27
- {...props}
28
- />
29
- ))
30
- CardHeader.displayName = "CardHeader"
18
+ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
19
+ return (
20
+ <div
21
+ data-slot="card-header"
22
+ 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",
24
+ className
25
+ )}
26
+ {...props}
27
+ />
28
+ )
29
+ }
31
30
 
32
- const CardTitle = React.forwardRef<
33
- HTMLDivElement,
34
- React.HTMLAttributes<HTMLDivElement>
35
- >(({ className, ...props }, ref) => (
36
- <div
37
- ref={ref}
38
- className={cn(
39
- "text-2xl font-semibold leading-none tracking-tight",
40
- className
41
- )}
42
- {...props}
43
- />
44
- ))
45
- CardTitle.displayName = "CardTitle"
31
+ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
32
+ return (
33
+ <div
34
+ data-slot="card-title"
35
+ className={cn("leading-none font-semibold", className)}
36
+ {...props}
37
+ />
38
+ )
39
+ }
46
40
 
47
- const CardDescription = React.forwardRef<
48
- HTMLDivElement,
49
- React.HTMLAttributes<HTMLDivElement>
50
- >(({ className, ...props }, ref) => (
51
- <div
52
- ref={ref}
53
- className={cn("text-sm text-muted-foreground", className)}
54
- {...props}
55
- />
56
- ))
57
- CardDescription.displayName = "CardDescription"
41
+ function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
42
+ return (
43
+ <div
44
+ data-slot="card-description"
45
+ className={cn("text-sm text-muted-foreground", className)}
46
+ {...props}
47
+ />
48
+ )
49
+ }
58
50
 
59
- const CardContent = React.forwardRef<
60
- HTMLDivElement,
61
- React.HTMLAttributes<HTMLDivElement>
62
- >(({ className, ...props }, ref) => (
63
- <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />
64
- ))
65
- CardContent.displayName = "CardContent"
51
+ function CardAction({ className, ...props }: React.ComponentProps<"div">) {
52
+ return (
53
+ <div
54
+ data-slot="card-action"
55
+ className={cn(
56
+ "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
57
+ className
58
+ )}
59
+ {...props}
60
+ />
61
+ )
62
+ }
66
63
 
67
- const CardFooter = React.forwardRef<
68
- HTMLDivElement,
69
- React.HTMLAttributes<HTMLDivElement>
70
- >(({ className, ...props }, ref) => (
71
- <div
72
- ref={ref}
73
- className={cn("flex items-center p-6 pt-0", className)}
74
- {...props}
75
- />
76
- ))
77
- CardFooter.displayName = "CardFooter"
64
+ function CardContent({ className, ...props }: React.ComponentProps<"div">) {
65
+ return (
66
+ <div
67
+ data-slot="card-content"
68
+ className={cn("px-6", className)}
69
+ {...props}
70
+ />
71
+ )
72
+ }
78
73
 
79
- export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
74
+ function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
75
+ return (
76
+ <div
77
+ data-slot="card-footer"
78
+ className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
79
+ {...props}
80
+ />
81
+ )
82
+ }
83
+
84
+ export {
85
+ Card,
86
+ CardHeader,
87
+ CardFooter,
88
+ CardTitle,
89
+ CardAction,
90
+ CardDescription,
91
+ CardContent,
92
+ }
@@ -1,11 +1,13 @@
1
+ "use client"
2
+
1
3
  import * as React from "react"
2
4
  import useEmblaCarousel, {
3
5
  type UseEmblaCarouselType,
4
6
  } from "embla-carousel-react"
5
- import { ArrowLeft, ArrowRight } from "lucide-react"
7
+ import { ArrowLeft, ArrowRight } from "@phosphor-icons/react"
6
8
 
7
- import { cn } from "@/lib/utils"
8
- import { Button } from "@/components/button"
9
+ import { cn } from "../lib/utils"
10
+ import { Button } from "./button"
9
11
 
10
12
  type CarouselApi = UseEmblaCarouselType[1]
11
13
  type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
@@ -40,124 +42,106 @@ function useCarousel() {
40
42
  return context
41
43
  }
42
44
 
43
- const Carousel = React.forwardRef<
44
- HTMLDivElement,
45
- React.HTMLAttributes<HTMLDivElement> & CarouselProps
46
- >(
47
- (
45
+ function Carousel({
46
+ orientation = "horizontal",
47
+ opts,
48
+ setApi,
49
+ plugins,
50
+ className,
51
+ children,
52
+ ...props
53
+ }: React.ComponentProps<"div"> & CarouselProps) {
54
+ const [carouselRef, api] = useEmblaCarousel(
48
55
  {
49
- orientation = "horizontal",
50
- opts,
51
- setApi,
52
- plugins,
53
- className,
54
- children,
55
- ...props
56
+ ...opts,
57
+ axis: orientation === "horizontal" ? "x" : "y",
56
58
  },
57
- ref
58
- ) => {
59
- const [carouselRef, api] = useEmblaCarousel(
60
- {
61
- ...opts,
62
- axis: orientation === "horizontal" ? "x" : "y",
63
- },
64
- plugins
65
- )
66
- const [canScrollPrev, setCanScrollPrev] = React.useState(false)
67
- const [canScrollNext, setCanScrollNext] = React.useState(false)
68
-
69
- const onSelect = React.useCallback((api: CarouselApi) => {
70
- if (!api) {
71
- return
72
- }
73
-
74
- setCanScrollPrev(api.canScrollPrev())
75
- setCanScrollNext(api.canScrollNext())
76
- }, [])
77
-
78
- const scrollPrev = React.useCallback(() => {
79
- api?.scrollPrev()
80
- }, [api])
81
-
82
- const scrollNext = React.useCallback(() => {
83
- api?.scrollNext()
84
- }, [api])
85
-
86
- const handleKeyDown = React.useCallback(
87
- (event: React.KeyboardEvent<HTMLDivElement>) => {
88
- if (event.key === "ArrowLeft") {
89
- event.preventDefault()
90
- scrollPrev()
91
- } else if (event.key === "ArrowRight") {
92
- event.preventDefault()
93
- scrollNext()
94
- }
95
- },
96
- [scrollPrev, scrollNext]
97
- )
98
-
99
- React.useEffect(() => {
100
- if (!api || !setApi) {
101
- return
59
+ plugins
60
+ )
61
+ const [canScrollPrev, setCanScrollPrev] = React.useState(false)
62
+ const [canScrollNext, setCanScrollNext] = React.useState(false)
63
+
64
+ const onSelect = React.useCallback((api: CarouselApi) => {
65
+ if (!api) return
66
+ setCanScrollPrev(api.canScrollPrev())
67
+ setCanScrollNext(api.canScrollNext())
68
+ }, [])
69
+
70
+ const scrollPrev = React.useCallback(() => {
71
+ api?.scrollPrev()
72
+ }, [api])
73
+
74
+ const scrollNext = React.useCallback(() => {
75
+ api?.scrollNext()
76
+ }, [api])
77
+
78
+ const handleKeyDown = React.useCallback(
79
+ (event: React.KeyboardEvent<HTMLDivElement>) => {
80
+ if (event.key === "ArrowLeft") {
81
+ event.preventDefault()
82
+ scrollPrev()
83
+ } else if (event.key === "ArrowRight") {
84
+ event.preventDefault()
85
+ scrollNext()
102
86
  }
87
+ },
88
+ [scrollPrev, scrollNext]
89
+ )
103
90
 
104
- setApi(api)
105
- }, [api, setApi])
106
-
107
- React.useEffect(() => {
108
- if (!api) {
109
- return
110
- }
91
+ React.useEffect(() => {
92
+ if (!api || !setApi) return
93
+ setApi(api)
94
+ }, [api, setApi])
111
95
 
112
- onSelect(api)
113
- api.on("reInit", onSelect)
114
- api.on("select", onSelect)
96
+ React.useEffect(() => {
97
+ if (!api) return
98
+ onSelect(api)
99
+ api.on("reInit", onSelect)
100
+ api.on("select", onSelect)
115
101
 
116
- return () => {
117
- api?.off("select", onSelect)
118
- }
119
- }, [api, onSelect])
102
+ return () => {
103
+ api?.off("select", onSelect)
104
+ }
105
+ }, [api, onSelect])
120
106
 
121
- return (
122
- <CarouselContext.Provider
123
- value={{
124
- carouselRef,
125
- api: api,
126
- opts,
127
- orientation:
128
- orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
129
- scrollPrev,
130
- scrollNext,
131
- canScrollPrev,
132
- canScrollNext,
133
- }}
107
+ return (
108
+ <CarouselContext.Provider
109
+ value={{
110
+ carouselRef,
111
+ api: api,
112
+ opts,
113
+ orientation:
114
+ orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
115
+ scrollPrev,
116
+ scrollNext,
117
+ canScrollPrev,
118
+ canScrollNext,
119
+ }}
120
+ >
121
+ <div
122
+ onKeyDownCapture={handleKeyDown}
123
+ className={cn("relative", className)}
124
+ role="region"
125
+ aria-roledescription="carousel"
126
+ data-slot="carousel"
127
+ {...props}
134
128
  >
135
- <div
136
- ref={ref}
137
- onKeyDownCapture={handleKeyDown}
138
- className={cn("relative", className)}
139
- role="region"
140
- aria-roledescription="carousel"
141
- {...props}
142
- >
143
- {children}
144
- </div>
145
- </CarouselContext.Provider>
146
- )
147
- }
148
- )
149
- Carousel.displayName = "Carousel"
129
+ {children}
130
+ </div>
131
+ </CarouselContext.Provider>
132
+ )
133
+ }
150
134
 
151
- const CarouselContent = React.forwardRef<
152
- HTMLDivElement,
153
- React.HTMLAttributes<HTMLDivElement>
154
- >(({ className, ...props }, ref) => {
135
+ function CarouselContent({ className, ...props }: React.ComponentProps<"div">) {
155
136
  const { carouselRef, orientation } = useCarousel()
156
137
 
157
138
  return (
158
- <div ref={carouselRef} className="overflow-hidden">
139
+ <div
140
+ ref={carouselRef}
141
+ className="overflow-hidden"
142
+ data-slot="carousel-content"
143
+ >
159
144
  <div
160
- ref={ref}
161
145
  className={cn(
162
146
  "flex",
163
147
  orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
@@ -167,20 +151,16 @@ const CarouselContent = React.forwardRef<
167
151
  />
168
152
  </div>
169
153
  )
170
- })
171
- CarouselContent.displayName = "CarouselContent"
154
+ }
172
155
 
173
- const CarouselItem = React.forwardRef<
174
- HTMLDivElement,
175
- React.HTMLAttributes<HTMLDivElement>
176
- >(({ className, ...props }, ref) => {
156
+ function CarouselItem({ className, ...props }: React.ComponentProps<"div">) {
177
157
  const { orientation } = useCarousel()
178
158
 
179
159
  return (
180
160
  <div
181
- ref={ref}
182
161
  role="group"
183
162
  aria-roledescription="slide"
163
+ data-slot="carousel-item"
184
164
  className={cn(
185
165
  "min-w-0 shrink-0 grow-0 basis-full",
186
166
  orientation === "horizontal" ? "pl-4" : "pt-4",
@@ -189,24 +169,25 @@ const CarouselItem = React.forwardRef<
189
169
  {...props}
190
170
  />
191
171
  )
192
- })
193
- CarouselItem.displayName = "CarouselItem"
172
+ }
194
173
 
195
- const CarouselPrevious = React.forwardRef<
196
- HTMLButtonElement,
197
- React.ComponentProps<typeof Button>
198
- >(({ className, variant = "outline", size = "icon", ...props }, ref) => {
174
+ function CarouselPrevious({
175
+ className,
176
+ variant = "outline",
177
+ size = "icon",
178
+ ...props
179
+ }: React.ComponentProps<typeof Button>) {
199
180
  const { orientation, scrollPrev, canScrollPrev } = useCarousel()
200
181
 
201
182
  return (
202
183
  <Button
203
- ref={ref}
184
+ data-slot="carousel-previous"
204
185
  variant={variant}
205
186
  size={size}
206
187
  className={cn(
207
- "absolute h-8 w-8 rounded-full",
188
+ "absolute size-8 rounded-full",
208
189
  orientation === "horizontal"
209
- ? "-left-12 top-1/2 -translate-y-1/2"
190
+ ? "top-1/2 -left-12 -translate-y-1/2"
210
191
  : "-top-12 left-1/2 -translate-x-1/2 rotate-90",
211
192
  className
212
193
  )}
@@ -214,28 +195,29 @@ const CarouselPrevious = React.forwardRef<
214
195
  onClick={scrollPrev}
215
196
  {...props}
216
197
  >
217
- <ArrowLeft className="h-4 w-4" />
198
+ <ArrowLeft />
218
199
  <span className="sr-only">Previous slide</span>
219
200
  </Button>
220
201
  )
221
- })
222
- CarouselPrevious.displayName = "CarouselPrevious"
202
+ }
223
203
 
224
- const CarouselNext = React.forwardRef<
225
- HTMLButtonElement,
226
- React.ComponentProps<typeof Button>
227
- >(({ className, variant = "outline", size = "icon", ...props }, ref) => {
204
+ function CarouselNext({
205
+ className,
206
+ variant = "outline",
207
+ size = "icon",
208
+ ...props
209
+ }: React.ComponentProps<typeof Button>) {
228
210
  const { orientation, scrollNext, canScrollNext } = useCarousel()
229
211
 
230
212
  return (
231
213
  <Button
232
- ref={ref}
214
+ data-slot="carousel-next"
233
215
  variant={variant}
234
216
  size={size}
235
217
  className={cn(
236
- "absolute h-8 w-8 rounded-full",
218
+ "absolute size-8 rounded-full",
237
219
  orientation === "horizontal"
238
- ? "-right-12 top-1/2 -translate-y-1/2"
220
+ ? "top-1/2 -right-12 -translate-y-1/2"
239
221
  : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
240
222
  className
241
223
  )}
@@ -243,12 +225,11 @@ const CarouselNext = React.forwardRef<
243
225
  onClick={scrollNext}
244
226
  {...props}
245
227
  >
246
- <ArrowRight className="h-4 w-4" />
228
+ <ArrowRight />
247
229
  <span className="sr-only">Next slide</span>
248
230
  </Button>
249
231
  )
250
- })
251
- CarouselNext.displayName = "CarouselNext"
232
+ }
252
233
 
253
234
  export {
254
235
  type CarouselApi,