@central-ui/react 0.1.2 → 0.3.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 (287) hide show
  1. package/LICENSE +49 -0
  2. package/dist/components/accordion/index.d.ts +4 -3
  3. package/dist/components/accordion/index.js +7 -4
  4. package/dist/components/autocomplete/index.d.ts +23 -30
  5. package/dist/components/autocomplete/index.js +81 -56
  6. package/dist/components/avatar/index.d.ts +1 -2
  7. package/dist/components/avatar/index.js +0 -1
  8. package/dist/components/badge/index.d.ts +0 -1
  9. package/dist/components/badge/index.js +2 -2
  10. package/dist/components/banner/index.d.ts +1 -1
  11. package/dist/components/banner/index.js +23 -25
  12. package/dist/components/barchart/index.d.ts +106 -0
  13. package/dist/components/barchart/index.js +122 -0
  14. package/dist/components/breadcrumb/index.d.ts +0 -1
  15. package/dist/components/breadcrumb/index.js +6 -7
  16. package/dist/components/button/index.d.ts +2 -3
  17. package/dist/components/button/index.js +11 -12
  18. package/dist/components/card/index.d.ts +0 -1
  19. package/dist/components/card/index.js +0 -1
  20. package/dist/components/carousel/index.d.ts +169 -0
  21. package/dist/components/carousel/index.js +299 -0
  22. package/dist/components/checkbox/index.d.ts +13 -11
  23. package/dist/components/checkbox/index.js +51 -31
  24. package/dist/components/chip/index.d.ts +1 -1
  25. package/dist/components/chip/index.js +2 -3
  26. package/dist/components/combobox/index.d.ts +33 -49
  27. package/dist/components/combobox/index.js +102 -70
  28. package/dist/components/datepicker/index.d.ts +18 -31
  29. package/dist/components/datepicker/index.js +81 -99
  30. package/dist/components/dialog/index.d.ts +14 -27
  31. package/dist/components/dialog/index.js +17 -18
  32. package/dist/components/divider/index.d.ts +0 -1
  33. package/dist/components/divider/index.js +0 -1
  34. package/dist/components/donutchart/index.d.ts +100 -0
  35. package/dist/components/donutchart/index.js +178 -0
  36. package/dist/components/drawer/index.d.ts +12 -21
  37. package/dist/components/drawer/index.js +34 -36
  38. package/dist/components/empty/index.d.ts +3 -3
  39. package/dist/components/empty/index.js +4 -5
  40. package/dist/components/exception/index.d.ts +86 -0
  41. package/dist/components/exception/index.js +116 -0
  42. package/dist/components/fileupload/index.d.ts +4 -9
  43. package/dist/components/fileupload/index.js +26 -38
  44. package/dist/components/form/index.d.ts +0 -1
  45. package/dist/components/form/index.js +0 -1
  46. package/dist/components/horizontalbarchart/index.d.ts +120 -0
  47. package/dist/components/horizontalbarchart/index.js +193 -0
  48. package/dist/components/input/index.d.ts +22 -22
  49. package/dist/components/input/index.js +76 -105
  50. package/dist/components/linechart/index.d.ts +114 -0
  51. package/dist/components/linechart/index.js +139 -0
  52. package/dist/components/menu/index.d.ts +9 -11
  53. package/dist/components/menu/index.js +42 -39
  54. package/dist/components/metric/index.d.ts +0 -1
  55. package/dist/components/metric/index.js +0 -1
  56. package/dist/components/numberinput/index.d.ts +14 -21
  57. package/dist/components/numberinput/index.js +40 -53
  58. package/dist/components/otpinput/index.d.ts +14 -9
  59. package/dist/components/otpinput/index.js +25 -18
  60. package/dist/components/page/index.d.ts +0 -1
  61. package/dist/components/page/index.js +1 -3
  62. package/dist/components/passwordinput/index.d.ts +14 -11
  63. package/dist/components/passwordinput/index.js +36 -45
  64. package/dist/components/popover/index.d.ts +21 -19
  65. package/dist/components/popover/index.js +34 -15
  66. package/dist/components/radio/index.d.ts +13 -9
  67. package/dist/components/radio/index.js +69 -60
  68. package/dist/components/ratinginput/index.d.ts +13 -8
  69. package/dist/components/ratinginput/index.js +37 -17
  70. package/dist/components/select/index.d.ts +30 -30
  71. package/dist/components/select/index.js +80 -41
  72. package/dist/components/skeleton/index.d.ts +0 -1
  73. package/dist/components/skeleton/index.js +0 -1
  74. package/dist/components/slider/index.d.ts +14 -9
  75. package/dist/components/slider/index.js +64 -63
  76. package/dist/components/spinner/index.d.ts +1 -2
  77. package/dist/components/spinner/index.js +2 -3
  78. package/dist/components/splitter/index.d.ts +1 -2
  79. package/dist/components/splitter/index.js +5 -6
  80. package/dist/components/stepper/index.d.ts +8 -20
  81. package/dist/components/stepper/index.js +15 -16
  82. package/dist/components/switch/index.d.ts +12 -10
  83. package/dist/components/switch/index.js +46 -30
  84. package/dist/components/table/index.d.ts +3 -3
  85. package/dist/components/table/index.js +14 -13
  86. package/dist/components/tabs/index.d.ts +0 -1
  87. package/dist/components/tabs/index.js +1 -2
  88. package/dist/components/textarea/index.d.ts +14 -11
  89. package/dist/components/textarea/index.js +37 -46
  90. package/dist/components/textlink/index.d.ts +3 -1
  91. package/dist/components/textlink/index.js +4 -1
  92. package/dist/components/toast/index.d.ts +8 -14
  93. package/dist/components/toast/index.js +48 -48
  94. package/dist/components/toggle/index.d.ts +0 -1
  95. package/dist/components/toggle/index.js +17 -24
  96. package/dist/components/tooltip/index.d.ts +11 -13
  97. package/dist/components/tooltip/index.js +12 -9
  98. package/dist/components/tour/index.d.ts +154 -0
  99. package/dist/components/tour/index.js +280 -0
  100. package/dist/index.d.ts +7 -2
  101. package/dist/index.js +7 -1
  102. package/dist/types/Icon.d.ts +0 -1
  103. package/dist/types/Icon.js +0 -1
  104. package/dist/types/Style.d.ts +0 -1
  105. package/dist/types/Style.js +0 -1
  106. package/dist/types/Validation.d.ts +12 -0
  107. package/dist/types/Validation.js +1 -0
  108. package/dist/utils/ArkStateToDataAttributes.d.ts +0 -1
  109. package/dist/utils/ArkStateToDataAttributes.js +0 -1
  110. package/dist/utils/Validation.d.ts +14 -0
  111. package/dist/utils/Validation.js +23 -0
  112. package/dist/utils/asChild.d.ts +41 -0
  113. package/dist/utils/asChild.js +15 -0
  114. package/dist/utils/icons.d.ts +24 -0
  115. package/dist/utils/icons.js +160 -0
  116. package/dist/utils/useForwardClickToInput.d.ts +0 -1
  117. package/dist/utils/useForwardClickToInput.js +0 -1
  118. package/dist/utils/virtualization/useVirtualizedAutocomplete.d.ts +0 -1
  119. package/dist/utils/virtualization/useVirtualizedAutocomplete.js +0 -1
  120. package/dist/utils/virtualization/useVirtualizedCombobox.d.ts +0 -1
  121. package/dist/utils/virtualization/useVirtualizedCombobox.js +0 -1
  122. package/dist/utils/virtualization/useVirtualizedTable.d.ts +0 -1
  123. package/dist/utils/virtualization/useVirtualizedTable.js +0 -1
  124. package/package.json +14 -11
  125. package/src/presets/shopify-polaris/shopify-polaris-autocomplete.css +2 -2
  126. package/src/presets/shopify-polaris/shopify-polaris-barchart.css +64 -0
  127. package/src/presets/shopify-polaris/shopify-polaris-carousel.css +62 -0
  128. package/src/presets/shopify-polaris/shopify-polaris-checkbox.css +2 -2
  129. package/src/presets/shopify-polaris/shopify-polaris-combobox.css +2 -2
  130. package/src/presets/shopify-polaris/shopify-polaris-datepicker.css +4 -4
  131. package/src/presets/shopify-polaris/shopify-polaris-dialog.css +16 -0
  132. package/src/presets/shopify-polaris/shopify-polaris-donutchart.css +172 -0
  133. package/src/presets/shopify-polaris/shopify-polaris-drawer.css +16 -0
  134. package/src/presets/shopify-polaris/shopify-polaris-exception.css +40 -0
  135. package/src/presets/shopify-polaris/shopify-polaris-fileupload.css +1 -1
  136. package/src/presets/shopify-polaris/shopify-polaris-horizontalbarchart.css +60 -0
  137. package/src/presets/shopify-polaris/shopify-polaris-input.css +2 -2
  138. package/src/presets/shopify-polaris/shopify-polaris-linechart.css +68 -0
  139. package/src/presets/shopify-polaris/shopify-polaris-menu.css +16 -0
  140. package/src/presets/shopify-polaris/shopify-polaris-numberinput.css +2 -2
  141. package/src/presets/shopify-polaris/shopify-polaris-otpinput.css +2 -2
  142. package/src/presets/shopify-polaris/shopify-polaris-passwordinput.css +2 -2
  143. package/src/presets/shopify-polaris/shopify-polaris-popover.css +29 -0
  144. package/src/presets/shopify-polaris/shopify-polaris-radio.css +2 -2
  145. package/src/presets/shopify-polaris/shopify-polaris-ratinginput.css +2 -2
  146. package/src/presets/shopify-polaris/shopify-polaris-select.css +2 -2
  147. package/src/presets/shopify-polaris/shopify-polaris-slider.css +2 -2
  148. package/src/presets/shopify-polaris/shopify-polaris-stepper.css +16 -0
  149. package/src/presets/shopify-polaris/shopify-polaris-switch.css +2 -2
  150. package/src/presets/shopify-polaris/shopify-polaris-textarea.css +2 -2
  151. package/src/presets/shopify-polaris/shopify-polaris-tooltip.css +16 -0
  152. package/src/presets/shopify-polaris/shopify-polaris.css +6 -0
  153. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-autocomplete.css +2 -2
  154. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-barchart.css +64 -0
  155. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-carousel.css +55 -0
  156. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-checkbox.css +2 -2
  157. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-combobox.css +2 -2
  158. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-datepicker.css +2 -2
  159. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-dialog.css +9 -0
  160. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-donutchart.css +172 -0
  161. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-drawer.css +9 -0
  162. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-exception.css +40 -0
  163. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-fileupload.css +1 -1
  164. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-horizontalbarchart.css +60 -0
  165. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-input.css +2 -2
  166. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-linechart.css +68 -0
  167. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-menu.css +9 -0
  168. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-numberinput.css +2 -2
  169. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-otpinput.css +2 -2
  170. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-passwordinput.css +2 -2
  171. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-popover.css +22 -0
  172. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-radio.css +2 -2
  173. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-ratinginput.css +2 -2
  174. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-slider.css +2 -2
  175. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-stepper.css +9 -0
  176. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-switch.css +2 -2
  177. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-textarea.css +2 -2
  178. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-tooltip.css +9 -0
  179. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy.css +6 -0
  180. package/dist/components/accordion/index.d.ts.map +0 -1
  181. package/dist/components/accordion/index.js.map +0 -1
  182. package/dist/components/autocomplete/index.d.ts.map +0 -1
  183. package/dist/components/autocomplete/index.js.map +0 -1
  184. package/dist/components/avatar/index.d.ts.map +0 -1
  185. package/dist/components/avatar/index.js.map +0 -1
  186. package/dist/components/badge/index.d.ts.map +0 -1
  187. package/dist/components/badge/index.js.map +0 -1
  188. package/dist/components/banner/index.d.ts.map +0 -1
  189. package/dist/components/banner/index.js.map +0 -1
  190. package/dist/components/breadcrumb/index.d.ts.map +0 -1
  191. package/dist/components/breadcrumb/index.js.map +0 -1
  192. package/dist/components/button/index.d.ts.map +0 -1
  193. package/dist/components/button/index.js.map +0 -1
  194. package/dist/components/card/index.d.ts.map +0 -1
  195. package/dist/components/card/index.js.map +0 -1
  196. package/dist/components/checkbox/index.d.ts.map +0 -1
  197. package/dist/components/checkbox/index.js.map +0 -1
  198. package/dist/components/chip/index.d.ts.map +0 -1
  199. package/dist/components/chip/index.js.map +0 -1
  200. package/dist/components/combobox/index.d.ts.map +0 -1
  201. package/dist/components/combobox/index.js.map +0 -1
  202. package/dist/components/datepicker/index.d.ts.map +0 -1
  203. package/dist/components/datepicker/index.js.map +0 -1
  204. package/dist/components/dialog/index.d.ts.map +0 -1
  205. package/dist/components/dialog/index.js.map +0 -1
  206. package/dist/components/divider/index.d.ts.map +0 -1
  207. package/dist/components/divider/index.js.map +0 -1
  208. package/dist/components/drawer/index.d.ts.map +0 -1
  209. package/dist/components/drawer/index.js.map +0 -1
  210. package/dist/components/empty/index.d.ts.map +0 -1
  211. package/dist/components/empty/index.js.map +0 -1
  212. package/dist/components/fileupload/index.d.ts.map +0 -1
  213. package/dist/components/fileupload/index.js.map +0 -1
  214. package/dist/components/form/index.d.ts.map +0 -1
  215. package/dist/components/form/index.js.map +0 -1
  216. package/dist/components/input/index.d.ts.map +0 -1
  217. package/dist/components/input/index.js.map +0 -1
  218. package/dist/components/menu/index.d.ts.map +0 -1
  219. package/dist/components/menu/index.js.map +0 -1
  220. package/dist/components/metric/index.d.ts.map +0 -1
  221. package/dist/components/metric/index.js.map +0 -1
  222. package/dist/components/numberinput/index.d.ts.map +0 -1
  223. package/dist/components/numberinput/index.js.map +0 -1
  224. package/dist/components/otpinput/index.d.ts.map +0 -1
  225. package/dist/components/otpinput/index.js.map +0 -1
  226. package/dist/components/page/index.d.ts.map +0 -1
  227. package/dist/components/page/index.js.map +0 -1
  228. package/dist/components/passwordinput/index.d.ts.map +0 -1
  229. package/dist/components/passwordinput/index.js.map +0 -1
  230. package/dist/components/popover/index.d.ts.map +0 -1
  231. package/dist/components/popover/index.js.map +0 -1
  232. package/dist/components/radio/index.d.ts.map +0 -1
  233. package/dist/components/radio/index.js.map +0 -1
  234. package/dist/components/ratinginput/index.d.ts.map +0 -1
  235. package/dist/components/ratinginput/index.js.map +0 -1
  236. package/dist/components/select/index.d.ts.map +0 -1
  237. package/dist/components/select/index.js.map +0 -1
  238. package/dist/components/skeleton/index.d.ts.map +0 -1
  239. package/dist/components/skeleton/index.js.map +0 -1
  240. package/dist/components/slider/index.d.ts.map +0 -1
  241. package/dist/components/slider/index.js.map +0 -1
  242. package/dist/components/spinner/index.d.ts.map +0 -1
  243. package/dist/components/spinner/index.js.map +0 -1
  244. package/dist/components/splitter/index.d.ts.map +0 -1
  245. package/dist/components/splitter/index.js.map +0 -1
  246. package/dist/components/stepper/index.d.ts.map +0 -1
  247. package/dist/components/stepper/index.js.map +0 -1
  248. package/dist/components/switch/index.d.ts.map +0 -1
  249. package/dist/components/switch/index.js.map +0 -1
  250. package/dist/components/table/index.d.ts.map +0 -1
  251. package/dist/components/table/index.js.map +0 -1
  252. package/dist/components/tabs/index.d.ts.map +0 -1
  253. package/dist/components/tabs/index.js.map +0 -1
  254. package/dist/components/textarea/index.d.ts.map +0 -1
  255. package/dist/components/textarea/index.js.map +0 -1
  256. package/dist/components/textlink/index.d.ts.map +0 -1
  257. package/dist/components/textlink/index.js.map +0 -1
  258. package/dist/components/toast/index.d.ts.map +0 -1
  259. package/dist/components/toast/index.js.map +0 -1
  260. package/dist/components/toggle/index.d.ts.map +0 -1
  261. package/dist/components/toggle/index.js.map +0 -1
  262. package/dist/components/tooltip/index.d.ts.map +0 -1
  263. package/dist/components/tooltip/index.js.map +0 -1
  264. package/dist/index.d.ts.map +0 -1
  265. package/dist/index.js.map +0 -1
  266. package/dist/types/Icon.d.ts.map +0 -1
  267. package/dist/types/Icon.js.map +0 -1
  268. package/dist/types/Style.d.ts.map +0 -1
  269. package/dist/types/Style.js.map +0 -1
  270. package/dist/types/Tone.d.ts +0 -4
  271. package/dist/types/Tone.d.ts.map +0 -1
  272. package/dist/types/Tone.js +0 -2
  273. package/dist/types/Tone.js.map +0 -1
  274. package/dist/utils/ArkStateToDataAttributes.d.ts.map +0 -1
  275. package/dist/utils/ArkStateToDataAttributes.js.map +0 -1
  276. package/dist/utils/Tone.d.ts +0 -3
  277. package/dist/utils/Tone.d.ts.map +0 -1
  278. package/dist/utils/Tone.js +0 -7
  279. package/dist/utils/Tone.js.map +0 -1
  280. package/dist/utils/useForwardClickToInput.d.ts.map +0 -1
  281. package/dist/utils/useForwardClickToInput.js.map +0 -1
  282. package/dist/utils/virtualization/useVirtualizedAutocomplete.d.ts.map +0 -1
  283. package/dist/utils/virtualization/useVirtualizedAutocomplete.js.map +0 -1
  284. package/dist/utils/virtualization/useVirtualizedCombobox.d.ts.map +0 -1
  285. package/dist/utils/virtualization/useVirtualizedCombobox.js.map +0 -1
  286. package/dist/utils/virtualization/useVirtualizedTable.d.ts.map +0 -1
  287. package/dist/utils/virtualization/useVirtualizedTable.js.map +0 -1
@@ -0,0 +1,299 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { asChildStyleAttributes } from "../../utils/asChild.js";
3
+ import { ChevronLeft, ChevronRight } from "../../utils/icons.js";
4
+ import { useDirection } from '@base-ui/react/direction-provider';
5
+ import { mergeProps } from '@base-ui/react/merge-props';
6
+ import { useRender } from '@base-ui/react/use-render';
7
+ import useEmblaCarousel from 'embla-carousel-react';
8
+ import Autoplay from 'embla-carousel-autoplay';
9
+ import { Fragment, cloneElement, createContext, forwardRef, useContext, useEffect, useState } from 'react';
10
+ import { twMerge } from 'tailwind-merge';
11
+ const CarouselContext = /* @__PURE__ */ createContext(null);
12
+ /**
13
+ * A row of slides users swipe through, built on Embla Carousel. Root holds the carousel's state and renders no element;
14
+ * SlidesList is the visible window and Slide is one item, written by hand so each can hold different content.
15
+ * Previous/Next and Indicator buttons work on their own: no click handlers needed.
16
+ * Every part carries data-orientation, data-disabled, and data-playing (while autoplay runs), so any part can be styled by the carousel's state.
17
+ *
18
+ * @example Complete composition
19
+ * import { Carousel } from '@central-ui/react'
20
+ *
21
+ * function Example() {
22
+ * return (
23
+ * <Carousel.Root loop>
24
+ * <Carousel.SlidesList>
25
+ * {products.map((product) => (
26
+ * <Carousel.Slide key={product.id}>
27
+ * <img src={product.image} alt={product.title} />
28
+ * </Carousel.Slide>
29
+ * ))}
30
+ * </Carousel.SlidesList>
31
+ * <Carousel.PreviousButton aria-label="Previous slide">
32
+ * <Carousel.PreviousButtonIcon />
33
+ * </Carousel.PreviousButton>
34
+ * <Carousel.NextButton aria-label="Next slide">
35
+ * <Carousel.NextButtonIcon />
36
+ * </Carousel.NextButton>
37
+ * <Carousel.IndicatorList>
38
+ * {(index) => <Carousel.IndicatorButton index={index} />}
39
+ * </Carousel.IndicatorList>
40
+ * </Carousel.Root>
41
+ * )
42
+ * }
43
+ *
44
+ * @example Several slides at once
45
+ * // Size slides with Tailwind (responsive classes work); gap is subtracted from that size.
46
+ * ;<Carousel.Root gap={12} align="start" slidesToScroll="auto">
47
+ * <Carousel.SlidesList>
48
+ * <Carousel.Slide className="basis-full md:basis-1/3">…</Carousel.Slide>
49
+ * </Carousel.SlidesList>
50
+ * </Carousel.Root>
51
+ *
52
+ * @example Autoplay, pausing while hovered and resuming on mouse leave
53
+ * ;<Carousel.Root loop autoplay={{ delay: 5000, stopOnMouseEnter: true, stopOnInteraction: false }}>
54
+ *
55
+ * @example Controlled position
56
+ * const [index, setIndex] = useState(0)
57
+ * ;<Carousel.Root index={index} onIndexChange={setIndex}>
58
+ */
59
+ export function Root({ orientation = 'horizontal', loop = false, align = 'center', slidesToScroll = 1, dragFree = false, gap = 0, disabled = false, autoplay = false, index, defaultIndex = 0, onIndexChange, children, }) {
60
+ const direction = useDirection();
61
+ // Embla reads the start only once; keeping it fixed stops a controlled index from restarting the carousel
62
+ const [startIndex] = useState(index ?? defaultIndex);
63
+ const [emblaRef, api] = useEmblaCarousel({
64
+ axis: orientation === 'vertical' ? 'y' : 'x',
65
+ direction,
66
+ loop,
67
+ align,
68
+ slidesToScroll,
69
+ dragFree,
70
+ startIndex,
71
+ active: !disabled,
72
+ }, autoplay ? [Autoplay(autoplay === true ? {} : autoplay)] : []);
73
+ const [snapshot, setSnapshot] = useState({
74
+ selectedIndex: startIndex,
75
+ snapCount: 0,
76
+ canScrollPrevious: false,
77
+ canScrollNext: false,
78
+ playing: false,
79
+ });
80
+ //1. Mirroring Embla's state, so the parts re-render when it changes
81
+ useEffect(() => {
82
+ if (!api)
83
+ return;
84
+ function sync(carousel, event) {
85
+ setSnapshot({
86
+ selectedIndex: carousel.selectedScrollSnap(),
87
+ snapCount: carousel.scrollSnapList().length,
88
+ canScrollPrevious: carousel.canScrollPrev(),
89
+ canScrollNext: carousel.canScrollNext(),
90
+ playing: readPlaying(carousel, event),
91
+ });
92
+ }
93
+ // The plugin fires play/stop before updating isPlaying(), so those events decide it themselves
94
+ function readPlaying(carousel, event) {
95
+ if (event === 'autoplay:play')
96
+ return true;
97
+ if (event === 'autoplay:stop')
98
+ return false;
99
+ // Embla starts no plugins while disabled, so plugins() is undefined then
100
+ return carousel.plugins()?.autoplay?.isPlaying() ?? false;
101
+ }
102
+ sync(api);
103
+ api.on('select', sync).on('reInit', sync).on('autoplay:play', sync).on('autoplay:stop', sync);
104
+ return () => {
105
+ api.off('select', sync).off('reInit', sync).off('autoplay:play', sync).off('autoplay:stop', sync);
106
+ };
107
+ }, [api]);
108
+ //2. Reporting every newly selected slide
109
+ useEffect(() => {
110
+ if (!api || !onIndexChange)
111
+ return;
112
+ function handleSelect(carousel) {
113
+ onIndexChange?.(carousel.selectedScrollSnap());
114
+ }
115
+ api.on('select', handleSelect);
116
+ return () => {
117
+ api.off('select', handleSelect);
118
+ };
119
+ }, [api, onIndexChange]);
120
+ //3. Moving to a controlled index set from outside
121
+ useEffect(() => {
122
+ if (!api || index === undefined || index === api.selectedScrollSnap())
123
+ return;
124
+ api.scrollTo(index);
125
+ }, [api, index]);
126
+ const context = { emblaRef, api, orientation, disabled, gap, ...snapshot };
127
+ return _jsx(CarouselContext.Provider, { value: context, children: children });
128
+ }
129
+ /** The visible window the slides move inside, announced to screen readers as the carousel. Style it freely (background, border, radius); a vertical carousel needs a height here. Put only Slides inside. */
130
+ export const SlidesList = /* @__PURE__ */ forwardRef(function SlidesList({ disableStyle, style, children, ...props }, ref) {
131
+ const context = useCarouselContext('SlidesList');
132
+ const vertical = context.orientation === 'vertical';
133
+ // The track Embla moves; its negative margin cancels the first slide's gap
134
+ const track = (_jsx("div", { style: {
135
+ display: 'flex',
136
+ flexDirection: vertical ? 'column' : 'row',
137
+ height: vertical ? '100%' : undefined,
138
+ touchAction: vertical ? 'pan-x pinch-zoom' : 'pan-y pinch-zoom',
139
+ [vertical ? 'marginBlockStart' : 'marginInlineStart']: negativeLength(context.gap),
140
+ }, children: children }));
141
+ return useRender({
142
+ ref: [ref, context.emblaRef],
143
+ state: partState(context),
144
+ props: {
145
+ role: 'region',
146
+ 'aria-roledescription': 'carousel',
147
+ ...props,
148
+ style: { overflow: 'hidden', ...style },
149
+ 'data-component': 'carousel-slideslist',
150
+ 'data-style-disabled': disableStyle ? '' : undefined,
151
+ children: track,
152
+ },
153
+ });
154
+ });
155
+ /**
156
+ * One slide; each can hold different content. Size it with a className, like `basis-1/3`; it fills SlidesList by default.
157
+ * Its padding makes the gap between slides, so put backgrounds, borders and radius on its content, not on the Slide itself.
158
+ */
159
+ export const Slide = /* @__PURE__ */ forwardRef(function Slide({ disableStyle, style, ...props }, ref) {
160
+ const context = useCarouselContext('Slide');
161
+ const vertical = context.orientation === 'vertical';
162
+ return useRender({
163
+ ref,
164
+ state: partState(context),
165
+ props: {
166
+ role: 'group',
167
+ 'aria-roledescription': 'slide',
168
+ ...props,
169
+ style: {
170
+ flexShrink: 0,
171
+ minWidth: 0,
172
+ minHeight: 0,
173
+ boxSizing: 'border-box',
174
+ [vertical ? 'paddingBlockStart' : 'paddingInlineStart']: context.gap,
175
+ ...style,
176
+ },
177
+ 'data-component': 'carousel-slide',
178
+ 'data-style-disabled': disableStyle ? '' : undefined,
179
+ },
180
+ });
181
+ });
182
+ /** Moves to the previous slide; no click handler needed. Disabled when there's no slide before (never with loop). Supply its content, normally PreviousButtonIcon, and an accessible label. Pass asChild to give this behavior to your own button instead. */
183
+ export const PreviousButton = /* @__PURE__ */ forwardRef(function PreviousButton(props, ref) {
184
+ const context = useCarouselContext('PreviousButton');
185
+ return useActionButton(props, ref, context, {
186
+ component: 'carousel-previousbutton',
187
+ disabled: context.disabled || !context.canScrollPrevious,
188
+ onClick: () => context.api?.scrollPrev(),
189
+ });
190
+ });
191
+ /** Moves to the next slide; no click handler needed. Disabled when there's no slide after (never with loop). Supply its content, normally NextButtonIcon, and an accessible label. Pass asChild to give this behavior to your own button instead. */
192
+ export const NextButton = /* @__PURE__ */ forwardRef(function NextButton(props, ref) {
193
+ const context = useCarouselContext('NextButton');
194
+ return useActionButton(props, ref, context, {
195
+ component: 'carousel-nextbutton',
196
+ disabled: context.disabled || !context.canScrollNext,
197
+ onClick: () => context.api?.scrollNext(),
198
+ });
199
+ });
200
+ /**
201
+ * Renders one IndicatorButton per position through its children function, which receives that position's index.
202
+ * The count comes from the carousel itself: with several slides per view, it counts positions, not slides.
203
+ *
204
+ * @example Dots
205
+ * ;<Carousel.IndicatorList>
206
+ * {(index) => <Carousel.IndicatorButton index={index} />}
207
+ * </Carousel.IndicatorList>
208
+ */
209
+ export const IndicatorList = /* @__PURE__ */ forwardRef(function IndicatorList({ disableStyle, children, ...props }, ref) {
210
+ const context = useCarouselContext('IndicatorList');
211
+ return useRender({
212
+ ref,
213
+ state: partState(context),
214
+ props: {
215
+ ...props,
216
+ 'data-component': 'carousel-indicatorlist',
217
+ 'data-style-disabled': disableStyle ? '' : undefined,
218
+ children: Array.from({ length: context.snapCount }, (_, index) => _jsx(Fragment, { children: children(index) }, index)),
219
+ },
220
+ });
221
+ });
222
+ /**
223
+ * Moves to its position when clicked, and carries data-selected while that position is shown. Shows as a dot when empty.
224
+ * Pass asChild to give this behavior to your own button instead.
225
+ *
226
+ * @example Thumbnails instead of dots
227
+ * ;<Carousel.IndicatorList>
228
+ * {(index) => (
229
+ * <Carousel.IndicatorButton index={index}>
230
+ * <img src={images[index].thumbnail} alt="" />
231
+ * </Carousel.IndicatorButton>
232
+ * )}
233
+ * </Carousel.IndicatorList>
234
+ */
235
+ export const IndicatorButton = /* @__PURE__ */ forwardRef(function IndicatorButton({ index, ...props }, ref) {
236
+ const context = useCarouselContext('IndicatorButton');
237
+ const selected = context.selectedIndex === index;
238
+ return useActionButton(props, ref, context, {
239
+ component: 'carousel-indicatorbutton',
240
+ disabled: context.disabled,
241
+ selected,
242
+ attributes: { 'aria-label': `Go to slide ${index + 1}`, 'aria-current': selected ? 'true' : undefined },
243
+ onClick: () => context.api?.scrollTo(index),
244
+ });
245
+ });
246
+ /** Built-in decorative previous icon. Place inside PreviousButton. Omit children for the supplied default icon; pass an icon only to replace it. Defaults to strokeWidth 1.5. */
247
+ export const PreviousButtonIcon = /* @__PURE__ */ forwardRef(function PreviousButtonIcon(props, ref) {
248
+ return _jsx(BuiltInIcon, { ...props, ref: ref, icon: ChevronLeft, component: "carousel-previousbuttonicon" });
249
+ });
250
+ /** Built-in decorative next icon. Place inside NextButton. Omit children for the supplied default icon; pass an icon only to replace it. Defaults to strokeWidth 1.5. */
251
+ export const NextButtonIcon = /* @__PURE__ */ forwardRef(function NextButtonIcon(props, ref) {
252
+ return _jsx(BuiltInIcon, { ...props, ref: ref, icon: ChevronRight, component: "carousel-nextbuttonicon" });
253
+ });
254
+ // The shared body of the built-in decorative icons above, which only differ by their icon and component name
255
+ const BuiltInIcon = /* @__PURE__ */ forwardRef(function BuiltInIcon({ disableStyle, className, strokeWidth, icon: Icon, component, children, ...props }, ref) {
256
+ const attributes = partAttributes(useCarouselContext('Icon'));
257
+ return cloneElement(children ?? _jsx(Icon, {}), {
258
+ ...attributes,
259
+ 'aria-hidden': true,
260
+ ...props,
261
+ ref,
262
+ strokeWidth: strokeWidth ?? children?.props.strokeWidth ?? 1.5,
263
+ 'data-component': component,
264
+ 'data-style-disabled': disableStyle ? '' : undefined,
265
+ className: twMerge(children?.props.className, className),
266
+ });
267
+ });
268
+ // The shared body of the action buttons: the part's own styled button, or the consumer's child with asChild
269
+ function useActionButton({ asChild, disableStyle, children, ...props }, ref, context, internal) {
270
+ return useRender({
271
+ render: asChild ? children : undefined,
272
+ defaultTagName: 'button',
273
+ ref,
274
+ state: { ...partState(context), disabled: internal.disabled, selected: internal.selected ?? false },
275
+ props: mergeProps({ type: 'button', disabled: internal.disabled, onClick: internal.onClick, ...internal.attributes }, props, asChild ? {} : { children, ...asChildStyleAttributes({ asChild, component: internal.component, disableStyle }) }),
276
+ });
277
+ }
278
+ // The carousel's state every part exposes as data attributes
279
+ function partState(context) {
280
+ return { orientation: context.orientation, disabled: context.disabled, playing: context.playing };
281
+ }
282
+ // The same data attributes, for the icons, which render without useRender
283
+ function partAttributes(context) {
284
+ return {
285
+ 'data-orientation': context.orientation,
286
+ 'data-disabled': context.disabled ? '' : undefined,
287
+ 'data-playing': context.playing ? '' : undefined,
288
+ };
289
+ }
290
+ // Turning the gap into the track's offset, whether it's a number of pixels or a CSS length
291
+ function negativeLength(length) {
292
+ return typeof length === 'number' ? -length : `calc(${length} * -1)`;
293
+ }
294
+ function useCarouselContext(part) {
295
+ const context = useContext(CarouselContext);
296
+ if (!context)
297
+ throw new Error(`Carousel.${part} must be placed inside Carousel.Root.`);
298
+ return context;
299
+ }
@@ -1,11 +1,11 @@
1
1
  import type { StyleProps } from '../../types/Style.ts';
2
2
  import { Checkbox as BaseCheckbox } from '@base-ui/react/checkbox';
3
- import type { ReactNode } from 'react';
3
+ import type { ComponentProps, ReactNode } from 'react';
4
+ import type { ValidationProps } from '../../types/Validation.ts';
5
+ import type { ValidationMessageChildren } from '../../utils/Validation.ts';
4
6
  type CoreKeys = 'checked' | 'defaultChecked' | 'onCheckedChange' | 'indeterminate' | 'disabled' | 'readOnly' | 'required' | 'name' | 'form' | 'value' | 'uncheckedValue' | 'id' | 'inputRef' | 'parent';
5
- export type RootProps = Pick<BaseCheckbox.Root.Props, CoreKeys> & {
7
+ export type RootProps = Pick<BaseCheckbox.Root.Props, CoreKeys> & ValidationProps & {
6
8
  children: ReactNode;
7
- /** Choose the visual tone. This does not validate data or show/hide feedback messages. */
8
- tone?: 'neutral' | 'valid' | 'invalid';
9
9
  };
10
10
  /**
11
11
  * Keep Button and Indicator inside the same Root as Label. Indicator tracks checked and indeterminate state automatically; no conditional checkmark needed. Use CheckboxGroup only when coordinating several checkbox roots.
@@ -42,7 +42,7 @@ export type RootProps = Pick<BaseCheckbox.Root.Props, CoreKeys> & {
42
42
  * )
43
43
  * }
44
44
  */
45
- export declare function Root({ children, id, tone, ...coreProps }: RootProps): import("react").JSX.Element;
45
+ export declare function Root({ children, id, validation, ...coreProps }: RootProps): import("react").JSX.Element;
46
46
  /** Optional: controls multiple checkboxes as a native array of checked values. Put individual Roots inside and give each child a value. For a select-all checkbox, use parent on its Root and provide allValues on this controlled group; Base UI derives checked and indeterminate automatically. */
47
47
  export declare const CheckboxGroup: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").CheckboxGroupProps, "className"> & {
48
48
  className?: string;
@@ -52,15 +52,17 @@ export declare const Button: import("react").ForwardRefExoticComponent<Omit<Omit
52
52
  className?: string;
53
53
  } & StyleProps, "ref"> & import("react").RefAttributes<HTMLElement>>;
54
54
  /** Tracks the surrounding item state automatically. Keep it mounted; do not add your own visibility condition. Use the supplied default visual unless customization is needed. */
55
- export declare const Indicator: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").CheckboxIndicatorProps, "children" | "className" | "render"> & {
55
+ export declare const Indicator: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").CheckboxIndicatorProps, "className" | "children" | "render"> & {
56
56
  className?: string;
57
57
  } & StyleProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
58
58
  /** Labels the associated control automatically. Supply the visible text; do not wire a second label association. */
59
59
  export declare const Label: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, "htmlFor"> & StyleProps, "ref"> & import("react").RefAttributes<HTMLLabelElement>>;
60
60
  export declare const Description: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLSpanElement> & import("react").HTMLAttributes<HTMLSpanElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
61
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
62
- export declare const Error: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLSpanElement> & import("react").HTMLAttributes<HTMLSpanElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
63
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
64
- export declare const Success: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLSpanElement> & import("react").HTMLAttributes<HTMLSpanElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
61
+ type MessageProps = Omit<ComponentProps<'span'>, 'children'> & StyleProps & {
62
+ children?: ValidationMessageChildren;
63
+ };
64
+ /** Shows itself only while Root's validation is `'error'`: with no children it shows the message from `['error', message]`, a function children formats that message, and other children replace it. */
65
+ export declare const Error: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
66
+ /** Shows itself only while Root's validation is `'success'`: with no children it shows the message from `['success', message]`, a function children formats that message, and other children replace it. */
67
+ export declare const Success: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
65
68
  export {};
66
- //# sourceMappingURL=index.d.ts.map
@@ -2,8 +2,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Checkbox as BaseCheckbox } from '@base-ui/react/checkbox';
3
3
  import { CheckboxGroup as BaseCheckboxGroup } from '@base-ui/react/checkbox-group';
4
4
  import { createContext, forwardRef, useContext, useEffect, useId, useState, } from 'react';
5
- import { Check, Minus } from 'lucide-react';
6
- import { ToneProvider, useToneContext } from "../../utils/Tone.js";
5
+ import { Check, Minus } from "../../utils/icons.js";
6
+ import { readValidation, validationAttributes, validationMessageContent } from "../../utils/Validation.js";
7
7
  /**
8
8
  * Keep Button and Indicator inside the same Root as Label. Indicator tracks checked and indeterminate state automatically; no conditional checkmark needed. Use CheckboxGroup only when coordinating several checkbox roots.
9
9
  *
@@ -39,9 +39,10 @@ import { ToneProvider, useToneContext } from "../../utils/Tone.js";
39
39
  * )
40
40
  * }
41
41
  */
42
- export function Root({ children, id, tone = 'neutral', ...coreProps }) {
43
- const generatedId = useId();
42
+ export function Root({ children, id, validation, ...coreProps }) {
43
+ //1. Holding the ids of Description, Error and Success, so Button announces them to screen readers through aria-describedby
44
44
  const [messageIds, setMessageIds] = useState([]);
45
+ //2. Mirroring Base UI's live state, so parts outside Button (Label, Description…) can carry its data attributes
45
46
  const [state, setState] = useState({
46
47
  checked: coreProps.checked ?? coreProps.defaultChecked ?? false,
47
48
  indeterminate: coreProps.indeterminate ?? false,
@@ -49,13 +50,16 @@ export function Root({ children, id, tone = 'neutral', ...coreProps }) {
49
50
  readOnly: coreProps.readOnly ?? false,
50
51
  required: coreProps.required ?? false,
51
52
  });
53
+ //3. Sharing everything with the parts
54
+ const generatedId = useId();
52
55
  return (_jsx(CheckboxContext.Provider, { value: {
53
56
  coreProps: { ...coreProps, id: id ?? generatedId },
54
57
  state,
55
58
  setState,
56
59
  messageIds,
57
60
  setMessageIds,
58
- }, children: _jsx(ToneProvider, { value: tone, children: children }) }));
61
+ validation: readValidation(validation),
62
+ }, children: children }));
59
63
  }
60
64
  /** Optional: controls multiple checkboxes as a native array of checked values. Put individual Roots inside and give each child a value. For a select-all checkbox, use parent on its Root and provide allValues on this controlled group; Base UI derives checked and indeterminate automatically. */
61
65
  export const CheckboxGroup = /* @__PURE__ */ forwardRef(function CheckboxGroup({ disableStyle, className, ...props }, ref) {
@@ -66,14 +70,19 @@ export const Container = /* @__PURE__ */ forwardRef(function Container({ disable
66
70
  });
67
71
  export const Button = /* @__PURE__ */ forwardRef(function Button({ disableStyle, className, ...props }, ref) {
68
72
  const context = useCheckboxContext();
69
- const tone = useToneContext();
70
- return (_jsx(BaseCheckbox.Root, { ...props, ...context.coreProps, ref: ref, "data-tone": tone, "aria-invalid": tone === 'invalid' || props['aria-invalid'] || undefined, "aria-describedby": [props['aria-describedby'], ...context.messageIds]
73
+ return (_jsx(BaseCheckbox.Root, { ...props, ...context.coreProps, ref: ref, ...validationAttributes(context.validation), "aria-invalid": context.validation.state === 'error' || props['aria-invalid'] || undefined, "aria-describedby": [props['aria-describedby'], ...context.messageIds]
71
74
  .filter(Boolean)
72
75
  .join(' ') || undefined, "data-component": "checkbox-button", "data-style-disabled": disableStyle ? '' : undefined, className: className, render: (buttonProps, state) => (_jsx(CheckboxButtonSurface, { ...buttonProps, state: state })) }));
73
76
  });
74
77
  /** Tracks the surrounding item state automatically. Keep it mounted; do not add your own visibility condition. Use the supplied default visual unless customization is needed. */
75
78
  export const Indicator = /* @__PURE__ */ forwardRef(function Indicator({ disableStyle, className, ...props }, ref) {
76
- return (_jsx(BaseCheckbox.Indicator, { ...props, ref: ref, "data-component": "checkbox-indicator", "data-style-disabled": disableStyle ? '' : undefined, className: className, render: (indicatorProps, state) => (_jsx("span", { ...indicatorProps, children: state.indeterminate ? (_jsx(Minus, { "aria-hidden": true, strokeWidth: 3.5, "data-component": "checkbox-indicator-1" })) : state.checked ? (_jsx(Check, { "aria-hidden": true, strokeWidth: 3.5, "data-component": "checkbox-indicator-2" })) : null })) }));
79
+ return (_jsx(BaseCheckbox.Indicator, { ...props, ref: ref, "data-component": "checkbox-indicator", "data-style-disabled": disableStyle ? '' : undefined, className: className, render: (indicatorProps, state) => (_jsx("span", { ...indicatorProps, children: (() => {
80
+ if (state.indeterminate)
81
+ return _jsx(Minus, { "aria-hidden": true, strokeWidth: 3.5, "data-component": "checkbox-indicator-1" });
82
+ if (state.checked)
83
+ return _jsx(Check, { "aria-hidden": true, strokeWidth: 3.5, "data-component": "checkbox-indicator-2" });
84
+ return null;
85
+ })() })) }));
77
86
  });
78
87
  /** Labels the associated control automatically. Supply the visible text; do not wire a second label association. */
79
88
  export const Label = /* @__PURE__ */ forwardRef(function Label({ disableStyle, className, ...props }, ref) {
@@ -84,15 +93,26 @@ export const Description = /* @__PURE__ */ forwardRef(function Description({ dis
84
93
  const messageId = useMessageId(id);
85
94
  return (_jsx("span", { ...usePartAttributes(), ...props, ref: ref, id: messageId, "data-component": "checkbox-description", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
86
95
  });
87
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
88
- export const Error = /* @__PURE__ */ forwardRef(function Error({ disableStyle, className, id, ...props }, ref) {
89
- const messageId = useMessageId(id);
90
- return (_jsx("span", { role: "alert", "aria-atomic": "true", ...usePartAttributes(), ...props, ref: ref, id: messageId, "data-component": "checkbox-error", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
96
+ /** Shows itself only while Root's validation is `'error'`: with no children it shows the message from `['error', message]`, a function children formats that message, and other children replace it. */
97
+ export const Error = /* @__PURE__ */ forwardRef(function Error({ children, ...props }, ref) {
98
+ const context = useCheckboxContext();
99
+ const content = validationMessageContent(context.validation, 'error', children);
100
+ if (content === undefined)
101
+ return null;
102
+ return _jsx(Message, { ...props, ref: ref, role: "alert", component: "checkbox-error", children: content });
91
103
  });
92
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
93
- export const Success = /* @__PURE__ */ forwardRef(function Success({ disableStyle, className, id, ...props }, ref) {
104
+ /** Shows itself only while Root's validation is `'success'`: with no children it shows the message from `['success', message]`, a function children formats that message, and other children replace it. */
105
+ export const Success = /* @__PURE__ */ forwardRef(function Success({ children, ...props }, ref) {
106
+ const context = useCheckboxContext();
107
+ const content = validationMessageContent(context.validation, 'success', children);
108
+ if (content === undefined)
109
+ return null;
110
+ return _jsx(Message, { ...props, ref: ref, role: "status", component: "checkbox-success", children: content });
111
+ });
112
+ // The shared body of Error and Success, mounted only while they show, so only visible messages describe the checkbox
113
+ const Message = /* @__PURE__ */ forwardRef(function Message({ disableStyle, className, id, component, ...props }, ref) {
94
114
  const messageId = useMessageId(id);
95
- return (_jsx("span", { role: "status", "aria-atomic": "true", ...usePartAttributes(), ...props, ref: ref, id: messageId, "data-component": "checkbox-success", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
115
+ return _jsx("span", { "aria-atomic": "true", ...usePartAttributes(), ...props, ref: ref, id: messageId, "data-component": component, "data-style-disabled": disableStyle ? '' : undefined, className: className });
96
116
  });
97
117
  const CheckboxContext = /* @__PURE__ */ createContext(null);
98
118
  function useCheckboxContext() {
@@ -102,21 +122,21 @@ function useCheckboxContext() {
102
122
  return context;
103
123
  }
104
124
  function usePartAttributes() {
105
- const { state } = useCheckboxContext();
106
- const tone = useToneContext();
125
+ const context = useCheckboxContext();
107
126
  return {
108
- 'data-checked': state.checked ? '' : undefined,
109
- 'data-indeterminate': state.indeterminate ? '' : undefined,
110
- 'data-disabled': state.disabled ? '' : undefined,
111
- 'data-readonly': state.readOnly ? '' : undefined,
112
- 'data-required': state.required ? '' : undefined,
113
- 'data-tone': tone,
127
+ 'data-checked': context.state.checked ? '' : undefined,
128
+ 'data-indeterminate': context.state.indeterminate ? '' : undefined,
129
+ 'data-disabled': context.state.disabled ? '' : undefined,
130
+ 'data-readonly': context.state.readOnly ? '' : undefined,
131
+ 'data-required': context.state.required ? '' : undefined,
132
+ ...validationAttributes(context.validation),
114
133
  };
115
134
  }
135
+ // Rendered by Base UI as the checkbox element, it reports Base UI's live state back to Root's mirror
116
136
  const CheckboxButtonSurface = /* @__PURE__ */ forwardRef(function CheckboxButtonSurface({ state, ...props }, ref) {
117
- const { setState } = useCheckboxContext();
137
+ const context = useCheckboxContext();
118
138
  useEffect(() => {
119
- setState({
139
+ context.setState({
120
140
  checked: state.checked,
121
141
  indeterminate: state.indeterminate,
122
142
  disabled: state.disabled,
@@ -129,18 +149,18 @@ const CheckboxButtonSurface = /* @__PURE__ */ forwardRef(function CheckboxButton
129
149
  state.disabled,
130
150
  state.readOnly,
131
151
  state.required,
132
- setState,
152
+ context.setState,
133
153
  ]);
134
154
  return _jsx("span", { ...props, ref: ref });
135
155
  });
156
+ // Registering a message part's id in Button's aria-describedby while the part is mounted
136
157
  function useMessageId(id) {
137
158
  const generatedId = useId();
138
159
  const messageId = id ?? generatedId;
139
- const { setMessageIds } = useCheckboxContext();
160
+ const context = useCheckboxContext();
140
161
  useEffect(() => {
141
- setMessageIds((current) => [...current, messageId]);
142
- return () => setMessageIds((current) => current.filter((value) => value !== messageId));
143
- }, [messageId, setMessageIds]);
162
+ context.setMessageIds((current) => [...current, messageId]);
163
+ return () => context.setMessageIds((current) => current.filter((value) => value !== messageId));
164
+ }, [messageId, context.setMessageIds]);
144
165
  return messageId;
145
166
  }
146
- //# sourceMappingURL=index.js.map
@@ -17,10 +17,10 @@ import type { ComponentProps, ReactElement } from 'react';
17
17
  * }
18
18
  */
19
19
  export declare function Chip({ disableStyle, className, ...props }: ComponentProps<'div'> & StyleProps): import("react").JSX.Element;
20
+ /** Icon-only: put just a CloseButtonIcon inside, never text like "Remove". Name it for screen readers with aria-label instead, e.g. aria-label="Remove tag". */
20
21
  export declare function CloseButton({ disableStyle, type, className, ...props }: ComponentProps<'button'> & StyleProps): import("react").JSX.Element;
21
22
  /** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
22
23
  export declare function CloseButtonIcon({ disableStyle, children, className, ...props }: (Omit<ComponentProps<'svg'>, 'children'> & {
23
24
  /** Omit for the supplied default icon; pass a child only to replace it. */
24
25
  children?: ReactElement<ComponentProps<'svg'>>;
25
26
  }) & StyleProps): ReactElement<import("react").SVGProps<SVGSVGElement>, string | import("react").JSXElementConstructor<any>>;
26
- //# sourceMappingURL=index.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { X } from 'lucide-react';
2
+ import { X } from "../../utils/icons.js";
3
3
  import { cloneElement } from 'react';
4
4
  import { twMerge } from 'tailwind-merge';
5
5
  /**
@@ -21,13 +21,13 @@ import { twMerge } from 'tailwind-merge';
21
21
  export function Chip({ disableStyle, className, ...props }) {
22
22
  return (_jsx("div", { ...props, "data-component": "chip-chip", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
23
23
  }
24
+ /** Icon-only: put just a CloseButtonIcon inside, never text like "Remove". Name it for screen readers with aria-label instead, e.g. aria-label="Remove tag". */
24
25
  export function CloseButton({ disableStyle, type = 'button', className, ...props }) {
25
26
  return (_jsx("button", { ...props, type: type, "data-component": "chip-closebutton", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
26
27
  }
27
28
  /** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
28
29
  export function CloseButtonIcon({ disableStyle, children = _jsx(X, {}), className, ...props }) {
29
30
  return cloneElement(children, {
30
- ...children.props,
31
31
  ...props,
32
32
  ...{
33
33
  'data-component': 'chip-closebuttonicon',
@@ -37,4 +37,3 @@ export function CloseButtonIcon({ disableStyle, children = _jsx(X, {}), classNam
37
37
  strokeWidth: props.strokeWidth ?? children.props.strokeWidth ?? 1.5,
38
38
  });
39
39
  }
40
- //# sourceMappingURL=index.js.map