xiod-ui 1.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 (224) hide show
  1. package/LICENSE +73 -0
  2. package/README.md +167 -0
  3. package/dist/components/accordion.d.ts +9 -0
  4. package/dist/components/accordion.js +46 -0
  5. package/dist/components/agent-steps.d.ts +47 -0
  6. package/dist/components/agent-steps.js +223 -0
  7. package/dist/components/alert-dialog.d.ts +21 -0
  8. package/dist/components/alert-dialog.js +74 -0
  9. package/dist/components/alert.d.ts +12 -0
  10. package/dist/components/alert.js +45 -0
  11. package/dist/components/aspect-ratio.d.ts +9 -0
  12. package/dist/components/aspect-ratio.js +22 -0
  13. package/dist/components/autocomplete.d.ts +35 -0
  14. package/dist/components/autocomplete.js +160 -0
  15. package/dist/components/avatar.d.ts +17 -0
  16. package/dist/components/avatar.js +65 -0
  17. package/dist/components/badge.d.ts +15 -0
  18. package/dist/components/badge.js +46 -0
  19. package/dist/components/breadcrumb.d.ts +12 -0
  20. package/dist/components/breadcrumb.js +75 -0
  21. package/dist/components/button-group.d.ts +14 -0
  22. package/dist/components/button-group.js +45 -0
  23. package/dist/components/button-split.d.ts +19 -0
  24. package/dist/components/button-split.js +73 -0
  25. package/dist/components/button.d.ts +15 -0
  26. package/dist/components/button.js +54 -0
  27. package/dist/components/calendar.d.ts +63 -0
  28. package/dist/components/calendar.js +425 -0
  29. package/dist/components/card.d.ts +17 -0
  30. package/dist/components/card.js +139 -0
  31. package/dist/components/carousel.d.ts +59 -0
  32. package/dist/components/carousel.js +503 -0
  33. package/dist/components/checkbox.d.ts +16 -0
  34. package/dist/components/checkbox.js +86 -0
  35. package/dist/components/circular-progress.d.ts +28 -0
  36. package/dist/components/circular-progress.js +127 -0
  37. package/dist/components/collapsible.d.ts +8 -0
  38. package/dist/components/collapsible.js +27 -0
  39. package/dist/components/color-picker.d.ts +159 -0
  40. package/dist/components/color-picker.js +1589 -0
  41. package/dist/components/combobox.d.ts +46 -0
  42. package/dist/components/combobox.js +237 -0
  43. package/dist/components/command.d.ts +22 -0
  44. package/dist/components/command.js +129 -0
  45. package/dist/components/context-menu.d.ts +38 -0
  46. package/dist/components/context-menu.js +164 -0
  47. package/dist/components/copy-to-clipboard.d.ts +32 -0
  48. package/dist/components/copy-to-clipboard.js +83 -0
  49. package/dist/components/corner-badge.d.ts +22 -0
  50. package/dist/components/corner-badge.js +84 -0
  51. package/dist/components/dashboard-grid.d.ts +83 -0
  52. package/dist/components/dashboard-grid.js +486 -0
  53. package/dist/components/date-picker.d.ts +29 -0
  54. package/dist/components/date-picker.js +261 -0
  55. package/dist/components/dialog.d.ts +26 -0
  56. package/dist/components/dialog.js +97 -0
  57. package/dist/components/dot-matrix.d.ts +32 -0
  58. package/dist/components/dot-matrix.js +707 -0
  59. package/dist/components/draggable.d.ts +42 -0
  60. package/dist/components/draggable.js +346 -0
  61. package/dist/components/drawer.d.ts +66 -0
  62. package/dist/components/drawer.js +304 -0
  63. package/dist/components/empty.d.ts +14 -0
  64. package/dist/components/empty.js +75 -0
  65. package/dist/components/field.d.ts +12 -0
  66. package/dist/components/field.js +44 -0
  67. package/dist/components/fieldset.d.ts +7 -0
  68. package/dist/components/fieldset.js +21 -0
  69. package/dist/components/file-upload.d.ts +61 -0
  70. package/dist/components/file-upload.js +482 -0
  71. package/dist/components/form.d.ts +6 -0
  72. package/dist/components/form.js +14 -0
  73. package/dist/components/frame.d.ts +10 -0
  74. package/dist/components/frame.js +47 -0
  75. package/dist/components/gauge.d.ts +27 -0
  76. package/dist/components/gauge.js +74 -0
  77. package/dist/components/grid.d.ts +26 -0
  78. package/dist/components/grid.js +204 -0
  79. package/dist/components/group.d.ts +19 -0
  80. package/dist/components/group.js +45 -0
  81. package/dist/components/input-group.d.ts +15 -0
  82. package/dist/components/input-group.js +61 -0
  83. package/dist/components/input-otp.d.ts +24 -0
  84. package/dist/components/input-otp.js +50 -0
  85. package/dist/components/input-payment.d.ts +131 -0
  86. package/dist/components/input-payment.js +1140 -0
  87. package/dist/components/input-phone.d.ts +70 -0
  88. package/dist/components/input-phone.js +657 -0
  89. package/dist/components/input-sensitive.d.ts +12 -0
  90. package/dist/components/input-sensitive.js +169 -0
  91. package/dist/components/input.d.ts +13 -0
  92. package/dist/components/input.js +26 -0
  93. package/dist/components/kbd.d.ts +6 -0
  94. package/dist/components/kbd.js +19 -0
  95. package/dist/components/kinetic-click.d.ts +48 -0
  96. package/dist/components/kinetic-click.js +1184 -0
  97. package/dist/components/label.d.ts +6 -0
  98. package/dist/components/label.js +18 -0
  99. package/dist/components/list-box.d.ts +20 -0
  100. package/dist/components/list-box.js +148 -0
  101. package/dist/components/loader.d.ts +13 -0
  102. package/dist/components/loader.js +430 -0
  103. package/dist/components/marker.d.ts +15 -0
  104. package/dist/components/marker.js +59 -0
  105. package/dist/components/menu.d.ts +42 -0
  106. package/dist/components/menu.js +186 -0
  107. package/dist/components/menubar.d.ts +40 -0
  108. package/dist/components/menubar.js +107 -0
  109. package/dist/components/message.d.ts +33 -0
  110. package/dist/components/message.js +112 -0
  111. package/dist/components/meter.d.ts +10 -0
  112. package/dist/components/meter.js +42 -0
  113. package/dist/components/morphic-toast.d.ts +61 -0
  114. package/dist/components/morphic-toast.js +916 -0
  115. package/dist/components/navigation-menu.d.ts +26 -0
  116. package/dist/components/navigation-menu.js +116 -0
  117. package/dist/components/number-field.d.ts +15 -0
  118. package/dist/components/number-field.js +86 -0
  119. package/dist/components/option-picker.d.ts +18 -0
  120. package/dist/components/option-picker.js +89 -0
  121. package/dist/components/orb.d.ts +38 -0
  122. package/dist/components/orb.js +1413 -0
  123. package/dist/components/pagination.d.ts +25 -0
  124. package/dist/components/pagination.js +147 -0
  125. package/dist/components/popover.d.ts +22 -0
  126. package/dist/components/popover.js +79 -0
  127. package/dist/components/preview-card.d.ts +16 -0
  128. package/dist/components/preview-card.js +60 -0
  129. package/dist/components/progress.d.ts +21 -0
  130. package/dist/components/progress.js +139 -0
  131. package/dist/components/radio.d.ts +16 -0
  132. package/dist/components/radio.js +68 -0
  133. package/dist/components/resizable.d.ts +58 -0
  134. package/dist/components/resizable.js +964 -0
  135. package/dist/components/ruler-picker.d.ts +27 -0
  136. package/dist/components/ruler-picker.js +253 -0
  137. package/dist/components/scroll-area.d.ts +13 -0
  138. package/dist/components/scroll-area.js +34 -0
  139. package/dist/components/scroll-bar.d.ts +13 -0
  140. package/dist/components/scroll-bar.js +47 -0
  141. package/dist/components/select.d.ts +29 -0
  142. package/dist/components/select.js +140 -0
  143. package/dist/components/separator.d.ts +6 -0
  144. package/dist/components/separator.js +15 -0
  145. package/dist/components/sidebar.d.ts +65 -0
  146. package/dist/components/sidebar.js +408 -0
  147. package/dist/components/skeleton.d.ts +5 -0
  148. package/dist/components/skeleton.js +12 -0
  149. package/dist/components/slider.d.ts +12 -0
  150. package/dist/components/slider.js +96 -0
  151. package/dist/components/sortable.d.ts +44 -0
  152. package/dist/components/sortable.js +327 -0
  153. package/dist/components/switch.d.ts +15 -0
  154. package/dist/components/switch.js +63 -0
  155. package/dist/components/table.d.ts +12 -0
  156. package/dist/components/table.js +65 -0
  157. package/dist/components/tabs.d.ts +12 -0
  158. package/dist/components/tabs.js +39 -0
  159. package/dist/components/text.d.ts +14 -0
  160. package/dist/components/text.js +69 -0
  161. package/dist/components/textarea.d.ts +9 -0
  162. package/dist/components/textarea.js +20 -0
  163. package/dist/components/theme-provider.d.ts +52 -0
  164. package/dist/components/theme-provider.js +148 -0
  165. package/dist/components/timeline.d.ts +34 -0
  166. package/dist/components/timeline.js +147 -0
  167. package/dist/components/toast.d.ts +17 -0
  168. package/dist/components/toast.js +161 -0
  169. package/dist/components/toggle-group.d.ts +14 -0
  170. package/dist/components/toggle-group.js +53 -0
  171. package/dist/components/toggle.d.ts +11 -0
  172. package/dist/components/toggle.js +36 -0
  173. package/dist/components/toolbar.d.ts +11 -0
  174. package/dist/components/toolbar.js +49 -0
  175. package/dist/components/tooltip.d.ts +17 -0
  176. package/dist/components/tooltip.js +56 -0
  177. package/dist/components/waveform.d.ts +61 -0
  178. package/dist/components/waveform.js +500 -0
  179. package/dist/components/wheel-picker.d.ts +44 -0
  180. package/dist/components/wheel-picker.js +771 -0
  181. package/dist/hooks/use-copy-to-clipboard.d.ts +9 -0
  182. package/dist/hooks/use-copy-to-clipboard.js +36 -0
  183. package/dist/hooks/use-media-query.d.ts +21 -0
  184. package/dist/hooks/use-media-query.js +58 -0
  185. package/dist/styles.css +202 -0
  186. package/dist/themes/afterglow.css +89 -0
  187. package/dist/themes/afterglow.scoped.css +90 -0
  188. package/dist/themes/blacklight.css +89 -0
  189. package/dist/themes/blacklight.scoped.css +90 -0
  190. package/dist/themes/cathode.css +89 -0
  191. package/dist/themes/cathode.scoped.css +90 -0
  192. package/dist/themes/cel.css +89 -0
  193. package/dist/themes/cel.scoped.css +90 -0
  194. package/dist/themes/cinder.css +89 -0
  195. package/dist/themes/cinder.scoped.css +90 -0
  196. package/dist/themes/clay.css +89 -0
  197. package/dist/themes/clay.scoped.css +90 -0
  198. package/dist/themes/cobalt.css +89 -0
  199. package/dist/themes/cobalt.scoped.css +90 -0
  200. package/dist/themes/crimson.css +89 -0
  201. package/dist/themes/crimson.scoped.css +90 -0
  202. package/dist/themes/ion.css +89 -0
  203. package/dist/themes/ion.scoped.css +90 -0
  204. package/dist/themes/iris.css +89 -0
  205. package/dist/themes/iris.scoped.css +90 -0
  206. package/dist/themes/lagoon.css +89 -0
  207. package/dist/themes/lagoon.scoped.css +90 -0
  208. package/dist/themes/mochi.css +89 -0
  209. package/dist/themes/mochi.scoped.css +90 -0
  210. package/dist/themes/riso.css +89 -0
  211. package/dist/themes/riso.scoped.css +90 -0
  212. package/dist/themes/roast.css +89 -0
  213. package/dist/themes/roast.scoped.css +90 -0
  214. package/dist/themes/sage.css +89 -0
  215. package/dist/themes/sage.scoped.css +90 -0
  216. package/dist/themes/sepia.css +89 -0
  217. package/dist/themes/sepia.scoped.css +90 -0
  218. package/dist/themes/sorbet.css +89 -0
  219. package/dist/themes/sorbet.scoped.css +90 -0
  220. package/dist/themes/taffy.css +89 -0
  221. package/dist/themes/taffy.scoped.css +90 -0
  222. package/dist/themes/toxin.css +89 -0
  223. package/dist/themes/toxin.scoped.css +90 -0
  224. package/package.json +140 -0
@@ -0,0 +1,139 @@
1
+ "use client";
2
+ import { cn } from "cn";
3
+ import { mergeProps } from "@base-ui/react/merge-props";
4
+ import { useRender } from "@base-ui/react/use-render";
5
+ //#region src/components/card.tsx
6
+ function Card({ className, render, ...props }) {
7
+ const defaultProps = {
8
+ className: cn("relative flex flex-col rounded-2xl border bg-card not-dark:bg-clip-padding text-card-foreground shadow-xs/5 before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-2xl)-1px)] before:shadow-[0_1px_--theme(--color-black/4%)] dark:before:shadow-[0_-1px_--theme(--color-white/6%)]", className),
9
+ "data-slot": "card"
10
+ };
11
+ return useRender({
12
+ defaultTagName: "div",
13
+ props: mergeProps(defaultProps, props),
14
+ render
15
+ });
16
+ }
17
+ function CardFrame({ className, render, ...props }) {
18
+ const defaultProps = {
19
+ className: cn("[--clip-top:-1rem] [--clip-bottom:-1rem] *:data-[slot=card]:first:[--clip-top:1px] *:data-[slot=card]:last:[--clip-bottom:1px] flex flex-col relative rounded-2xl border bg-card before:bg-muted/72 not-dark:bg-clip-padding text-card-foreground shadow-xs/5 before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-2xl)-1px)] before:shadow-[0_1px_--theme(--color-black/4%)] dark:before:shadow-[0_-1px_--theme(--color-white/6%)] *:data-[slot=card]:-m-px *:not-last:data-[slot=card]:rounded-b-xl *:not-last:data-[slot=card]:before:rounded-b-[calc(var(--radius-xl)-1px)] *:not-first:data-[slot=card]:rounded-t-xl *:not-first:data-[slot=card]:before:rounded-t-[calc(var(--radius-xl)-1px)] *:data-[slot=card]:[clip-path:inset(var(--clip-top)_1px_var(--clip-bottom)_1px_round_calc(var(--radius-2xl)-1px))] *:data-[slot=card]:shadow-none *:data-[slot=card]:before:hidden *:data-[slot=card]:bg-clip-padding", className),
20
+ "data-slot": "card-frame"
21
+ };
22
+ return useRender({
23
+ defaultTagName: "div",
24
+ props: mergeProps(defaultProps, props),
25
+ render
26
+ });
27
+ }
28
+ function CardFrameHeader({ className, render, ...props }) {
29
+ const defaultProps = {
30
+ className: cn("relative flex flex-col px-6 py-4", className),
31
+ "data-slot": "card-frame-header"
32
+ };
33
+ return useRender({
34
+ defaultTagName: "div",
35
+ props: mergeProps(defaultProps, props),
36
+ render
37
+ });
38
+ }
39
+ function CardFrameTitle({ className, render, ...props }) {
40
+ const defaultProps = {
41
+ className: cn("font-semibold text-sm", className),
42
+ "data-slot": "card-frame-title"
43
+ };
44
+ return useRender({
45
+ defaultTagName: "div",
46
+ props: mergeProps(defaultProps, props),
47
+ render
48
+ });
49
+ }
50
+ function CardFrameDescription({ className, render, ...props }) {
51
+ const defaultProps = {
52
+ className: cn("text-muted-foreground text-sm", className),
53
+ "data-slot": "card-frame-description"
54
+ };
55
+ return useRender({
56
+ defaultTagName: "div",
57
+ props: mergeProps(defaultProps, props),
58
+ render
59
+ });
60
+ }
61
+ function CardFrameFooter({ className, render, ...props }) {
62
+ const defaultProps = {
63
+ className: cn("px-6 py-4", className),
64
+ "data-slot": "card-frame-footer"
65
+ };
66
+ return useRender({
67
+ defaultTagName: "div",
68
+ props: mergeProps(defaultProps, props),
69
+ render
70
+ });
71
+ }
72
+ function CardHeader({ className, render, ...props }) {
73
+ const defaultProps = {
74
+ className: cn("grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 p-6 in-[[data-slot=card]:has(>[data-slot=card-panel])]:pb-4 has-data-[slot=card-action]:grid-cols-[1fr_auto]", className),
75
+ "data-slot": "card-header"
76
+ };
77
+ return useRender({
78
+ defaultTagName: "div",
79
+ props: mergeProps(defaultProps, props),
80
+ render
81
+ });
82
+ }
83
+ function CardTitle({ className, render, ...props }) {
84
+ const defaultProps = {
85
+ className: cn("font-semibold text-lg leading-none", className),
86
+ "data-slot": "card-title"
87
+ };
88
+ return useRender({
89
+ defaultTagName: "div",
90
+ props: mergeProps(defaultProps, props),
91
+ render
92
+ });
93
+ }
94
+ function CardDescription({ className, render, ...props }) {
95
+ const defaultProps = {
96
+ className: cn("text-muted-foreground text-sm", className),
97
+ "data-slot": "card-description"
98
+ };
99
+ return useRender({
100
+ defaultTagName: "div",
101
+ props: mergeProps(defaultProps, props),
102
+ render
103
+ });
104
+ }
105
+ function CardAction({ className, render, ...props }) {
106
+ const defaultProps = {
107
+ className: cn("col-start-2 row-span-2 row-start-1 self-start justify-self-end inline-flex", className),
108
+ "data-slot": "card-action"
109
+ };
110
+ return useRender({
111
+ defaultTagName: "div",
112
+ props: mergeProps(defaultProps, props),
113
+ render
114
+ });
115
+ }
116
+ function CardPanel({ className, render, ...props }) {
117
+ const defaultProps = {
118
+ className: cn("flex-1 p-6 in-[[data-slot=card]:has(>[data-slot=card-header]:not(.border-b))]:pt-0 in-[[data-slot=card]:has(>[data-slot=card-footer]:not(.border-t))]:pb-0", className),
119
+ "data-slot": "card-panel"
120
+ };
121
+ return useRender({
122
+ defaultTagName: "div",
123
+ props: mergeProps(defaultProps, props),
124
+ render
125
+ });
126
+ }
127
+ function CardFooter({ className, render, ...props }) {
128
+ const defaultProps = {
129
+ className: cn("flex items-center p-6 in-[[data-slot=card]:has(>[data-slot=card-panel])]:pt-4", className),
130
+ "data-slot": "card-footer"
131
+ };
132
+ return useRender({
133
+ defaultTagName: "div",
134
+ props: mergeProps(defaultProps, props),
135
+ render
136
+ });
137
+ }
138
+ //#endregion
139
+ export { Card, CardAction, CardPanel as CardContent, CardPanel, CardDescription, CardFooter, CardFrame, CardFrameDescription, CardFrameFooter, CardFrameHeader, CardFrameTitle, CardHeader, CardTitle };
@@ -0,0 +1,59 @@
1
+ import { Button } from "./button.js";
2
+ import * as React$1 from "react";
3
+ //#region src/components/carousel.d.ts
4
+ export type CarouselApi = {
5
+ scrollPrev: (jump?: boolean) => void;
6
+ scrollNext: (jump?: boolean) => void;
7
+ scrollTo: (index: number, jump?: boolean) => void;
8
+ canScrollPrev: () => boolean;
9
+ canScrollNext: () => boolean;
10
+ selectedScrollSnap: () => number;
11
+ scrollSnapList: () => number[];
12
+ on: (event: string, cb: (api: CarouselApi) => void) => void;
13
+ off: (event: string, cb: (api: CarouselApi) => void) => void;
14
+ reInit: (options?: CarouselOptions) => void;
15
+ destroy: () => void;
16
+ };
17
+ export type CarouselOptions = {
18
+ align?: "start" | "center" | "end";
19
+ axis?: "x" | "y";
20
+ containScroll?: boolean;
21
+ loop?: boolean;
22
+ dragFree?: boolean;
23
+ speed?: number;
24
+ };
25
+ export type CarouselPlugin = {
26
+ name?: string;
27
+ init?: (api: CarouselApi) => void;
28
+ destroy?: () => void;
29
+ };
30
+ export type UseEmblaCarouselType = [(node: HTMLElement | null) => void, CarouselApi | undefined];
31
+ export declare function useEmblaCarousel(options?: CarouselOptions, plugins?: CarouselPlugin[]): UseEmblaCarouselType;
32
+ export interface CarouselProps {
33
+ orientation?: "horizontal" | "vertical";
34
+ autoplay?: boolean;
35
+ autoplayInterval?: number;
36
+ loop?: boolean;
37
+ activeIndex?: number;
38
+ }
39
+ type CarouselContextProps = {
40
+ carouselRef: (node: HTMLElement | null) => void;
41
+ api: CarouselApi | undefined;
42
+ scrollPrev: () => void;
43
+ scrollNext: () => void;
44
+ canScrollPrev: boolean;
45
+ canScrollNext: boolean;
46
+ orientation: "horizontal" | "vertical";
47
+ } & CarouselProps;
48
+ export declare function useCarousel(): CarouselContextProps;
49
+ export declare function Carousel({ orientation, opts, plugins, autoplay, autoplayInterval, loop, className, children, ...props }: React$1.ComponentProps<"div"> & CarouselProps & {
50
+ opts?: CarouselOptions;
51
+ plugins?: CarouselPlugin[];
52
+ }): React$1.JSX.Element;
53
+ export declare function CarouselContent({ className, ...props }: React$1.ComponentProps<"div">): React$1.JSX.Element;
54
+ export declare function CarouselItem({ className, ...props }: React$1.ComponentProps<"div">): React$1.JSX.Element;
55
+ export declare function CarouselPrevious({ className, variant, size, ...props }: React$1.ComponentProps<typeof Button>): React$1.JSX.Element;
56
+ export declare function CarouselNext({ className, variant, size, ...props }: React$1.ComponentProps<typeof Button>): React$1.JSX.Element;
57
+ export declare function CarouselDots({ className, ...props }: React$1.HTMLAttributes<HTMLDivElement>): React$1.JSX.Element | null;
58
+ //#endregion
59
+ export type { CarouselApi as EmblaCarouselType, CarouselOptions as EmblaOptionsType };
@@ -0,0 +1,503 @@
1
+ "use client";
2
+ import { Button } from "./button.js";
3
+ import { cn } from "cn";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import * as React$1 from "react";
6
+ import { ChevronRight } from "xiod-icons/icons/ChevronRight";
7
+ import { ChevronLeft } from "xiod-icons/icons/ChevronLeft";
8
+ //#region src/components/carousel.tsx
9
+ function useEmblaCarousel(options = {}, plugins = []) {
10
+ const [viewportNode, setViewportNode] = React$1.useState(null);
11
+ const [api, setApi] = React$1.useState();
12
+ const optionsRef = React$1.useRef(options);
13
+ optionsRef.current = options;
14
+ const apiRef = React$1.useRef(null);
15
+ const viewportNodeRef = React$1.useRef(null);
16
+ const containerRef = React$1.useRef(null);
17
+ const activeIndexRef = React$1.useRef(0);
18
+ const [_activeIndexState, setActiveIndexState] = React$1.useState(0);
19
+ const snapOffsetsRef = React$1.useRef([]);
20
+ const listenersRef = React$1.useRef({});
21
+ const isDraggingRef = React$1.useRef(false);
22
+ const dragStartPosRef = React$1.useRef(0);
23
+ const dragStartTimeRef = React$1.useRef(0);
24
+ const baseTranslationRef = React$1.useRef(0);
25
+ const currentTranslationRef = React$1.useRef(0);
26
+ const draggedDistanceRef = React$1.useRef(0);
27
+ React$1.useCallback(() => {
28
+ return optionsRef.current.axis === "y" ? "y" : "x";
29
+ }, []);
30
+ const emit = React$1.useCallback((event) => {
31
+ if (!apiRef.current) return;
32
+ const list = listenersRef.current[event] || [];
33
+ for (const cb of list) cb(apiRef.current);
34
+ }, []);
35
+ const translateTrack = React$1.useCallback((value, animate = true) => {
36
+ const container = containerRef.current;
37
+ if (!container) return;
38
+ if (animate) {
39
+ container.style.transition = "transform 400ms cubic-bezier(0.25, 1, 0.5, 1)";
40
+ container.offsetHeight;
41
+ } else container.style.transition = "none";
42
+ const isY = optionsRef.current.axis === "y";
43
+ container.style.transform = isY ? `translate3d(0, ${value}px, 0)` : `translate3d(${value}px, 0, 0)`;
44
+ currentTranslationRef.current = value;
45
+ }, []);
46
+ const calculateSnaps = React$1.useCallback(() => {
47
+ const viewport = viewportNodeRef.current;
48
+ const container = containerRef.current;
49
+ if (!viewport || !container) return;
50
+ const isY = optionsRef.current.axis === "y";
51
+ const children = Array.from(container.children);
52
+ if (children.length === 0) {
53
+ snapOffsetsRef.current = [];
54
+ return;
55
+ }
56
+ const viewportSize = isY ? viewport.clientHeight : viewport.clientWidth;
57
+ const containerSize = isY ? container.scrollHeight : container.scrollWidth;
58
+ const align = optionsRef.current.align || "center";
59
+ const snaps = [];
60
+ for (let i = 0; i < children.length; i++) {
61
+ const child = children[i];
62
+ const childSize = isY ? child.clientHeight : child.clientWidth;
63
+ const childOffset = isY ? child.offsetTop : child.offsetLeft;
64
+ let alignOffset = 0;
65
+ if (align === "start") alignOffset = 0;
66
+ else if (align === "end") alignOffset = viewportSize - childSize;
67
+ else alignOffset = (viewportSize - childSize) / 2;
68
+ let snapTarget = childOffset - alignOffset;
69
+ if (optionsRef.current.containScroll !== false) {
70
+ const maxLimit = containerSize - viewportSize;
71
+ snapTarget = Math.max(0, Math.min(maxLimit, snapTarget));
72
+ }
73
+ snaps.push(-snapTarget);
74
+ }
75
+ snapOffsetsRef.current = snaps.filter((val, index, self) => self.indexOf(val) === index);
76
+ emit("reInit");
77
+ }, [emit]);
78
+ const scrollTo = React$1.useCallback((index, jump = false) => {
79
+ if (snapOffsetsRef.current.length === 0) return;
80
+ const loop = optionsRef.current.loop;
81
+ let targetIndex = index;
82
+ if (loop) {
83
+ const len = snapOffsetsRef.current.length;
84
+ targetIndex = (index % len + len) % len;
85
+ } else targetIndex = Math.max(0, Math.min(snapOffsetsRef.current.length - 1, index));
86
+ activeIndexRef.current = targetIndex;
87
+ setActiveIndexState(targetIndex);
88
+ const targetTranslation = snapOffsetsRef.current[targetIndex];
89
+ translateTrack(targetTranslation, !jump);
90
+ baseTranslationRef.current = targetTranslation;
91
+ emit("select");
92
+ }, [translateTrack, emit]);
93
+ const scrollPrev = React$1.useCallback((jump) => {
94
+ scrollTo(activeIndexRef.current - 1, jump === true);
95
+ }, [scrollTo]);
96
+ const scrollNext = React$1.useCallback((jump) => {
97
+ scrollTo(activeIndexRef.current + 1, jump === true);
98
+ }, [scrollTo]);
99
+ const canScrollPrev = React$1.useCallback(() => {
100
+ return optionsRef.current.loop || activeIndexRef.current > 0;
101
+ }, []);
102
+ const canScrollNext = React$1.useCallback(() => {
103
+ return optionsRef.current.loop || activeIndexRef.current < snapOffsetsRef.current.length - 1;
104
+ }, []);
105
+ const selectedScrollSnap = React$1.useCallback(() => {
106
+ return activeIndexRef.current;
107
+ }, []);
108
+ const scrollSnapList = React$1.useCallback(() => {
109
+ return snapOffsetsRef.current.map((_, i) => i);
110
+ }, []);
111
+ const handlePointerDown = React$1.useCallback((e) => {
112
+ const container = containerRef.current;
113
+ const viewport = viewportNodeRef.current;
114
+ if (!container || !viewport) return;
115
+ if (e.button !== 0 && e.pointerType !== "touch") return;
116
+ if (e.pointerType === "mouse") e.preventDefault();
117
+ isDraggingRef.current = true;
118
+ draggedDistanceRef.current = 0;
119
+ dragStartTimeRef.current = Date.now();
120
+ const isY = optionsRef.current.axis === "y";
121
+ dragStartPosRef.current = isY ? e.pageY : e.pageX;
122
+ container.style.transition = "none";
123
+ baseTranslationRef.current = currentTranslationRef.current;
124
+ try {
125
+ viewport.setPointerCapture(e.pointerId);
126
+ } catch {}
127
+ }, []);
128
+ const handlePointerMove = React$1.useCallback((e) => {
129
+ if (!isDraggingRef.current) return;
130
+ const viewport = viewportNodeRef.current;
131
+ const container = containerRef.current;
132
+ if (!viewport || !container) return;
133
+ const delta = (optionsRef.current.axis === "y" ? e.pageY : e.pageX) - dragStartPosRef.current;
134
+ draggedDistanceRef.current = Math.abs(delta);
135
+ if (draggedDistanceRef.current > 4) {
136
+ e.preventDefault();
137
+ container.style.userSelect = "none";
138
+ container.style.webkitUserSelect = "none";
139
+ viewport.style.cursor = "grabbing";
140
+ let translation = baseTranslationRef.current + delta;
141
+ if (!optionsRef.current.loop) {
142
+ const snaps = snapOffsetsRef.current;
143
+ if (snaps.length > 0) {
144
+ const maxBound = snaps[0];
145
+ const minBound = snaps[snaps.length - 1];
146
+ if (translation > maxBound) translation = maxBound + (translation - maxBound) * .35;
147
+ else if (translation < minBound) translation = minBound + (translation - minBound) * .35;
148
+ }
149
+ }
150
+ translateTrack(translation, false);
151
+ }
152
+ }, [translateTrack]);
153
+ const handlePointerUp = React$1.useCallback((e) => {
154
+ if (!isDraggingRef.current) return;
155
+ isDraggingRef.current = false;
156
+ const viewport = viewportNodeRef.current;
157
+ const container = containerRef.current;
158
+ if (!viewport || !container) return;
159
+ try {
160
+ viewport.releasePointerCapture(e.pointerId);
161
+ } catch {}
162
+ container.style.userSelect = "";
163
+ container.style.webkitUserSelect = "";
164
+ viewport.style.cursor = "";
165
+ const snaps = snapOffsetsRef.current;
166
+ if (snaps.length === 0) return;
167
+ optionsRef.current.axis;
168
+ const delta = currentTranslationRef.current - baseTranslationRef.current;
169
+ const velocity = delta / (Date.now() - dragStartTimeRef.current || 1);
170
+ let targetIndex = activeIndexRef.current;
171
+ if (Math.abs(delta) > 30) {
172
+ if (Math.abs(velocity) > .25) targetIndex = velocity > 0 ? activeIndexRef.current - 1 : activeIndexRef.current + 1;
173
+ else {
174
+ let minDiff = Number.POSITIVE_INFINITY;
175
+ for (let i = 0; i < snaps.length; i++) {
176
+ const diff = Math.abs(currentTranslationRef.current - snaps[i]);
177
+ if (diff < minDiff) {
178
+ minDiff = diff;
179
+ targetIndex = i;
180
+ }
181
+ }
182
+ }
183
+ }
184
+ scrollTo(targetIndex, false);
185
+ }, [scrollTo]);
186
+ const handleClickCapture = React$1.useCallback((e) => {
187
+ if (draggedDistanceRef.current > 6) {
188
+ e.preventDefault();
189
+ e.stopPropagation();
190
+ draggedDistanceRef.current = 0;
191
+ }
192
+ }, []);
193
+ const on = React$1.useCallback((event, cb) => {
194
+ listenersRef.current[event] = listenersRef.current[event] || [];
195
+ listenersRef.current[event].push(cb);
196
+ }, []);
197
+ const off = React$1.useCallback((event, cb) => {
198
+ if (!listenersRef.current[event]) return;
199
+ listenersRef.current[event] = listenersRef.current[event].filter((item) => item !== cb);
200
+ }, []);
201
+ const reInit = React$1.useCallback((newOptions) => {
202
+ if (newOptions) optionsRef.current = {
203
+ ...optionsRef.current,
204
+ ...newOptions
205
+ };
206
+ calculateSnaps();
207
+ scrollTo(activeIndexRef.current, true);
208
+ }, [calculateSnaps, scrollTo]);
209
+ const destroy = React$1.useCallback(() => {
210
+ listenersRef.current = {};
211
+ }, []);
212
+ React$1.useEffect(() => {
213
+ const apiObject = {
214
+ scrollPrev,
215
+ scrollNext,
216
+ scrollTo,
217
+ canScrollPrev,
218
+ canScrollNext,
219
+ selectedScrollSnap,
220
+ scrollSnapList,
221
+ on,
222
+ off,
223
+ reInit,
224
+ destroy
225
+ };
226
+ apiRef.current = apiObject;
227
+ setApi(apiObject);
228
+ }, [
229
+ scrollPrev,
230
+ scrollNext,
231
+ scrollTo,
232
+ canScrollPrev,
233
+ canScrollNext,
234
+ selectedScrollSnap,
235
+ scrollSnapList,
236
+ on,
237
+ off,
238
+ reInit,
239
+ destroy
240
+ ]);
241
+ React$1.useEffect(() => {
242
+ const viewport = viewportNode;
243
+ if (!viewport) return;
244
+ viewportNodeRef.current = viewport;
245
+ const container = viewport.firstElementChild;
246
+ containerRef.current = container;
247
+ calculateSnaps();
248
+ const observer = new ResizeObserver(() => calculateSnaps());
249
+ observer.observe(viewport);
250
+ if (container) observer.observe(container);
251
+ scrollTo(activeIndexRef.current, true);
252
+ viewport.addEventListener("pointerdown", handlePointerDown);
253
+ viewport.addEventListener("pointermove", handlePointerMove);
254
+ window.addEventListener("pointerup", handlePointerUp);
255
+ window.addEventListener("pointercancel", handlePointerUp);
256
+ viewport.addEventListener("click", handleClickCapture, true);
257
+ return () => {
258
+ observer.disconnect();
259
+ viewport.removeEventListener("pointerdown", handlePointerDown);
260
+ viewport.removeEventListener("pointermove", handlePointerMove);
261
+ window.removeEventListener("pointerup", handlePointerUp);
262
+ window.removeEventListener("pointercancel", handlePointerUp);
263
+ viewport.removeEventListener("click", handleClickCapture, true);
264
+ };
265
+ }, [
266
+ viewportNode,
267
+ calculateSnaps,
268
+ scrollTo,
269
+ handlePointerDown,
270
+ handlePointerMove,
271
+ handlePointerUp,
272
+ handleClickCapture
273
+ ]);
274
+ React$1.useEffect(() => {
275
+ if (!api || plugins.length === 0) return;
276
+ for (const plugin of plugins) if (plugin && typeof plugin.init === "function") plugin.init(api);
277
+ }, [api, plugins]);
278
+ return [React$1.useCallback((node) => {
279
+ setViewportNode(node);
280
+ }, []), api];
281
+ }
282
+ const CarouselContext = React$1.createContext(null);
283
+ function useCarousel() {
284
+ const context = React$1.useContext(CarouselContext);
285
+ if (!context) throw new Error("useCarousel must be used within a <Carousel />");
286
+ return context;
287
+ }
288
+ function Carousel({ orientation = "horizontal", opts, plugins, autoplay = false, autoplayInterval = 5e3, loop = true, className, children, ...props }) {
289
+ const [carouselRef, api] = useEmblaCarousel(React$1.useMemo(() => ({
290
+ axis: orientation === "horizontal" ? "x" : "y",
291
+ loop,
292
+ ...opts
293
+ }), [
294
+ orientation,
295
+ loop,
296
+ opts
297
+ ]), plugins);
298
+ const [canScrollPrev, setCanScrollPrev] = React$1.useState(false);
299
+ const [canScrollNext, setCanScrollNext] = React$1.useState(false);
300
+ const [activeIndex, setActiveIndex] = React$1.useState(0);
301
+ const autoplayTimerRef = React$1.useRef(null);
302
+ const isHoveredRef = React$1.useRef(false);
303
+ const isFocusedRef = React$1.useRef(false);
304
+ const onSelect = React$1.useCallback((emblaApi) => {
305
+ if (!emblaApi) return;
306
+ setCanScrollPrev(emblaApi.canScrollPrev());
307
+ setCanScrollNext(emblaApi.canScrollNext());
308
+ setActiveIndex(emblaApi.selectedScrollSnap());
309
+ }, []);
310
+ const scrollPrev = React$1.useCallback(() => {
311
+ api?.scrollPrev();
312
+ }, [api]);
313
+ const scrollNext = React$1.useCallback(() => {
314
+ api?.scrollNext();
315
+ }, [api]);
316
+ const stopAutoplay = React$1.useCallback(() => {
317
+ if (autoplayTimerRef.current) {
318
+ clearInterval(autoplayTimerRef.current);
319
+ autoplayTimerRef.current = null;
320
+ }
321
+ }, []);
322
+ const startAutoplay = React$1.useCallback(() => {
323
+ if (!autoplay || !api) return;
324
+ stopAutoplay();
325
+ autoplayTimerRef.current = setInterval(() => {
326
+ if (!isHoveredRef.current && !isFocusedRef.current) api.scrollNext();
327
+ }, autoplayInterval);
328
+ }, [
329
+ autoplay,
330
+ autoplayInterval,
331
+ api,
332
+ stopAutoplay
333
+ ]);
334
+ React$1.useEffect(() => {
335
+ if (!api) return;
336
+ onSelect(api);
337
+ api.on("select", onSelect);
338
+ api.on("reInit", onSelect);
339
+ startAutoplay();
340
+ return () => {
341
+ api.off("select", onSelect);
342
+ api.off("reInit", onSelect);
343
+ stopAutoplay();
344
+ };
345
+ }, [
346
+ api,
347
+ onSelect,
348
+ startAutoplay,
349
+ stopAutoplay
350
+ ]);
351
+ const handleKeyDown = React$1.useCallback((event) => {
352
+ if (orientation === "horizontal") {
353
+ if (event.key === "ArrowLeft") {
354
+ event.preventDefault();
355
+ scrollPrev();
356
+ } else if (event.key === "ArrowRight") {
357
+ event.preventDefault();
358
+ scrollNext();
359
+ }
360
+ } else if (event.key === "ArrowUp") {
361
+ event.preventDefault();
362
+ scrollPrev();
363
+ } else if (event.key === "ArrowDown") {
364
+ event.preventDefault();
365
+ scrollNext();
366
+ }
367
+ }, [
368
+ scrollPrev,
369
+ scrollNext,
370
+ orientation
371
+ ]);
372
+ const contextValue = React$1.useMemo(() => ({
373
+ carouselRef,
374
+ api,
375
+ orientation,
376
+ scrollPrev,
377
+ scrollNext,
378
+ canScrollPrev,
379
+ canScrollNext,
380
+ autoplay,
381
+ autoplayInterval,
382
+ loop,
383
+ activeIndex
384
+ }), [
385
+ carouselRef,
386
+ api,
387
+ orientation,
388
+ scrollPrev,
389
+ scrollNext,
390
+ canScrollPrev,
391
+ canScrollNext,
392
+ autoplay,
393
+ autoplayInterval,
394
+ loop,
395
+ activeIndex
396
+ ]);
397
+ return /* @__PURE__ */ jsx(CarouselContext.Provider, {
398
+ value: contextValue,
399
+ children: /* @__PURE__ */ jsx("div", {
400
+ onKeyDownCapture: handleKeyDown,
401
+ onMouseEnter: () => {
402
+ isHoveredRef.current = true;
403
+ stopAutoplay();
404
+ },
405
+ onMouseLeave: () => {
406
+ isHoveredRef.current = false;
407
+ startAutoplay();
408
+ },
409
+ onFocus: () => {
410
+ isFocusedRef.current = true;
411
+ stopAutoplay();
412
+ },
413
+ onBlur: () => {
414
+ isFocusedRef.current = false;
415
+ startAutoplay();
416
+ },
417
+ className: cn("relative outline-none", className),
418
+ role: "region",
419
+ "aria-roledescription": "carousel",
420
+ "data-slot": "carousel",
421
+ ...props,
422
+ children
423
+ })
424
+ });
425
+ }
426
+ function CarouselContent({ className, ...props }) {
427
+ const { carouselRef, orientation } = useCarousel();
428
+ return /* @__PURE__ */ jsx("div", {
429
+ ref: carouselRef,
430
+ className: "overflow-hidden w-full h-full relative",
431
+ "data-slot": "carousel-viewport",
432
+ children: /* @__PURE__ */ jsx("div", {
433
+ className: cn("flex h-full w-full touch-pan-y pointer-events-auto will-change-transform", orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col", className),
434
+ style: props.style,
435
+ "data-slot": "carousel-content",
436
+ ...props
437
+ })
438
+ });
439
+ }
440
+ function CarouselItem({ className, ...props }) {
441
+ const { orientation } = useCarousel();
442
+ return /* @__PURE__ */ jsx("div", {
443
+ role: "group",
444
+ "aria-roledescription": "slide",
445
+ className: cn("min-w-0 shrink-0 grow-0 basis-full select-none", orientation === "horizontal" ? "pl-4" : "pt-4", className),
446
+ "data-slot": "carousel-item",
447
+ ...props
448
+ });
449
+ }
450
+ function CarouselPrevious({ className, variant = "outline", size = "icon-sm", ...props }) {
451
+ const { orientation, scrollPrev, canScrollPrev } = useCarousel();
452
+ return /* @__PURE__ */ jsxs(Button, {
453
+ "data-slot": "carousel-previous",
454
+ variant,
455
+ size,
456
+ className: cn("absolute z-10 rounded-full", orientation === "horizontal" ? "inset-y-0 -left-12 my-auto" : "-top-12 left-1/2 -translate-x-1/2 rotate-90", className),
457
+ disabled: !canScrollPrev,
458
+ onClick: scrollPrev,
459
+ ...props,
460
+ children: [/* @__PURE__ */ jsx(ChevronLeft, { className: "size-4.5 sm:size-4 cn-rtl-flip" }), /* @__PURE__ */ jsx("span", {
461
+ className: "sr-only",
462
+ children: "Previous slide"
463
+ })]
464
+ });
465
+ }
466
+ function CarouselNext({ className, variant = "outline", size = "icon-sm", ...props }) {
467
+ const { orientation, scrollNext, canScrollNext } = useCarousel();
468
+ return /* @__PURE__ */ jsxs(Button, {
469
+ "data-slot": "carousel-next",
470
+ variant,
471
+ size,
472
+ className: cn("absolute z-10 rounded-full", orientation === "horizontal" ? "inset-y-0 -right-12 my-auto" : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90", className),
473
+ disabled: !canScrollNext,
474
+ onClick: scrollNext,
475
+ ...props,
476
+ children: [/* @__PURE__ */ jsx(ChevronRight, { className: "size-4.5 sm:size-4 cn-rtl-flip" }), /* @__PURE__ */ jsx("span", {
477
+ className: "sr-only",
478
+ children: "Next slide"
479
+ })]
480
+ });
481
+ }
482
+ function CarouselDots({ className, ...props }) {
483
+ const { api, activeIndex } = useCarousel();
484
+ const snaps = api ? api.scrollSnapList() : [];
485
+ if (snaps.length <= 1) return null;
486
+ return /* @__PURE__ */ jsx("div", {
487
+ className: cn("flex justify-center items-center gap-1.5", className),
488
+ role: "tablist",
489
+ "aria-label": "Carousel pagination",
490
+ "data-slot": "carousel-dots",
491
+ ...props,
492
+ children: snaps.map((_, i) => /* @__PURE__ */ jsx("button", {
493
+ type: "button",
494
+ role: "tab",
495
+ "aria-selected": i === activeIndex,
496
+ "aria-label": `Go to slide ${i + 1}`,
497
+ className: cn("h-1.5 rounded-full transition-[width,background-color] duration-300 pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11 focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-none", i === activeIndex ? "bg-foreground w-4" : "bg-muted-foreground/30 hover:bg-muted-foreground/50 w-1.5"),
498
+ onClick: () => api?.scrollTo(i)
499
+ }, i))
500
+ });
501
+ }
502
+ //#endregion
503
+ export { Carousel, CarouselContent, CarouselDots, CarouselItem, CarouselNext, CarouselPrevious, useCarousel, useEmblaCarousel };