@giddaa-housing/ui 0.1.0 → 1.1.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 (315) hide show
  1. package/README.md +18 -6
  2. package/css/base.css +37 -0
  3. package/css/components.css +135 -0
  4. package/css/generated/shared.css +1 -0
  5. package/css/giddaa.css +402 -0
  6. package/css/preset.css +77 -0
  7. package/css/styles.css +2 -0
  8. package/css/theme.css +255 -0
  9. package/dist/accordion.d.ts +9 -10
  10. package/dist/accordion.js +41 -117
  11. package/dist/activity-timeline.d.ts +29 -0
  12. package/dist/activity-timeline.js +97 -0
  13. package/dist/alert.d.ts +8 -9
  14. package/dist/alert.js +53 -141
  15. package/dist/auth-layout.d.ts +23 -0
  16. package/dist/auth-layout.js +153 -0
  17. package/dist/avatar.d.ts +6 -6
  18. package/dist/avatar.js +40 -142
  19. package/dist/badge.d.ts +12 -13
  20. package/dist/badge.js +66 -114
  21. package/dist/bar-chart.d.ts +136 -114
  22. package/dist/bar-chart.js +244 -297
  23. package/dist/breadcrumb.d.ts +5 -5
  24. package/dist/breadcrumb.js +56 -148
  25. package/dist/bullet-chart.d.ts +33 -33
  26. package/dist/bullet-chart.js +123 -183
  27. package/dist/button-BZIeyUw6.d.ts +17 -0
  28. package/dist/button-group.d.ts +13 -16
  29. package/dist/button-group.js +38 -163
  30. package/dist/button.d.ts +2 -19
  31. package/dist/button.js +90 -142
  32. package/dist/calendar.d.ts +6 -6
  33. package/dist/calendar.js +134 -288
  34. package/dist/card.d.ts +14 -16
  35. package/dist/card.js +58 -174
  36. package/dist/carousel.d.ts +34 -35
  37. package/dist/carousel.js +319 -378
  38. package/dist/chart.d.ts +58 -59
  39. package/dist/chart.js +350 -466
  40. package/dist/checkbox.d.ts +10 -12
  41. package/dist/checkbox.js +84 -84
  42. package/dist/cn-BI_4DMBf.js +23 -0
  43. package/dist/collapsible.d.ts +7 -8
  44. package/dist/collapsible.js +23 -77
  45. package/dist/combobox.d.ts +10 -10
  46. package/dist/combobox.js +220 -696
  47. package/dist/cta.d.ts +64 -0
  48. package/dist/cta.js +192 -0
  49. package/dist/currency-selector.d.ts +41 -0
  50. package/dist/currency-selector.js +114 -0
  51. package/dist/data-table.d.ts +164 -0
  52. package/dist/data-table.js +673 -0
  53. package/dist/date-picker.d.ts +27 -20
  54. package/dist/date-picker.js +122 -520
  55. package/dist/details-card.d.ts +19 -0
  56. package/dist/details-card.js +118 -0
  57. package/dist/dialog.d.ts +13 -14
  58. package/dist/dialog.js +117 -320
  59. package/dist/dropdown-menu.d.ts +14 -14
  60. package/dist/dropdown-menu.js +170 -365
  61. package/dist/dropzone.d.ts +55 -55
  62. package/dist/dropzone.js +328 -467
  63. package/dist/editorial-card.d.ts +27 -0
  64. package/dist/editorial-card.js +144 -0
  65. package/dist/empty-state.d.ts +8 -9
  66. package/dist/empty-state.js +48 -135
  67. package/dist/field.d.ts +23 -25
  68. package/dist/field.js +111 -327
  69. package/dist/filter.d.ts +118 -0
  70. package/dist/filter.js +775 -0
  71. package/dist/footer.d.ts +40 -0
  72. package/dist/footer.js +227 -0
  73. package/dist/funnel-chart.d.ts +38 -41
  74. package/dist/funnel-chart.js +168 -563
  75. package/dist/gallery-indicator.d.ts +17 -0
  76. package/dist/gallery-indicator.js +75 -0
  77. package/dist/heatmap-chart.d.ts +95 -0
  78. package/dist/heatmap-chart.js +197 -0
  79. package/dist/infotip.d.ts +10 -0
  80. package/dist/infotip.js +40 -0
  81. package/dist/input-CfoEJ8A6.d.ts +12 -0
  82. package/dist/input-group.d.ts +16 -19
  83. package/dist/input-group.js +92 -372
  84. package/dist/input-size-context-C-SFx9sx.d.ts +10 -0
  85. package/dist/input-size-context.d.ts +2 -11
  86. package/dist/input-size-context.js +14 -20
  87. package/dist/input.d.ts +2 -13
  88. package/dist/input.js +23 -79
  89. package/dist/item.d.ts +7 -8
  90. package/dist/item.js +22 -89
  91. package/dist/kpi-card.d.ts +18 -20
  92. package/dist/kpi-card.js +84 -232
  93. package/dist/label.d.ts +6 -6
  94. package/dist/label.js +39 -66
  95. package/dist/line-chart.d.ts +88 -89
  96. package/dist/line-chart.js +143 -262
  97. package/dist/logo.d.ts +4 -4
  98. package/dist/logo.js +87 -141
  99. package/dist/map-indicator.d.ts +13 -0
  100. package/dist/map-indicator.js +83 -0
  101. package/dist/match.d.ts +15 -0
  102. package/dist/match.js +68 -0
  103. package/dist/media-gallery-hero.d.ts +58 -0
  104. package/dist/media-gallery-hero.js +201 -0
  105. package/dist/media-player.d.ts +60 -0
  106. package/dist/media-player.js +919 -0
  107. package/dist/multi-step-form.d.ts +56 -0
  108. package/dist/multi-step-form.js +342 -0
  109. package/dist/number-input.d.ts +34 -34
  110. package/dist/number-input.js +62 -413
  111. package/dist/page-header.d.ts +10 -11
  112. package/dist/page-header.js +34 -107
  113. package/dist/pagination.d.ts +17 -20
  114. package/dist/pagination.js +132 -341
  115. package/dist/password-input.d.ts +5 -12
  116. package/dist/password-input.js +32 -354
  117. package/dist/phone-input.d.ts +19 -19
  118. package/dist/phone-input.js +232 -561
  119. package/dist/photo-gallery.d.ts +20 -20
  120. package/dist/photo-gallery.js +314 -746
  121. package/dist/picker-lzgmsNfG.js +32 -0
  122. package/dist/pie-chart.d.ts +60 -60
  123. package/dist/pie-chart.js +141 -184
  124. package/dist/popover.d.ts +9 -9
  125. package/dist/popover.js +60 -156
  126. package/dist/price-tag.d.ts +34 -0
  127. package/dist/price-tag.js +118 -0
  128. package/dist/progress.d.ts +18 -16
  129. package/dist/progress.js +156 -300
  130. package/dist/property-listing-card.d.ts +29 -0
  131. package/dist/property-listing-card.js +117 -0
  132. package/dist/radar-chart.d.ts +108 -0
  133. package/dist/radar-chart.js +172 -0
  134. package/dist/radio-group.d.ts +11 -13
  135. package/dist/radio-group.js +47 -96
  136. package/dist/review-block.d.ts +18 -0
  137. package/dist/review-block.js +154 -0
  138. package/dist/rich-text-editor.d.ts +30 -14
  139. package/dist/rich-text-editor.js +594 -979
  140. package/dist/scatter-chart.d.ts +140 -0
  141. package/dist/scatter-chart.js +248 -0
  142. package/dist/search-input.d.ts +8 -15
  143. package/dist/search-input.js +58 -408
  144. package/dist/select.d.ts +8 -8
  145. package/dist/select.js +131 -291
  146. package/dist/separator.d.ts +8 -9
  147. package/dist/separator.js +31 -70
  148. package/dist/sheet.d.ts +11 -11
  149. package/dist/sheet.js +84 -262
  150. package/dist/sidebar.d.ts +32 -37
  151. package/dist/sidebar.js +380 -1055
  152. package/dist/size-context-D4mYvcg8.d.ts +10 -0
  153. package/dist/size-context.d.ts +2 -11
  154. package/dist/size-context.js +14 -18
  155. package/dist/skeleton.d.ts +4 -5
  156. package/dist/skeleton.js +9 -45
  157. package/dist/slider.d.ts +27 -0
  158. package/dist/slider.js +81 -0
  159. package/dist/sparkline.d.ts +43 -46
  160. package/dist/sparkline.js +223 -561
  161. package/dist/stepper.d.ts +23 -24
  162. package/dist/stepper.js +149 -276
  163. package/dist/styles.css +9995 -2
  164. package/dist/switch.d.ts +10 -12
  165. package/dist/switch.js +49 -106
  166. package/dist/table-card.d.ts +35 -0
  167. package/dist/table-card.js +125 -0
  168. package/dist/table.d.ts +18 -14
  169. package/dist/table.js +114 -182
  170. package/dist/tabs.d.ts +23 -15
  171. package/dist/tabs.js +62 -149
  172. package/dist/tag.d.ts +22 -23
  173. package/dist/tag.js +104 -156
  174. package/dist/testimonial-block.d.ts +33 -0
  175. package/dist/testimonial-block.js +208 -0
  176. package/dist/textarea-IS_D8pXf.d.ts +11 -0
  177. package/dist/textarea.d.ts +2 -12
  178. package/dist/textarea.js +20 -74
  179. package/dist/time-picker.d.ts +11 -11
  180. package/dist/time-picker.js +247 -464
  181. package/dist/toast.d.ts +16 -18
  182. package/dist/toast.js +154 -310
  183. package/dist/tooltip.d.ts +9 -10
  184. package/dist/tooltip.js +33 -91
  185. package/dist/tree-map.d.ts +54 -57
  186. package/dist/tree-map.js +231 -646
  187. package/dist/use-uncontrolled-CLfM1XbB.js +21 -0
  188. package/dist/waterfall-chart.d.ts +126 -0
  189. package/dist/waterfall-chart.js +480 -0
  190. package/package.json +123 -34
  191. package/dist/accordion.js.map +0 -1
  192. package/dist/alert.js.map +0 -1
  193. package/dist/avatar.js.map +0 -1
  194. package/dist/badge.js.map +0 -1
  195. package/dist/bar-chart.js.map +0 -1
  196. package/dist/base.css +0 -32
  197. package/dist/breadcrumb.js.map +0 -1
  198. package/dist/bullet-chart.js.map +0 -1
  199. package/dist/button-group.js.map +0 -1
  200. package/dist/button.js.map +0 -1
  201. package/dist/calendar.js.map +0 -1
  202. package/dist/card.js.map +0 -1
  203. package/dist/carousel.js.map +0 -1
  204. package/dist/chart.js.map +0 -1
  205. package/dist/checkbox.js.map +0 -1
  206. package/dist/collapsible.js.map +0 -1
  207. package/dist/combobox.js.map +0 -1
  208. package/dist/date-picker.js.map +0 -1
  209. package/dist/dialog.js.map +0 -1
  210. package/dist/dropdown-menu.js.map +0 -1
  211. package/dist/dropzone.js.map +0 -1
  212. package/dist/empty-state.js.map +0 -1
  213. package/dist/field.js.map +0 -1
  214. package/dist/files/red-hat-display-latin-300-italic.woff +0 -0
  215. package/dist/files/red-hat-display-latin-300-italic.woff2 +0 -0
  216. package/dist/files/red-hat-display-latin-300-normal.woff +0 -0
  217. package/dist/files/red-hat-display-latin-300-normal.woff2 +0 -0
  218. package/dist/files/red-hat-display-latin-400-italic.woff +0 -0
  219. package/dist/files/red-hat-display-latin-400-italic.woff2 +0 -0
  220. package/dist/files/red-hat-display-latin-400-normal.woff +0 -0
  221. package/dist/files/red-hat-display-latin-400-normal.woff2 +0 -0
  222. package/dist/files/red-hat-display-latin-500-italic.woff +0 -0
  223. package/dist/files/red-hat-display-latin-500-italic.woff2 +0 -0
  224. package/dist/files/red-hat-display-latin-500-normal.woff +0 -0
  225. package/dist/files/red-hat-display-latin-500-normal.woff2 +0 -0
  226. package/dist/files/red-hat-display-latin-600-italic.woff +0 -0
  227. package/dist/files/red-hat-display-latin-600-italic.woff2 +0 -0
  228. package/dist/files/red-hat-display-latin-600-normal.woff +0 -0
  229. package/dist/files/red-hat-display-latin-600-normal.woff2 +0 -0
  230. package/dist/files/red-hat-display-latin-700-italic.woff +0 -0
  231. package/dist/files/red-hat-display-latin-700-italic.woff2 +0 -0
  232. package/dist/files/red-hat-display-latin-700-normal.woff +0 -0
  233. package/dist/files/red-hat-display-latin-700-normal.woff2 +0 -0
  234. package/dist/files/red-hat-display-latin-800-italic.woff +0 -0
  235. package/dist/files/red-hat-display-latin-800-italic.woff2 +0 -0
  236. package/dist/files/red-hat-display-latin-800-normal.woff +0 -0
  237. package/dist/files/red-hat-display-latin-800-normal.woff2 +0 -0
  238. package/dist/files/red-hat-display-latin-900-italic.woff +0 -0
  239. package/dist/files/red-hat-display-latin-900-italic.woff2 +0 -0
  240. package/dist/files/red-hat-display-latin-900-normal.woff +0 -0
  241. package/dist/files/red-hat-display-latin-900-normal.woff2 +0 -0
  242. package/dist/files/red-hat-display-latin-ext-300-italic.woff +0 -0
  243. package/dist/files/red-hat-display-latin-ext-300-italic.woff2 +0 -0
  244. package/dist/files/red-hat-display-latin-ext-300-normal.woff +0 -0
  245. package/dist/files/red-hat-display-latin-ext-300-normal.woff2 +0 -0
  246. package/dist/files/red-hat-display-latin-ext-400-italic.woff +0 -0
  247. package/dist/files/red-hat-display-latin-ext-400-italic.woff2 +0 -0
  248. package/dist/files/red-hat-display-latin-ext-400-normal.woff +0 -0
  249. package/dist/files/red-hat-display-latin-ext-400-normal.woff2 +0 -0
  250. package/dist/files/red-hat-display-latin-ext-500-italic.woff +0 -0
  251. package/dist/files/red-hat-display-latin-ext-500-italic.woff2 +0 -0
  252. package/dist/files/red-hat-display-latin-ext-500-normal.woff +0 -0
  253. package/dist/files/red-hat-display-latin-ext-500-normal.woff2 +0 -0
  254. package/dist/files/red-hat-display-latin-ext-600-italic.woff +0 -0
  255. package/dist/files/red-hat-display-latin-ext-600-italic.woff2 +0 -0
  256. package/dist/files/red-hat-display-latin-ext-600-normal.woff +0 -0
  257. package/dist/files/red-hat-display-latin-ext-600-normal.woff2 +0 -0
  258. package/dist/files/red-hat-display-latin-ext-700-italic.woff +0 -0
  259. package/dist/files/red-hat-display-latin-ext-700-italic.woff2 +0 -0
  260. package/dist/files/red-hat-display-latin-ext-700-normal.woff +0 -0
  261. package/dist/files/red-hat-display-latin-ext-700-normal.woff2 +0 -0
  262. package/dist/files/red-hat-display-latin-ext-800-italic.woff +0 -0
  263. package/dist/files/red-hat-display-latin-ext-800-italic.woff2 +0 -0
  264. package/dist/files/red-hat-display-latin-ext-800-normal.woff +0 -0
  265. package/dist/files/red-hat-display-latin-ext-800-normal.woff2 +0 -0
  266. package/dist/files/red-hat-display-latin-ext-900-italic.woff +0 -0
  267. package/dist/files/red-hat-display-latin-ext-900-italic.woff2 +0 -0
  268. package/dist/files/red-hat-display-latin-ext-900-normal.woff +0 -0
  269. package/dist/files/red-hat-display-latin-ext-900-normal.woff2 +0 -0
  270. package/dist/funnel-chart.js.map +0 -1
  271. package/dist/index.d.ts +0 -87
  272. package/dist/index.js +0 -10448
  273. package/dist/index.js.map +0 -1
  274. package/dist/input-group.js.map +0 -1
  275. package/dist/input-size-context.js.map +0 -1
  276. package/dist/input.js.map +0 -1
  277. package/dist/item.js.map +0 -1
  278. package/dist/kpi-card.js.map +0 -1
  279. package/dist/label.js.map +0 -1
  280. package/dist/line-chart.js.map +0 -1
  281. package/dist/logo.js.map +0 -1
  282. package/dist/number-input.js.map +0 -1
  283. package/dist/page-header.js.map +0 -1
  284. package/dist/pagination.js.map +0 -1
  285. package/dist/password-input.js.map +0 -1
  286. package/dist/phone-input.js.map +0 -1
  287. package/dist/photo-gallery.js.map +0 -1
  288. package/dist/pie-chart.js.map +0 -1
  289. package/dist/popover.js.map +0 -1
  290. package/dist/progress.js.map +0 -1
  291. package/dist/radio-group.js.map +0 -1
  292. package/dist/red-hat-display.css +0 -2
  293. package/dist/rich-text-editor.js.map +0 -1
  294. package/dist/search-input.js.map +0 -1
  295. package/dist/select.js.map +0 -1
  296. package/dist/separator.js.map +0 -1
  297. package/dist/sheet.js.map +0 -1
  298. package/dist/sidebar.js.map +0 -1
  299. package/dist/size-context.js.map +0 -1
  300. package/dist/skeleton.js.map +0 -1
  301. package/dist/sparkline.js.map +0 -1
  302. package/dist/stepper.js.map +0 -1
  303. package/dist/switch.js.map +0 -1
  304. package/dist/tab-list.d.ts +0 -38
  305. package/dist/tab-list.js +0 -394
  306. package/dist/tab-list.js.map +0 -1
  307. package/dist/table.js.map +0 -1
  308. package/dist/tabs.js.map +0 -1
  309. package/dist/tag.js.map +0 -1
  310. package/dist/textarea.js.map +0 -1
  311. package/dist/theme/giddaa.css +0 -2
  312. package/dist/time-picker.js.map +0 -1
  313. package/dist/toast.js.map +0 -1
  314. package/dist/tooltip.js.map +0 -1
  315. package/dist/tree-map.js.map +0 -1
package/dist/carousel.js CHANGED
@@ -1,396 +1,337 @@
1
- // src/components/ui/carousel.tsx
2
- import { cva } from "class-variance-authority";
3
- import useEmblaCarousel from "embla-carousel-react";
1
+ "use client";
2
+ import { t as cn } from "./cn-BI_4DMBf.js";
3
+ import { useComponentSize } from "./size-context.js";
4
4
  import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ import { cva } from "class-variance-authority";
5
7
  import * as React from "react";
6
-
7
- // src/lib/cn.ts
8
- import { clsx } from "clsx";
9
- import { extendTailwindMerge } from "tailwind-merge";
10
- var twMerge = extendTailwindMerge({
11
- extend: {
12
- classGroups: {
13
- "font-size": [
14
- {
15
- text: [
16
- "gdt-display",
17
- "gdt-h1",
18
- "gdt-h2",
19
- "gdt-h3",
20
- "gdt-h4",
21
- "gdt-h5",
22
- "gdt-xl",
23
- "gdt-lg",
24
- "gdt-md",
25
- "gdt-sm",
26
- "gdt-xs",
27
- "gdt-subtext",
28
- "gdt-capitalized"
29
- ]
30
- }
31
- ]
32
- }
33
- }
8
+ import useEmblaCarousel from "embla-carousel-react";
9
+ //#region src/carousel.tsx
10
+ /**
11
+ * Shared glassmorphic treatment for every overlay surface in the carousel
12
+ * (navigation arrows + indicator). Dark glass at 35% over a 16px backdrop
13
+ * blur with a near-invisible 18% light border that lifts the chrome off the
14
+ * imagery. Always dark, in both themes — see `--color-surface-glass-overlay-button`.
15
+ */
16
+ const glassChrome = "border border-fg-on-brand/[0.18] bg-surface-glass-overlay-button backdrop-blur-[16px]";
17
+ const carouselVariants = cva("relative overflow-hidden rounded-2xl bg-surface-brand-subtle", {
18
+ variants: { imageSize: {
19
+ sm: "w-[320px] max-w-full aspect-[320/220]",
20
+ md: "w-[520px] max-w-full aspect-[520/340]",
21
+ lg: "w-[800px] max-w-full aspect-[800/500]",
22
+ full: "w-full"
23
+ } },
24
+ defaultVariants: { imageSize: "md" }
34
25
  });
35
- function cn(...inputs) {
36
- return twMerge(clsx(inputs));
37
- }
38
-
39
- // src/components/ui/size-context.tsx
40
- import { createContext, useContext } from "react";
41
- import { Fragment, jsx } from "react/jsx-runtime";
42
- var SizeContext = createContext(void 0);
43
- function useComponentSize(size, fallback = "md") {
44
- const inheritedSize = useContext(SizeContext);
45
- return size ?? inheritedSize ?? fallback;
46
- }
47
-
48
- // src/components/ui/carousel.tsx
49
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
50
- var glassChrome = "border border-fg-on-brand/[0.18] bg-surface-glass-overlay-button backdrop-blur-[16px]";
51
- var carouselVariants = cva(
52
- "relative overflow-hidden rounded-2xl bg-surface-brand-subtle",
53
- {
54
- variants: {
55
- imageSize: {
56
- sm: "w-[320px] max-w-full aspect-[320/220]",
57
- md: "w-[520px] max-w-full aspect-[520/340]",
58
- lg: "w-[800px] max-w-full aspect-[800/500]",
59
- full: "w-full"
60
- }
61
- },
62
- defaultVariants: {
63
- imageSize: "md"
64
- }
65
- }
66
- );
67
- var CarouselContext = React.createContext(null);
26
+ const CarouselContext = React.createContext(null);
68
27
  function useCarousel() {
69
- const context = React.useContext(CarouselContext);
70
- if (!context) {
71
- throw new Error("useCarousel must be used within a <Carousel />");
72
- }
73
- return context;
28
+ const context = React.useContext(CarouselContext);
29
+ if (!context) throw new Error("useCarousel must be used within a <Carousel />");
30
+ return context;
74
31
  }
75
- function Carousel({
76
- orientation = "horizontal",
77
- opts,
78
- setApi,
79
- plugins,
80
- size,
81
- imageSize,
82
- className,
83
- children,
84
- ...props
85
- }) {
86
- const resolvedSize = useComponentSize(size);
87
- const [carouselRef, api] = useEmblaCarousel(
88
- {
89
- ...opts,
90
- axis: orientation === "horizontal" ? "x" : "y"
91
- },
92
- plugins
93
- );
94
- const [canScrollPrev, setCanScrollPrev] = React.useState(false);
95
- const [canScrollNext, setCanScrollNext] = React.useState(false);
96
- const [selectedIndex, setSelectedIndex] = React.useState(0);
97
- const [scrollSnaps, setScrollSnaps] = React.useState([]);
98
- const onSelect = React.useCallback((api2) => {
99
- if (!api2) return;
100
- setCanScrollPrev(api2.canScrollPrev());
101
- setCanScrollNext(api2.canScrollNext());
102
- setSelectedIndex(api2.selectedScrollSnap());
103
- }, []);
104
- const onReInit = React.useCallback(
105
- (api2) => {
106
- if (!api2) return;
107
- setScrollSnaps(api2.scrollSnapList());
108
- onSelect(api2);
109
- },
110
- [onSelect]
111
- );
112
- const scrollPrev = React.useCallback(() => {
113
- api?.scrollPrev();
114
- }, [api]);
115
- const scrollNext = React.useCallback(() => {
116
- api?.scrollNext();
117
- }, [api]);
118
- const scrollTo = React.useCallback(
119
- (index) => {
120
- api?.scrollTo(index);
121
- },
122
- [api]
123
- );
124
- const handleKeyDown = React.useCallback(
125
- (event) => {
126
- if (event.key === "ArrowLeft") {
127
- event.preventDefault();
128
- scrollPrev();
129
- } else if (event.key === "ArrowRight") {
130
- event.preventDefault();
131
- scrollNext();
132
- }
133
- },
134
- [scrollPrev, scrollNext]
135
- );
136
- React.useEffect(() => {
137
- if (!api || !setApi) return;
138
- setApi(api);
139
- }, [api, setApi]);
140
- React.useEffect(() => {
141
- if (!api) return;
142
- onReInit(api);
143
- api.on("reInit", onReInit);
144
- api.on("select", onSelect);
145
- return () => {
146
- api?.off("reInit", onReInit);
147
- api?.off("select", onSelect);
148
- };
149
- }, [api, onReInit, onSelect]);
150
- return /* @__PURE__ */ jsx2(
151
- CarouselContext.Provider,
152
- {
153
- value: {
154
- carouselRef,
155
- api,
156
- orientation,
157
- size: resolvedSize,
158
- scrollPrev,
159
- scrollNext,
160
- scrollTo,
161
- canScrollPrev,
162
- canScrollNext,
163
- selectedIndex,
164
- scrollSnaps
165
- },
166
- children: /* @__PURE__ */ jsx2(
167
- "div",
168
- {
169
- onKeyDownCapture: handleKeyDown,
170
- className: cn(carouselVariants({ imageSize }), className),
171
- role: "region",
172
- "aria-roledescription": "carousel",
173
- "data-slot": "carousel",
174
- ...props,
175
- children
176
- }
177
- )
178
- }
179
- );
32
+ function Carousel({ orientation = "horizontal", opts, setApi, plugins, size, imageSize, className, children, ...props }) {
33
+ const resolvedSize = useComponentSize(size);
34
+ const [carouselRef, api] = useEmblaCarousel({
35
+ ...opts,
36
+ axis: orientation === "horizontal" ? "x" : "y"
37
+ }, plugins);
38
+ const [canScrollPrev, setCanScrollPrev] = React.useState(false);
39
+ const [canScrollNext, setCanScrollNext] = React.useState(false);
40
+ const [selectedIndex, setSelectedIndex] = React.useState(0);
41
+ const [scrollSnaps, setScrollSnaps] = React.useState([]);
42
+ const onSelect = React.useCallback((api) => {
43
+ if (!api) return;
44
+ setCanScrollPrev(api.canScrollPrev());
45
+ setCanScrollNext(api.canScrollNext());
46
+ setSelectedIndex(api.selectedScrollSnap());
47
+ }, []);
48
+ const onReInit = React.useCallback((api) => {
49
+ if (!api) return;
50
+ setScrollSnaps(api.scrollSnapList());
51
+ onSelect(api);
52
+ }, [onSelect]);
53
+ const scrollPrev = React.useCallback(() => {
54
+ api?.scrollPrev();
55
+ }, [api]);
56
+ const scrollNext = React.useCallback(() => {
57
+ api?.scrollNext();
58
+ }, [api]);
59
+ const scrollTo = React.useCallback((index) => {
60
+ api?.scrollTo(index);
61
+ }, [api]);
62
+ const handleKeyDown = React.useCallback((event) => {
63
+ const prevKey = orientation === "horizontal" ? "ArrowLeft" : "ArrowUp";
64
+ const nextKey = orientation === "horizontal" ? "ArrowRight" : "ArrowDown";
65
+ if (event.key === prevKey) {
66
+ event.preventDefault();
67
+ scrollPrev();
68
+ } else if (event.key === nextKey) {
69
+ event.preventDefault();
70
+ scrollNext();
71
+ }
72
+ }, [
73
+ orientation,
74
+ scrollPrev,
75
+ scrollNext
76
+ ]);
77
+ React.useEffect(() => {
78
+ if (!api || !setApi) return;
79
+ setApi(api);
80
+ }, [api, setApi]);
81
+ React.useEffect(() => {
82
+ if (!api) return;
83
+ onReInit(api);
84
+ api.on("reInit", onReInit);
85
+ api.on("select", onSelect);
86
+ return () => {
87
+ api?.off("reInit", onReInit);
88
+ api?.off("select", onSelect);
89
+ };
90
+ }, [
91
+ api,
92
+ onReInit,
93
+ onSelect
94
+ ]);
95
+ return /* @__PURE__ */ jsx(CarouselContext.Provider, {
96
+ value: {
97
+ carouselRef,
98
+ api,
99
+ orientation,
100
+ size: resolvedSize,
101
+ scrollPrev,
102
+ scrollNext,
103
+ scrollTo,
104
+ canScrollPrev,
105
+ canScrollNext,
106
+ selectedIndex,
107
+ scrollSnaps
108
+ },
109
+ children: /* @__PURE__ */ jsx("div", {
110
+ onKeyDownCapture: handleKeyDown,
111
+ className: cn(carouselVariants({ imageSize }), className),
112
+ role: "region",
113
+ "aria-roledescription": "carousel",
114
+ "data-slot": "carousel",
115
+ ...props,
116
+ children
117
+ })
118
+ });
180
119
  }
181
120
  function CarouselContent({ className, ...props }) {
182
- const { carouselRef, orientation } = useCarousel();
183
- return /* @__PURE__ */ jsx2(
184
- "div",
185
- {
186
- ref: carouselRef,
187
- className: "h-full overflow-hidden",
188
- "data-slot": "carousel-content",
189
- children: /* @__PURE__ */ jsx2(
190
- "div",
191
- {
192
- className: cn(
193
- "flex h-full",
194
- orientation === "horizontal" ? "" : "flex-col",
195
- className
196
- ),
197
- ...props
198
- }
199
- )
200
- }
201
- );
121
+ const { carouselRef, orientation } = useCarousel();
122
+ return /* @__PURE__ */ jsx("div", {
123
+ ref: carouselRef,
124
+ className: "h-full overflow-hidden",
125
+ "data-slot": "carousel-content",
126
+ children: /* @__PURE__ */ jsx("div", {
127
+ className: cn("flex h-full", orientation === "horizontal" ? "" : "flex-col", className),
128
+ ...props
129
+ })
130
+ });
202
131
  }
203
132
  function CarouselItem({ className, ...props }) {
204
- return (
205
- // biome-ignore lint/a11y/useSemanticElements: a carousel slide is a role="group" with aria-roledescription per the W3C pattern, not a fieldset.
206
- /* @__PURE__ */ jsx2(
207
- "div",
208
- {
209
- role: "group",
210
- "aria-roledescription": "slide",
211
- "data-slot": "carousel-item",
212
- className: cn("min-w-0 shrink-0 grow-0 basis-full", className),
213
- ...props
214
- }
215
- )
216
- );
133
+ return /* @__PURE__ */ jsx("div", {
134
+ role: "group",
135
+ "aria-roledescription": "slide",
136
+ "data-slot": "carousel-item",
137
+ className: cn("min-w-0 shrink-0 grow-0 basis-full", className),
138
+ ...props
139
+ });
217
140
  }
218
- var arrowVariants = cva(
219
- cn(
220
- "absolute top-1/2 z-10 grid -translate-y-1/2 place-items-center rounded-full text-fg-on-brand/95 shadow-1 transition-[transform,opacity] outline-none",
221
- glassChrome,
222
- "hover:scale-105 focus-visible:shadow-[0px_0px_0px_2px_var(--color-line-focus)] active:scale-95 disabled:pointer-events-none disabled:opacity-40"
223
- ),
224
- {
225
- variants: {
226
- size: {
227
- sm: "size-8 [&_svg]:size-4",
228
- md: "size-10 [&_svg]:size-[18px]",
229
- lg: "size-12 [&_svg]:size-5"
230
- },
231
- side: {
232
- prev: "",
233
- next: ""
234
- }
235
- },
236
- compoundVariants: [
237
- { size: "sm", side: "prev", className: "left-3" },
238
- { size: "sm", side: "next", className: "right-3" },
239
- { size: "md", side: "prev", className: "left-4" },
240
- { size: "md", side: "next", className: "right-4" },
241
- { size: "lg", side: "prev", className: "left-5" },
242
- { size: "lg", side: "next", className: "right-5" }
243
- ],
244
- defaultVariants: {
245
- size: "md",
246
- side: "prev"
247
- }
248
- }
249
- );
250
- function CarouselPrevious({
251
- className,
252
- ...props
253
- }) {
254
- const { size, scrollPrev, canScrollPrev } = useCarousel();
255
- return /* @__PURE__ */ jsxs(
256
- "button",
257
- {
258
- type: "button",
259
- "data-slot": "carousel-previous",
260
- className: cn(arrowVariants({ size, side: "prev" }), className),
261
- disabled: !canScrollPrev,
262
- onClick: scrollPrev,
263
- ...props,
264
- children: [
265
- /* @__PURE__ */ jsx2(ChevronLeftIcon, { className: "cn-rtl-flip" }),
266
- /* @__PURE__ */ jsx2("span", { className: "sr-only", children: "Previous slide" })
267
- ]
268
- }
269
- );
141
+ const arrowVariants = cva(cn("absolute top-1/2 z-10 grid -translate-y-1/2 place-items-center rounded-full text-fg-on-brand/95 shadow-1 transition-[transform,opacity] outline-none", glassChrome, "hover:scale-105 focus-visible:shadow-[0px_0px_0px_2px_var(--color-line-focus)] active:scale-95 disabled:pointer-events-none disabled:opacity-40"), {
142
+ variants: {
143
+ size: {
144
+ sm: "size-8 [&_svg]:size-4",
145
+ md: "size-10 [&_svg]:size-[18px]",
146
+ lg: "size-12 [&_svg]:size-5"
147
+ },
148
+ side: {
149
+ prev: "",
150
+ next: ""
151
+ }
152
+ },
153
+ compoundVariants: [
154
+ {
155
+ size: "sm",
156
+ side: "prev",
157
+ className: "left-3"
158
+ },
159
+ {
160
+ size: "sm",
161
+ side: "next",
162
+ className: "right-3"
163
+ },
164
+ {
165
+ size: "md",
166
+ side: "prev",
167
+ className: "left-4"
168
+ },
169
+ {
170
+ size: "md",
171
+ side: "next",
172
+ className: "right-4"
173
+ },
174
+ {
175
+ size: "lg",
176
+ side: "prev",
177
+ className: "left-5"
178
+ },
179
+ {
180
+ size: "lg",
181
+ side: "next",
182
+ className: "right-5"
183
+ }
184
+ ],
185
+ defaultVariants: {
186
+ size: "md",
187
+ side: "prev"
188
+ }
189
+ });
190
+ function CarouselPrevious({ className, ...props }) {
191
+ const { size, scrollPrev, canScrollPrev } = useCarousel();
192
+ return /* @__PURE__ */ jsxs("button", {
193
+ type: "button",
194
+ "data-slot": "carousel-previous",
195
+ className: cn(arrowVariants({
196
+ size,
197
+ side: "prev"
198
+ }), className),
199
+ disabled: !canScrollPrev,
200
+ onClick: scrollPrev,
201
+ ...props,
202
+ children: [/* @__PURE__ */ jsx(ChevronLeftIcon, { className: "cn-rtl-flip" }), /* @__PURE__ */ jsx("span", {
203
+ className: "sr-only",
204
+ children: "Previous slide"
205
+ })]
206
+ });
270
207
  }
271
208
  function CarouselNext({ className, ...props }) {
272
- const { size, scrollNext, canScrollNext } = useCarousel();
273
- return /* @__PURE__ */ jsxs(
274
- "button",
275
- {
276
- type: "button",
277
- "data-slot": "carousel-next",
278
- className: cn(arrowVariants({ size, side: "next" }), className),
279
- disabled: !canScrollNext,
280
- onClick: scrollNext,
281
- ...props,
282
- children: [
283
- /* @__PURE__ */ jsx2(ChevronRightIcon, { className: "cn-rtl-flip" }),
284
- /* @__PURE__ */ jsx2("span", { className: "sr-only", children: "Next slide" })
285
- ]
286
- }
287
- );
209
+ const { size, scrollNext, canScrollNext } = useCarousel();
210
+ return /* @__PURE__ */ jsxs("button", {
211
+ type: "button",
212
+ "data-slot": "carousel-next",
213
+ className: cn(arrowVariants({
214
+ size,
215
+ side: "next"
216
+ }), className),
217
+ disabled: !canScrollNext,
218
+ onClick: scrollNext,
219
+ ...props,
220
+ children: [/* @__PURE__ */ jsx(ChevronRightIcon, { className: "cn-rtl-flip" }), /* @__PURE__ */ jsx("span", {
221
+ className: "sr-only",
222
+ children: "Next slide"
223
+ })]
224
+ });
288
225
  }
289
- var MANY_THRESHOLD = 5;
290
- var MANY_WINDOW = 5;
226
+ /**
227
+ * Past this many items the indicator switches from "show every dot" to the
228
+ * Airbnb-style windowed mode: at most `MANY_WINDOW` dots, the active one kept
229
+ * near the centre, and dots at a clipped edge faded down to imply more beyond.
230
+ */
231
+ const MANY_THRESHOLD = 5;
232
+ const MANY_WINDOW = 5;
233
+ /**
234
+ * Returns the dots to render plus the window start, so the determinate and
235
+ * windowed ("many") cases share one render path. The dot strip is always the
236
+ * full list; `start` drives the translate that slides it under the viewport.
237
+ */
291
238
  function getIndicatorWindow(count, selected) {
292
- if (count < MANY_THRESHOLD) {
293
- const dots2 = Array.from({ length: count }, (_, index) => ({
294
- index,
295
- faded: false
296
- }));
297
- return { dots: dots2, start: 0, visible: count };
298
- }
299
- const half = Math.floor(MANY_WINDOW / 2);
300
- const start = Math.max(0, Math.min(selected - half, count - MANY_WINDOW));
301
- const end = start + MANY_WINDOW - 1;
302
- const overflowLeft = start > 0;
303
- const overflowRight = end < count - 1;
304
- const dots = Array.from({ length: count }, (_, index) => ({
305
- index,
306
- faded: overflowLeft && index === start || overflowRight && index === end
307
- }));
308
- return { dots, start, visible: MANY_WINDOW };
239
+ if (count < MANY_THRESHOLD) return {
240
+ dots: Array.from({ length: count }, (_, index) => ({
241
+ index,
242
+ faded: false
243
+ })),
244
+ start: 0,
245
+ visible: count
246
+ };
247
+ const start = Math.max(0, Math.min(selected - Math.floor(MANY_WINDOW / 2), count - MANY_WINDOW));
248
+ const end = start + MANY_WINDOW - 1;
249
+ const overflowLeft = start > 0;
250
+ const overflowRight = end < count - 1;
251
+ return {
252
+ dots: Array.from({ length: count }, (_, index) => ({
253
+ index,
254
+ faded: overflowLeft && index === start || overflowRight && index === end
255
+ })),
256
+ start,
257
+ visible: MANY_WINDOW
258
+ };
309
259
  }
310
- var INDICATOR_SIZES = {
311
- sm: { dot: 5, gap: 4, padX: 8, padY: 4 },
312
- md: { dot: 7, gap: 5, padX: 10, padY: 5 },
313
- lg: { dot: 9, gap: 6, padX: 12, padY: 6 }
260
+ /** Dot diameter, gap, and pill padding per size — in px to keep them crisp. */
261
+ const INDICATOR_SIZES = {
262
+ sm: {
263
+ dot: 5,
264
+ gap: 4,
265
+ padX: 8,
266
+ padY: 4
267
+ },
268
+ md: {
269
+ dot: 7,
270
+ gap: 5,
271
+ padX: 10,
272
+ padY: 5
273
+ },
274
+ lg: {
275
+ dot: 9,
276
+ gap: 6,
277
+ padX: 12,
278
+ padY: 6
279
+ }
314
280
  };
315
- var INDICATOR_OFFSET = {
316
- sm: "bottom-3",
317
- md: "bottom-[18px]",
318
- lg: "bottom-6"
281
+ /** Distance of the indicator from the bottom edge, per size (12/18/24px). */
282
+ const INDICATOR_OFFSET = {
283
+ sm: "bottom-3",
284
+ md: "bottom-[18px]",
285
+ lg: "bottom-6"
319
286
  };
320
- function CarouselIndicator({
321
- className,
322
- count: countProp,
323
- selected: selectedProp,
324
- size: sizeProp,
325
- onSelect,
326
- ...props
327
- }) {
328
- const ctx = React.useContext(CarouselContext);
329
- const inheritedSize = useComponentSize(sizeProp);
330
- const size = sizeProp ?? ctx?.size ?? inheritedSize;
331
- const count = countProp ?? ctx?.scrollSnaps.length ?? 0;
332
- const selected = selectedProp ?? ctx?.selectedIndex ?? 0;
333
- const handleSelect = onSelect ?? ctx?.scrollTo;
334
- if (count <= 1) return null;
335
- const { dot, gap, padX, padY } = INDICATOR_SIZES[size];
336
- const { dots, start, visible } = getIndicatorWindow(count, selected);
337
- const step = dot + gap;
338
- const viewportWidth = visible * step - gap;
339
- return /* @__PURE__ */ jsx2(
340
- "div",
341
- {
342
- "data-slot": "carousel-indicator",
343
- className: cn(
344
- "absolute left-1/2 z-10 flex -translate-x-1/2 items-center justify-center rounded-full",
345
- INDICATOR_OFFSET[size],
346
- glassChrome,
347
- className
348
- ),
349
- style: { padding: `${padY}px ${padX}px` },
350
- role: "tablist",
351
- "aria-label": "Slide indicators",
352
- ...props,
353
- children: /* @__PURE__ */ jsx2("div", { className: "overflow-hidden", style: { width: viewportWidth }, children: /* @__PURE__ */ jsx2(
354
- "div",
355
- {
356
- className: "flex items-center transition-transform duration-300 ease-out",
357
- style: { gap, transform: `translateX(${-start * step}px)` },
358
- children: dots.map(({ index, faded }) => {
359
- const isActive = index === selected;
360
- return /* @__PURE__ */ jsx2(
361
- "button",
362
- {
363
- type: "button",
364
- role: "tab",
365
- "aria-selected": isActive,
366
- "aria-label": `Go to slide ${index + 1}`,
367
- onClick: () => handleSelect?.(index),
368
- className: cn(
369
- "shrink-0 rounded-full bg-fg-on-brand transition-[transform,opacity] duration-300 ease-out",
370
- handleSelect ? "cursor-pointer" : "cursor-default"
371
- ),
372
- style: {
373
- width: dot,
374
- height: dot,
375
- opacity: faded ? 0.3 : isActive ? 1 : 0.55,
376
- transform: faded ? "scale(0.6)" : "scale(1)"
377
- }
378
- },
379
- index
380
- );
381
- })
382
- }
383
- ) })
384
- }
385
- );
287
+ function CarouselIndicator({ className, count: countProp, selected: selectedProp, size: sizeProp, onSelect, ...props }) {
288
+ const ctx = React.useContext(CarouselContext);
289
+ const inheritedSize = useComponentSize(sizeProp);
290
+ const size = sizeProp ?? ctx?.size ?? inheritedSize;
291
+ const count = countProp ?? ctx?.scrollSnaps.length ?? 0;
292
+ const selected = selectedProp ?? ctx?.selectedIndex ?? 0;
293
+ const handleSelect = onSelect ?? ctx?.scrollTo;
294
+ if (count <= 1) return null;
295
+ const { dot, gap, padX, padY } = INDICATOR_SIZES[size];
296
+ const { dots, start, visible } = getIndicatorWindow(count, selected);
297
+ const step = dot + gap;
298
+ const viewportWidth = visible * step - gap;
299
+ return /* @__PURE__ */ jsx("div", {
300
+ "data-slot": "carousel-indicator",
301
+ className: cn("absolute left-1/2 z-10 flex -translate-x-1/2 items-center justify-center rounded-full", INDICATOR_OFFSET[size], glassChrome, className),
302
+ style: { padding: `${padY}px ${padX}px` },
303
+ role: "tablist",
304
+ "aria-label": "Slide indicators",
305
+ ...props,
306
+ children: /* @__PURE__ */ jsx("div", {
307
+ className: "overflow-hidden",
308
+ style: { width: viewportWidth },
309
+ children: /* @__PURE__ */ jsx("div", {
310
+ className: "flex items-center transition-transform duration-300 ease-out",
311
+ style: {
312
+ gap,
313
+ transform: `translateX(${-start * step}px)`
314
+ },
315
+ children: dots.map(({ index, faded }) => {
316
+ const isActive = index === selected;
317
+ return /* @__PURE__ */ jsx("button", {
318
+ type: "button",
319
+ role: "tab",
320
+ "aria-selected": isActive,
321
+ "aria-label": `Go to slide ${index + 1}`,
322
+ onClick: () => handleSelect?.(index),
323
+ className: cn("shrink-0 rounded-full bg-fg-on-brand transition-[transform,opacity] duration-300 ease-out", handleSelect ? "cursor-pointer" : "cursor-default"),
324
+ style: {
325
+ width: dot,
326
+ height: dot,
327
+ opacity: faded ? .3 : isActive ? 1 : .55,
328
+ transform: faded ? "scale(0.6)" : "scale(1)"
329
+ }
330
+ }, index);
331
+ })
332
+ })
333
+ })
334
+ });
386
335
  }
387
- export {
388
- Carousel,
389
- CarouselContent,
390
- CarouselIndicator,
391
- CarouselItem,
392
- CarouselNext,
393
- CarouselPrevious,
394
- useCarousel
395
- };
396
- //# sourceMappingURL=carousel.js.map
336
+ //#endregion
337
+ export { Carousel, CarouselContent, CarouselIndicator, CarouselItem, CarouselNext, CarouselPrevious, useCarousel };