@central-ui/react 0.1.2 → 0.2.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 (279) 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 +14 -25
  5. package/dist/components/autocomplete/index.js +70 -54
  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/checkbox/index.d.ts +13 -11
  21. package/dist/components/checkbox/index.js +51 -31
  22. package/dist/components/chip/index.d.ts +1 -1
  23. package/dist/components/chip/index.js +2 -3
  24. package/dist/components/combobox/index.d.ts +18 -30
  25. package/dist/components/combobox/index.js +90 -67
  26. package/dist/components/datepicker/index.d.ts +18 -31
  27. package/dist/components/datepicker/index.js +81 -99
  28. package/dist/components/dialog/index.d.ts +14 -27
  29. package/dist/components/dialog/index.js +17 -18
  30. package/dist/components/divider/index.d.ts +0 -1
  31. package/dist/components/divider/index.js +0 -1
  32. package/dist/components/donutchart/index.d.ts +100 -0
  33. package/dist/components/donutchart/index.js +178 -0
  34. package/dist/components/drawer/index.d.ts +12 -21
  35. package/dist/components/drawer/index.js +34 -36
  36. package/dist/components/empty/index.d.ts +1 -2
  37. package/dist/components/empty/index.js +2 -4
  38. package/dist/components/fileupload/index.d.ts +4 -9
  39. package/dist/components/fileupload/index.js +26 -38
  40. package/dist/components/form/index.d.ts +0 -1
  41. package/dist/components/form/index.js +0 -1
  42. package/dist/components/horizontalbarchart/index.d.ts +120 -0
  43. package/dist/components/horizontalbarchart/index.js +193 -0
  44. package/dist/components/input/index.d.ts +22 -22
  45. package/dist/components/input/index.js +76 -105
  46. package/dist/components/linechart/index.d.ts +114 -0
  47. package/dist/components/linechart/index.js +139 -0
  48. package/dist/components/menu/index.d.ts +9 -11
  49. package/dist/components/menu/index.js +42 -39
  50. package/dist/components/metric/index.d.ts +0 -1
  51. package/dist/components/metric/index.js +0 -1
  52. package/dist/components/numberinput/index.d.ts +14 -21
  53. package/dist/components/numberinput/index.js +40 -53
  54. package/dist/components/otpinput/index.d.ts +14 -9
  55. package/dist/components/otpinput/index.js +25 -18
  56. package/dist/components/page/index.d.ts +0 -1
  57. package/dist/components/page/index.js +1 -3
  58. package/dist/components/passwordinput/index.d.ts +14 -11
  59. package/dist/components/passwordinput/index.js +36 -45
  60. package/dist/components/popover/index.d.ts +21 -19
  61. package/dist/components/popover/index.js +34 -15
  62. package/dist/components/radio/index.d.ts +13 -9
  63. package/dist/components/radio/index.js +69 -60
  64. package/dist/components/ratinginput/index.d.ts +13 -8
  65. package/dist/components/ratinginput/index.js +37 -17
  66. package/dist/components/select/index.d.ts +25 -28
  67. package/dist/components/select/index.js +67 -38
  68. package/dist/components/skeleton/index.d.ts +0 -1
  69. package/dist/components/skeleton/index.js +0 -1
  70. package/dist/components/slider/index.d.ts +14 -9
  71. package/dist/components/slider/index.js +64 -63
  72. package/dist/components/spinner/index.d.ts +1 -2
  73. package/dist/components/spinner/index.js +2 -3
  74. package/dist/components/splitter/index.d.ts +1 -2
  75. package/dist/components/splitter/index.js +5 -6
  76. package/dist/components/stepper/index.d.ts +8 -20
  77. package/dist/components/stepper/index.js +15 -16
  78. package/dist/components/switch/index.d.ts +12 -10
  79. package/dist/components/switch/index.js +46 -30
  80. package/dist/components/table/index.d.ts +3 -3
  81. package/dist/components/table/index.js +14 -13
  82. package/dist/components/tabs/index.d.ts +0 -1
  83. package/dist/components/tabs/index.js +1 -2
  84. package/dist/components/textarea/index.d.ts +14 -11
  85. package/dist/components/textarea/index.js +37 -46
  86. package/dist/components/textlink/index.d.ts +3 -1
  87. package/dist/components/textlink/index.js +4 -1
  88. package/dist/components/toast/index.d.ts +8 -14
  89. package/dist/components/toast/index.js +48 -48
  90. package/dist/components/toggle/index.d.ts +0 -1
  91. package/dist/components/toggle/index.js +17 -24
  92. package/dist/components/tooltip/index.d.ts +11 -13
  93. package/dist/components/tooltip/index.js +12 -9
  94. package/dist/components/tour/index.d.ts +154 -0
  95. package/dist/components/tour/index.js +280 -0
  96. package/dist/index.d.ts +5 -2
  97. package/dist/index.js +5 -1
  98. package/dist/types/Icon.d.ts +0 -1
  99. package/dist/types/Icon.js +0 -1
  100. package/dist/types/Style.d.ts +0 -1
  101. package/dist/types/Style.js +0 -1
  102. package/dist/types/Tone.d.ts +0 -1
  103. package/dist/types/Tone.js +0 -1
  104. package/dist/types/Validation.d.ts +12 -0
  105. package/dist/types/Validation.js +1 -0
  106. package/dist/utils/ArkStateToDataAttributes.d.ts +0 -1
  107. package/dist/utils/ArkStateToDataAttributes.js +0 -1
  108. package/dist/utils/Tone.d.ts +0 -1
  109. package/dist/utils/Tone.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 +12 -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-checkbox.css +2 -2
  128. package/src/presets/shopify-polaris/shopify-polaris-combobox.css +2 -2
  129. package/src/presets/shopify-polaris/shopify-polaris-datepicker.css +4 -4
  130. package/src/presets/shopify-polaris/shopify-polaris-dialog.css +16 -0
  131. package/src/presets/shopify-polaris/shopify-polaris-donutchart.css +172 -0
  132. package/src/presets/shopify-polaris/shopify-polaris-drawer.css +16 -0
  133. package/src/presets/shopify-polaris/shopify-polaris-fileupload.css +1 -1
  134. package/src/presets/shopify-polaris/shopify-polaris-horizontalbarchart.css +60 -0
  135. package/src/presets/shopify-polaris/shopify-polaris-input.css +2 -2
  136. package/src/presets/shopify-polaris/shopify-polaris-linechart.css +68 -0
  137. package/src/presets/shopify-polaris/shopify-polaris-menu.css +16 -0
  138. package/src/presets/shopify-polaris/shopify-polaris-numberinput.css +2 -2
  139. package/src/presets/shopify-polaris/shopify-polaris-otpinput.css +2 -2
  140. package/src/presets/shopify-polaris/shopify-polaris-passwordinput.css +2 -2
  141. package/src/presets/shopify-polaris/shopify-polaris-popover.css +29 -0
  142. package/src/presets/shopify-polaris/shopify-polaris-radio.css +2 -2
  143. package/src/presets/shopify-polaris/shopify-polaris-ratinginput.css +2 -2
  144. package/src/presets/shopify-polaris/shopify-polaris-select.css +2 -2
  145. package/src/presets/shopify-polaris/shopify-polaris-slider.css +2 -2
  146. package/src/presets/shopify-polaris/shopify-polaris-stepper.css +16 -0
  147. package/src/presets/shopify-polaris/shopify-polaris-switch.css +2 -2
  148. package/src/presets/shopify-polaris/shopify-polaris-textarea.css +2 -2
  149. package/src/presets/shopify-polaris/shopify-polaris-tooltip.css +16 -0
  150. package/src/presets/shopify-polaris/shopify-polaris.css +4 -0
  151. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-autocomplete.css +2 -2
  152. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-barchart.css +64 -0
  153. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-checkbox.css +2 -2
  154. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-combobox.css +2 -2
  155. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-datepicker.css +2 -2
  156. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-dialog.css +9 -0
  157. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-donutchart.css +172 -0
  158. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-drawer.css +9 -0
  159. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-fileupload.css +1 -1
  160. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-horizontalbarchart.css +60 -0
  161. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-input.css +2 -2
  162. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-linechart.css +68 -0
  163. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-menu.css +9 -0
  164. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-numberinput.css +2 -2
  165. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-otpinput.css +2 -2
  166. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-passwordinput.css +2 -2
  167. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-popover.css +22 -0
  168. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-radio.css +2 -2
  169. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-ratinginput.css +2 -2
  170. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-slider.css +2 -2
  171. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-stepper.css +9 -0
  172. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-switch.css +2 -2
  173. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-textarea.css +2 -2
  174. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-tooltip.css +9 -0
  175. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy.css +4 -0
  176. package/dist/components/accordion/index.d.ts.map +0 -1
  177. package/dist/components/accordion/index.js.map +0 -1
  178. package/dist/components/autocomplete/index.d.ts.map +0 -1
  179. package/dist/components/autocomplete/index.js.map +0 -1
  180. package/dist/components/avatar/index.d.ts.map +0 -1
  181. package/dist/components/avatar/index.js.map +0 -1
  182. package/dist/components/badge/index.d.ts.map +0 -1
  183. package/dist/components/badge/index.js.map +0 -1
  184. package/dist/components/banner/index.d.ts.map +0 -1
  185. package/dist/components/banner/index.js.map +0 -1
  186. package/dist/components/breadcrumb/index.d.ts.map +0 -1
  187. package/dist/components/breadcrumb/index.js.map +0 -1
  188. package/dist/components/button/index.d.ts.map +0 -1
  189. package/dist/components/button/index.js.map +0 -1
  190. package/dist/components/card/index.d.ts.map +0 -1
  191. package/dist/components/card/index.js.map +0 -1
  192. package/dist/components/checkbox/index.d.ts.map +0 -1
  193. package/dist/components/checkbox/index.js.map +0 -1
  194. package/dist/components/chip/index.d.ts.map +0 -1
  195. package/dist/components/chip/index.js.map +0 -1
  196. package/dist/components/combobox/index.d.ts.map +0 -1
  197. package/dist/components/combobox/index.js.map +0 -1
  198. package/dist/components/datepicker/index.d.ts.map +0 -1
  199. package/dist/components/datepicker/index.js.map +0 -1
  200. package/dist/components/dialog/index.d.ts.map +0 -1
  201. package/dist/components/dialog/index.js.map +0 -1
  202. package/dist/components/divider/index.d.ts.map +0 -1
  203. package/dist/components/divider/index.js.map +0 -1
  204. package/dist/components/drawer/index.d.ts.map +0 -1
  205. package/dist/components/drawer/index.js.map +0 -1
  206. package/dist/components/empty/index.d.ts.map +0 -1
  207. package/dist/components/empty/index.js.map +0 -1
  208. package/dist/components/fileupload/index.d.ts.map +0 -1
  209. package/dist/components/fileupload/index.js.map +0 -1
  210. package/dist/components/form/index.d.ts.map +0 -1
  211. package/dist/components/form/index.js.map +0 -1
  212. package/dist/components/input/index.d.ts.map +0 -1
  213. package/dist/components/input/index.js.map +0 -1
  214. package/dist/components/menu/index.d.ts.map +0 -1
  215. package/dist/components/menu/index.js.map +0 -1
  216. package/dist/components/metric/index.d.ts.map +0 -1
  217. package/dist/components/metric/index.js.map +0 -1
  218. package/dist/components/numberinput/index.d.ts.map +0 -1
  219. package/dist/components/numberinput/index.js.map +0 -1
  220. package/dist/components/otpinput/index.d.ts.map +0 -1
  221. package/dist/components/otpinput/index.js.map +0 -1
  222. package/dist/components/page/index.d.ts.map +0 -1
  223. package/dist/components/page/index.js.map +0 -1
  224. package/dist/components/passwordinput/index.d.ts.map +0 -1
  225. package/dist/components/passwordinput/index.js.map +0 -1
  226. package/dist/components/popover/index.d.ts.map +0 -1
  227. package/dist/components/popover/index.js.map +0 -1
  228. package/dist/components/radio/index.d.ts.map +0 -1
  229. package/dist/components/radio/index.js.map +0 -1
  230. package/dist/components/ratinginput/index.d.ts.map +0 -1
  231. package/dist/components/ratinginput/index.js.map +0 -1
  232. package/dist/components/select/index.d.ts.map +0 -1
  233. package/dist/components/select/index.js.map +0 -1
  234. package/dist/components/skeleton/index.d.ts.map +0 -1
  235. package/dist/components/skeleton/index.js.map +0 -1
  236. package/dist/components/slider/index.d.ts.map +0 -1
  237. package/dist/components/slider/index.js.map +0 -1
  238. package/dist/components/spinner/index.d.ts.map +0 -1
  239. package/dist/components/spinner/index.js.map +0 -1
  240. package/dist/components/splitter/index.d.ts.map +0 -1
  241. package/dist/components/splitter/index.js.map +0 -1
  242. package/dist/components/stepper/index.d.ts.map +0 -1
  243. package/dist/components/stepper/index.js.map +0 -1
  244. package/dist/components/switch/index.d.ts.map +0 -1
  245. package/dist/components/switch/index.js.map +0 -1
  246. package/dist/components/table/index.d.ts.map +0 -1
  247. package/dist/components/table/index.js.map +0 -1
  248. package/dist/components/tabs/index.d.ts.map +0 -1
  249. package/dist/components/tabs/index.js.map +0 -1
  250. package/dist/components/textarea/index.d.ts.map +0 -1
  251. package/dist/components/textarea/index.js.map +0 -1
  252. package/dist/components/textlink/index.d.ts.map +0 -1
  253. package/dist/components/textlink/index.js.map +0 -1
  254. package/dist/components/toast/index.d.ts.map +0 -1
  255. package/dist/components/toast/index.js.map +0 -1
  256. package/dist/components/toggle/index.d.ts.map +0 -1
  257. package/dist/components/toggle/index.js.map +0 -1
  258. package/dist/components/tooltip/index.d.ts.map +0 -1
  259. package/dist/components/tooltip/index.js.map +0 -1
  260. package/dist/index.d.ts.map +0 -1
  261. package/dist/index.js.map +0 -1
  262. package/dist/types/Icon.d.ts.map +0 -1
  263. package/dist/types/Icon.js.map +0 -1
  264. package/dist/types/Style.d.ts.map +0 -1
  265. package/dist/types/Style.js.map +0 -1
  266. package/dist/types/Tone.d.ts.map +0 -1
  267. package/dist/types/Tone.js.map +0 -1
  268. package/dist/utils/ArkStateToDataAttributes.d.ts.map +0 -1
  269. package/dist/utils/ArkStateToDataAttributes.js.map +0 -1
  270. package/dist/utils/Tone.d.ts.map +0 -1
  271. package/dist/utils/Tone.js.map +0 -1
  272. package/dist/utils/useForwardClickToInput.d.ts.map +0 -1
  273. package/dist/utils/useForwardClickToInput.js.map +0 -1
  274. package/dist/utils/virtualization/useVirtualizedAutocomplete.d.ts.map +0 -1
  275. package/dist/utils/virtualization/useVirtualizedAutocomplete.js.map +0 -1
  276. package/dist/utils/virtualization/useVirtualizedCombobox.d.ts.map +0 -1
  277. package/dist/utils/virtualization/useVirtualizedCombobox.js.map +0 -1
  278. package/dist/utils/virtualization/useVirtualizedTable.d.ts.map +0 -1
  279. package/dist/utils/virtualization/useVirtualizedTable.js.map +0 -1
package/LICENSE CHANGED
@@ -19,3 +19,52 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
22
+
23
+ ---
24
+
25
+ The built-in icons in src/utils/icons.tsx are copied from lucide-react
26
+ (https://lucide.dev) under the following license:
27
+
28
+ ISC License
29
+
30
+ Copyright (c) 2026 Lucide Icons and Contributors
31
+
32
+ Permission to use, copy, modify, and/or distribute this software for any
33
+ purpose with or without fee is hereby granted, provided that the above
34
+ copyright notice and this permission notice appear in all copies.
35
+
36
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
37
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
38
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
39
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
40
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
41
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
42
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
43
+
44
+ ---
45
+
46
+ The following Lucide icons are derived from the Feather project:
47
+
48
+ airplay, alert-circle, alert-octagon, alert-triangle, aperture, arrow-down-circle, arrow-down-left, arrow-down-right, arrow-down, arrow-left-circle, arrow-left, arrow-right-circle, arrow-right, arrow-up-circle, arrow-up-left, arrow-up-right, arrow-up, at-sign, calendar, cast, check, chevron-down, chevron-left, chevron-right, chevron-up, chevrons-down, chevrons-left, chevrons-right, chevrons-up, circle, clipboard, clock, code, columns, command, compass, corner-down-left, corner-down-right, corner-left-down, corner-left-up, corner-right-down, corner-right-up, corner-up-left, corner-up-right, crosshair, database, divide-circle, divide-square, dollar-sign, download, external-link, feather, frown, hash, headphones, help-circle, info, italic, key, layout, life-buoy, link-2, link, loader, lock, log-in, log-out, maximize, meh, minimize, minimize-2, minus-circle, minus-square, minus, monitor, moon, more-horizontal, more-vertical, move, music, navigation-2, navigation, octagon, pause-circle, percent, plus-circle, plus-square, plus, power, radio, rss, search, server, share, shopping-bag, sidebar, smartphone, smile, square, table-2, tablet, target, terminal, trash-2, trash, triangle, tv, type, upload, x-circle, x-octagon, x-square, x, zoom-in, zoom-out
49
+
50
+ The MIT License (MIT) (for the icons listed above)
51
+
52
+ Copyright (c) 2013-present Cole Bemis
53
+
54
+ Permission is hereby granted, free of charge, to any person obtaining a copy
55
+ of this software and associated documentation files (the "Software"), to deal
56
+ in the Software without restriction, including without limitation the rights
57
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
58
+ copies of the Software, and to permit persons to whom the Software is
59
+ furnished to do so, subject to the following conditions:
60
+
61
+ The above copyright notice and this permission notice shall be included in all
62
+ copies or substantial portions of the Software.
63
+
64
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
65
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
66
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
67
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
68
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
69
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
70
+ SOFTWARE.
@@ -1,4 +1,5 @@
1
1
  import type { StyleProps } from '../../types/Style.ts';
2
+ import type { AsChildProps } from '../../utils/asChild.ts';
2
3
  import { Accordion as BaseAccordion } from '@base-ui/react/accordion';
3
4
  import type { ReactElement } from 'react';
4
5
  import type { SVGIconProps } from '../../types/Icon.ts';
@@ -58,9 +59,10 @@ export declare const List: import("react").ForwardRefExoticComponent<Omit<import
58
59
  export declare const Item: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").AccordionItemProps, "className" | "render"> & {
59
60
  className?: string;
60
61
  } & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
61
- export declare const OpenButton: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").AccordionTriggerProps, "className"> & {
62
+ /** Expands or collapses its Item. Pass asChild to give this behavior to your own button instead; it keeps the state data attributes (like data-panel-open) but none of this part's styling. */
63
+ export declare const OpenButton: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").AccordionTriggerProps, "className" | "render"> & {
62
64
  className?: string;
63
- } & StyleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
65
+ } & AsChildProps & StyleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
64
66
  export declare const OpenerTitle: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLSpanElement> & import("react").HTMLAttributes<HTMLSpanElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
65
67
  /** Supplies the expansion icon and follows open state automatically. Omit children for the default; pass an icon only to replace it. */
66
68
  export declare const OpenerIndicator: import("react").ForwardRefExoticComponent<Omit<SVGIconProps & {
@@ -70,4 +72,3 @@ export declare const OpenerIndicator: import("react").ForwardRefExoticComponent<
70
72
  export declare const Content: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").AccordionPanelProps, "className"> & {
71
73
  className?: string;
72
74
  } & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
73
- //# sourceMappingURL=index.d.ts.map
@@ -1,8 +1,9 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import { asChildRendering } from "../../utils/asChild.js";
2
3
  import { Accordion as BaseAccordion } from '@base-ui/react/accordion';
3
4
  import { cloneElement, createContext, forwardRef, useContext } from 'react';
4
5
  import { twMerge } from 'tailwind-merge';
5
- import { ChevronDown } from 'lucide-react';
6
+ import { ChevronDown } from "../../utils/icons.js";
6
7
  /**
7
8
  * Use List → Item → OpenButton and Content. Item owns its expansion; do not add your own visibility conditions. Put the heading inside OpenerTitle and let OpenerIndicator reflect expansion.
8
9
  *
@@ -64,8 +65,10 @@ export const List = /* @__PURE__ */ forwardRef(function List({ disableStyle, cla
64
65
  export const Item = /* @__PURE__ */ forwardRef(function Item({ disableStyle, className, ...props }, ref) {
65
66
  return (_jsx(BaseAccordion.Item, { ...props, ref: ref, "data-component": "accordion-item", "data-style-disabled": disableStyle ? '' : undefined, className: className, render: (itemProps, state) => (_jsx(ItemContext.Provider, { value: state.open, children: _jsx("div", { ...itemProps }) })) }));
66
67
  });
67
- export const OpenButton = /* @__PURE__ */ forwardRef(function OpenButton({ disableStyle, className, ...props }, ref) {
68
- return (_jsx(BaseAccordion.Header, { children: _jsx(BaseAccordion.Trigger, { ...props, ref: ref, "data-component": "accordion-openbutton", "data-style-disabled": disableStyle ? '' : undefined, className: className }) }));
68
+ /** Expands or collapses its Item. Pass asChild to give this behavior to your own button instead; it keeps the state data attributes (like data-panel-open) but none of this part's styling. */
69
+ export const OpenButton = /* @__PURE__ */ forwardRef(function OpenButton({ asChild, disableStyle, children, ...props }, ref) {
70
+ const rendering = asChildRendering({ asChild, children, component: 'accordion-openbutton', disableStyle });
71
+ return (_jsx(BaseAccordion.Header, { children: _jsx(BaseAccordion.Trigger, { ...props, ref: ref, ...rendering }) }));
69
72
  });
70
73
  export const OpenerTitle = /* @__PURE__ */ forwardRef(function OpenerTitle({ disableStyle, className, ...props }, ref) {
71
74
  return (_jsx("span", { ...props, ref: ref, "data-component": "accordion-openertitle", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
@@ -88,5 +91,5 @@ export const OpenerIndicator = /* @__PURE__ */ forwardRef(function OpenerIndicat
88
91
  export const Content = /* @__PURE__ */ forwardRef(function Content({ disableStyle, className, ...props }, ref) {
89
92
  return (_jsx(BaseAccordion.Panel, { ...props, ref: ref, "data-component": "accordion-content", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
90
93
  });
94
+ // Sharing whether the item is open, so OpenerIndicator can follow it
91
95
  const ItemContext = /* @__PURE__ */ createContext(false);
92
- //# sourceMappingURL=index.js.map
@@ -1,6 +1,8 @@
1
1
  import { Autocomplete as BaseAutocomplete } from '@base-ui/react/autocomplete';
2
2
  import type { SVGIconProps } from '../../types/Icon.ts';
3
3
  import type { ComponentProps, ComponentPropsWithRef, ReactElement, ReactNode } from 'react';
4
+ import type { Validation } from '../../types/Validation.ts';
5
+ import type { ValidationMessageChildren } from '../../utils/Validation.ts';
4
6
  type StyleProps = {
5
7
  /**
6
8
  * Disables preset styling for this element.
@@ -48,8 +50,8 @@ export type RootProps<T extends readonly GroupShape[]> = Omit<BaseAutocomplete.R
48
50
  * Preserve the grouped structure; return undefined to restore built-in filtering.
49
51
  */
50
52
  filteredItems?: readonly GroupType<T>[];
51
- /** Changes the validation appearance; does not validate or show messages. @default 'neutral' */
52
- tone?: 'neutral' | 'valid' | 'invalid';
53
+ /** The field's validation state, with an optional message: `'error'` styles it as invalid, `['error', 'Pick a city']` also shows that message in Error. Same for `'success'` and Success. Omit it for a neutral field. */
54
+ validation?: Validation;
53
55
  };
54
56
  /**
55
57
  * Suggests cities while allowing users to keep their own text. Use Combobox instead
@@ -199,15 +201,6 @@ export type RootProps<T extends readonly GroupShape[]> = Omit<BaseAutocomplete.R
199
201
  * )}
200
202
  * </Autocomplete.Loading>
201
203
  *
202
- * @example Use a custom trigger button
203
- * // Replace the AddonOpenButton in Addon; do not add a second opener beside it.
204
- * // PopupOpenHandler adds behavior only. Its child owns the appearance.
205
- * ;<Autocomplete.PopupOpenHandler>
206
- * <button type="button" className="rounded-lg px-2">
207
- * Show cities
208
- * </button>
209
- * </Autocomplete.PopupOpenHandler>
210
- *
211
204
  * @example Replace styling on one part
212
205
  * // All other parts keep their imported preset styles.
213
206
  * ;<Autocomplete.AddonOpenButton
@@ -218,7 +211,7 @@ export type RootProps<T extends readonly GroupShape[]> = Omit<BaseAutocomplete.R
218
211
  * <Autocomplete.AddonOpenButtonIcon />
219
212
  * </Autocomplete.AddonOpenButton>
220
213
  */
221
- export declare function Root<T extends readonly GroupShape[]>({ children, id, tone, open, defaultOpen, onOpenChange, ...props }: RootProps<T>): import("react").JSX.Element;
214
+ export declare function Root<T extends readonly GroupShape[]>({ children, id, validation, open, defaultOpen, onOpenChange, ...props }: RootProps<T>): import("react").JSX.Element;
222
215
  /** Use for the standard stacked layout, or omit when supplying your own layout. */
223
216
  export declare const Container: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
224
217
  /** Labels the input automatically using Root's id. Supply the visible label as children; no htmlFor needed. */
@@ -285,12 +278,6 @@ export type PopupProps = Omit<ComponentPropsWithRef<typeof BaseAutocomplete.Popu
285
278
  export declare function Popup({ disableStyle, container, keepMounted, anchor, positionMethod, side, sideOffset, align, alignOffset, collisionBoundary, collisionPadding, sticky, arrowPadding, disableAnchorTracking, collisionAvoidance, className, style, ...props }: PopupProps): import("react").JSX.Element;
286
279
  /** Optional decorative popup arrow. Place inside Popup; the SVG and direction handling are supplied. No children needed. */
287
280
  export declare const Arrow: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").SVGProps<SVGSVGElement>, "children" | "dangerouslySetInnerHTML"> & StyleProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
288
- /** Behavior only: turns its single child element into the popup trigger. Adds no preset styling and has no disableStyle prop. Use an accessible button child; pass className to the child for its appearance. */
289
- export declare const PopupOpenHandler: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").AutocompleteTriggerProps, "children" | "className" | "render"> & {
290
- className?: string;
291
- /** Supply the button that should open the popup; no additional click handler needed. */
292
- children: ReactElement;
293
- }, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
294
281
  /** Optional input adornment container inside InputGroup. Wraps icons, text, or buttons without adding trigger behavior. */
295
282
  export declare const Addon: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & {
296
283
  /** Use emphasized for a shaded addon. Does not add interaction. @default 'normal' */
@@ -311,7 +298,7 @@ export declare const AddonButton: import("react").ForwardRefExoticComponent<Omit
311
298
  /** Root disabled or readOnly already disables this button; use for an additional condition. */
312
299
  disabled?: ComponentProps<"button">["disabled"];
313
300
  } & StyleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
314
- /** Use Input with optional Addon controls inside. An opener is optional for typing-driven suggestions. Root tone changes appearance only. */
301
+ /** Use Input with optional Addon controls inside. An opener is optional for typing-driven suggestions. Root validation controls its preset validation border. */
315
302
  export declare const InputGroup: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").AutocompleteInputGroupProps, "className"> & {
316
303
  className?: string;
317
304
  } & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
@@ -341,12 +328,15 @@ export declare const ItemText: import("react").ForwardRefExoticComponent<Omit<im
341
328
  export declare const AddonText: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLSpanElement> & import("react").HTMLAttributes<HTMLSpanElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
342
329
  /** Text content inside Empty. Supply your empty-result message; Empty handles its visibility automatically. */
343
330
  export declare const EmptyText: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
344
- /** Optional supporting text. Supply its content; it does not connect itself to the input with aria-describedby. Use matching id and Input aria-describedby when needed. */
331
+ /** Optional supporting text, announced with the input through aria-describedby automatically. */
345
332
  export declare const Description: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
346
- /** Optional alert message. You control when it is rendered and its contents; tone does not validate or show this message automatically. */
347
- export declare const Error: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
348
- /** Optional success status. You control when it is rendered and its contents; tone does not show this message automatically. */
349
- export declare const Success: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
333
+ type MessageProps = Omit<ComponentProps<'div'>, 'children'> & StyleProps & {
334
+ children?: ValidationMessageChildren;
335
+ };
336
+ /** 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. */
337
+ export declare const Error: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
338
+ /** 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. */
339
+ export declare const Success: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
350
340
  /** Built-in decorative open-button icon. Place inside AddonOpenButton; no children needed. Defaults to strokeWidth 1.5. */
351
341
  export declare const AddonOpenButtonIcon: import("react").ForwardRefExoticComponent<Omit<SVGIconProps & StyleProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
352
342
  /** Built-in decorative clear icon. Place inside AddonClearButton; no children needed. Defaults to strokeWidth 1.5. */
@@ -362,4 +352,3 @@ export declare const LoadingText: import("react").ForwardRefExoticComponent<Omit
362
352
  /** Built-in decorative spinner for Loading. No children needed; you control when it is rendered. */
363
353
  export declare const LoadingIcon: import("react").ForwardRefExoticComponent<Omit<SVGIconProps & StyleProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
364
354
  export {};
365
- //# sourceMappingURL=index.d.ts.map
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Autocomplete as BaseAutocomplete } from '@base-ui/react/autocomplete';
3
- import { ChevronsUpDown, LoaderCircle, X } from 'lucide-react';
4
- import { cloneElement, createContext, forwardRef, useContext, useId, useState, } from 'react';
3
+ import { ChevronsUpDown, LoaderCircle, X } from "../../utils/icons.js";
4
+ import { cloneElement, createContext, forwardRef, useContext, useEffect, useId, useState, } from 'react';
5
5
  import { twMerge } from 'tailwind-merge';
6
- import { ToneProvider, useToneContext } from "../../utils/Tone.js";
6
+ import { readValidation, validationAttributes, validationMessageContent } from "../../utils/Validation.js";
7
7
  /**
8
8
  * Suggests cities while allowing users to keep their own text. Use Combobox instead
9
9
  * when the user must choose an existing item. Input handles filtering and completion;
@@ -152,15 +152,6 @@ import { ToneProvider, useToneContext } from "../../utils/Tone.js";
152
152
  * )}
153
153
  * </Autocomplete.Loading>
154
154
  *
155
- * @example Use a custom trigger button
156
- * // Replace the AddonOpenButton in Addon; do not add a second opener beside it.
157
- * // PopupOpenHandler adds behavior only. Its child owns the appearance.
158
- * ;<Autocomplete.PopupOpenHandler>
159
- * <button type="button" className="rounded-lg px-2">
160
- * Show cities
161
- * </button>
162
- * </Autocomplete.PopupOpenHandler>
163
- *
164
155
  * @example Replace styling on one part
165
156
  * // All other parts keep their imported preset styles.
166
157
  * ;<Autocomplete.AddonOpenButton
@@ -171,10 +162,12 @@ import { ToneProvider, useToneContext } from "../../utils/Tone.js";
171
162
  * <Autocomplete.AddonOpenButtonIcon />
172
163
  * </Autocomplete.AddonOpenButton>
173
164
  */
174
- export function Root({ children, id, tone = 'neutral', open, defaultOpen = false, onOpenChange, ...props }) {
165
+ export function Root({ children, id, validation, open, defaultOpen = false, onOpenChange, ...props }) {
175
166
  const generatedId = useId();
176
167
  const inputId = id ?? generatedId;
177
168
  const [openInternalState, setOpenInternalState] = useState(defaultOpen);
169
+ // Holding the ids of Description, Error and Success, so Input announces them to screen readers through aria-describedby
170
+ const [describedByIds, setDescribedByIds] = useState([]);
178
171
  return (_jsx(BaseAutocomplete.Root, { ...props, id: inputId, open: open, defaultOpen: defaultOpen, onOpenChange: (nextOpen, details) => {
179
172
  onOpenChange?.(nextOpen, details);
180
173
  if (!details.isCanceled)
@@ -185,7 +178,10 @@ export function Root({ children, id, tone = 'neutral', open, defaultOpen = false
185
178
  disabled: props.disabled ?? false,
186
179
  readOnly: props.readOnly ?? false,
187
180
  required: props.required ?? false,
188
- }, children: _jsx(ToneProvider, { value: tone, children: children }) }) }));
181
+ validation: readValidation(validation),
182
+ describedByIds,
183
+ setDescribedByIds,
184
+ }, children: children }) }));
189
185
  }
190
186
  /** Use for the standard stacked layout, or omit when supplying your own layout. */
191
187
  export const Container = /* @__PURE__ */ forwardRef(function Container({ disableStyle, className, ...props }, ref) {
@@ -193,14 +189,14 @@ export const Container = /* @__PURE__ */ forwardRef(function Container({ disable
193
189
  });
194
190
  /** Labels the input automatically using Root's id. Supply the visible label as children; no htmlFor needed. */
195
191
  export const Label = /* @__PURE__ */ forwardRef(function Label({ disableStyle, className, ...props }, ref) {
196
- const { inputId } = useAutocompleteContext();
192
+ const context = useAutocompleteContext();
197
193
  const attributes = usePartAttributes();
198
- return (_jsx("label", { ...attributes, ...props, ref: ref, htmlFor: inputId, "data-component": "autocomplete-label", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
194
+ return (_jsx("label", { ...attributes, ...props, ref: ref, htmlFor: context.inputId, "data-component": "autocomplete-label", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
199
195
  });
200
196
  /** Let the input handle suggestion filtering and completion. It accepts free text; choosing a suggestion is optional. Label association is automatic. */
201
- export const Input = /* @__PURE__ */ forwardRef(function Input({ disableStyle, className, ...props }, ref) {
202
- const { inputId } = useAutocompleteContext();
203
- return (_jsx(BaseAutocomplete.Input, { ...props, ref: ref, id: inputId, "data-component": "autocomplete-input", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
197
+ export const Input = /* @__PURE__ */ forwardRef(function Input({ disableStyle, className, 'aria-describedby': describedBy, ...props }, ref) {
198
+ const context = useAutocompleteContext();
199
+ return (_jsx(BaseAutocomplete.Input, { "aria-invalid": context.validation.state === 'error' || undefined, ...props, "aria-describedby": [describedBy, ...context.describedByIds].filter(Boolean).join(' ') || undefined, ref: ref, id: context.inputId, "data-component": "autocomplete-input", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
204
200
  });
205
201
  /** Use only for an additional custom display of the current input text. Do not use it to build the editable input; Input already handles that. */
206
202
  export const Value = BaseAutocomplete.Value;
@@ -238,10 +234,6 @@ export function Popup({ disableStyle, container, keepMounted, anchor, positionMe
238
234
  export const Arrow = /* @__PURE__ */ forwardRef(function Arrow({ disableStyle, className, style, ...props }, ref) {
239
235
  return (_jsxs(BaseAutocomplete.Arrow, { style: style, render: _jsx("svg", { ...props, ref: ref, "aria-hidden": true, width: "20", height: "10", viewBox: "0 0 20 10" }), "data-component": "autocomplete-arrow", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: [_jsx("path", { d: "M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z", "data-component": "autocomplete-arrow-1" }), _jsx("path", { d: "M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z", "data-component": "autocomplete-arrow-2" }), _jsx("path", { d: "M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z", "data-component": "autocomplete-arrow-3" })] }));
240
236
  });
241
- /** Behavior only: turns its single child element into the popup trigger. Adds no preset styling and has no disableStyle prop. Use an accessible button child; pass className to the child for its appearance. */
242
- export const PopupOpenHandler = /* @__PURE__ */ forwardRef(function PopupOpenHandler({ children, ...props }, ref) {
243
- return _jsx(BaseAutocomplete.Trigger, { ...props, ref: ref, render: children });
244
- });
245
237
  /** Optional input adornment container inside InputGroup. Wraps icons, text, or buttons without adding trigger behavior. */
246
238
  export const Addon = /* @__PURE__ */ forwardRef(function Addon({ disableStyle, variant = 'normal', className, ...props }, ref) {
247
239
  return (_jsx("div", { ...props, ref: ref, "data-variant": variant, "data-component": "autocomplete-addon", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
@@ -266,10 +258,10 @@ export const AddonButton = /* @__PURE__ */ forwardRef(function AddonButton({ dis
266
258
  const attributes = usePartAttributes();
267
259
  return (_jsx("button", { ...attributes, ...props, ref: ref, type: type, disabled: disabled || context.disabled || context.readOnly, "data-component": "autocomplete-addonbutton", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
268
260
  });
269
- /** Use Input with optional Addon controls inside. An opener is optional for typing-driven suggestions. Root tone changes appearance only. */
261
+ /** Use Input with optional Addon controls inside. An opener is optional for typing-driven suggestions. Root validation controls its preset validation border. */
270
262
  export const InputGroup = /* @__PURE__ */ forwardRef(function InputGroup({ disableStyle, className, ...props }, ref) {
271
- const tone = useToneContext();
272
- return (_jsx(BaseAutocomplete.InputGroup, { "data-tone": tone, ...props, ref: ref, "data-component": "autocomplete-inputgroup", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
263
+ const context = useAutocompleteContext();
264
+ return (_jsx(BaseAutocomplete.InputGroup, { ...validationAttributes(context.validation), ...props, ref: ref, "data-component": "autocomplete-inputgroup", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
273
265
  });
274
266
  /** Opens and closes the popup automatically; no click handler needed. Supply its content, normally AddonOpenButtonIcon, and an accessible label. */
275
267
  export const AddonOpenButton = /* @__PURE__ */ forwardRef(function AddonOpenButton({ disableStyle, className, ...props }, ref) {
@@ -306,35 +298,50 @@ export const EmptyText = /* @__PURE__ */ forwardRef(function EmptyText({ disable
306
298
  const attributes = usePartAttributes();
307
299
  return (_jsx("div", { ...attributes, ...props, ref: ref, "data-component": "autocomplete-emptytext", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
308
300
  });
309
- /** Optional supporting text. Supply its content; it does not connect itself to the input with aria-describedby. Use matching id and Input aria-describedby when needed. */
310
- export const Description = /* @__PURE__ */ forwardRef(function Description({ disableStyle, className, ...props }, ref) {
301
+ /** Optional supporting text, announced with the input through aria-describedby automatically. */
302
+ export const Description = /* @__PURE__ */ forwardRef(function Description({ disableStyle, className, id, ...props }, ref) {
303
+ const describedById = useDescribedById(id);
311
304
  const attributes = usePartAttributes();
312
- return (_jsx("div", { ...attributes, ...props, ref: ref, "data-component": "autocomplete-description", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
305
+ return (_jsx("div", { ...attributes, ...props, id: describedById, ref: ref, "data-component": "autocomplete-description", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
313
306
  });
314
- /** Optional alert message. You control when it is rendered and its contents; tone does not validate or show this message automatically. */
315
- export const Error = /* @__PURE__ */ forwardRef(function Error({ disableStyle, className, ...props }, ref) {
316
- const attributes = usePartAttributes();
317
- return (_jsx("div", { role: "alert", "aria-atomic": "true", ...attributes, ...props, ref: ref, "data-component": "autocomplete-error", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
307
+ /** 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. */
308
+ export const Error = /* @__PURE__ */ forwardRef(function Error({ children, ...props }, ref) {
309
+ const context = useAutocompleteContext();
310
+ const content = validationMessageContent(context.validation, 'error', children);
311
+ if (content === undefined)
312
+ return null;
313
+ return _jsx(Message, { ...props, ref: ref, role: "alert", component: "autocomplete-error", children: content });
314
+ });
315
+ /** 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. */
316
+ export const Success = /* @__PURE__ */ forwardRef(function Success({ children, ...props }, ref) {
317
+ const context = useAutocompleteContext();
318
+ const content = validationMessageContent(context.validation, 'success', children);
319
+ if (content === undefined)
320
+ return null;
321
+ return _jsx(Message, { ...props, ref: ref, role: "status", component: "autocomplete-success", children: content });
318
322
  });
319
- /** Optional success status. You control when it is rendered and its contents; tone does not show this message automatically. */
320
- export const Success = /* @__PURE__ */ forwardRef(function Success({ disableStyle, className, ...props }, ref) {
323
+ // The shared body of Error and Success, mounted only while they show, so only visible messages describe the input
324
+ const Message = /* @__PURE__ */ forwardRef(function Message({ disableStyle, className, id, component, ...props }, ref) {
325
+ const describedById = useDescribedById(id);
321
326
  const attributes = usePartAttributes();
322
- return (_jsx("div", { role: "status", "aria-atomic": "true", ...attributes, ...props, ref: ref, "data-component": "autocomplete-success", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
327
+ return _jsx("div", { "aria-atomic": "true", ...attributes, ...props, id: describedById, ref: ref, "data-component": component, "data-style-disabled": disableStyle ? '' : undefined, className: className });
323
328
  });
324
329
  /** Built-in decorative open-button icon. Place inside AddonOpenButton; no children needed. Defaults to strokeWidth 1.5. */
325
- export const AddonOpenButtonIcon = /* @__PURE__ */ forwardRef(function AddonOpenButtonIcon({ disableStyle, className, strokeWidth = 1.5, ...props }, ref) {
326
- const attributes = usePartAttributes();
327
- return (_jsx(ChevronsUpDown, { ...attributes, "aria-hidden": true, ...props, ref: ref, strokeWidth: strokeWidth, "data-component": "autocomplete-addonopenbuttonicon", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
330
+ export const AddonOpenButtonIcon = /* @__PURE__ */ forwardRef(function AddonOpenButtonIcon(props, ref) {
331
+ return _jsx(BuiltInIcon, { ...props, ref: ref, icon: ChevronsUpDown, component: "autocomplete-addonopenbuttonicon" });
328
332
  });
329
333
  /** Built-in decorative clear icon. Place inside AddonClearButton; no children needed. Defaults to strokeWidth 1.5. */
330
- export const AddonClearButtonIcon = /* @__PURE__ */ forwardRef(function AddonClearButtonIcon({ disableStyle, className, strokeWidth = 1.5, ...props }, ref) {
331
- const attributes = usePartAttributes();
332
- return (_jsx(X, { ...attributes, "aria-hidden": true, ...props, ref: ref, strokeWidth: strokeWidth, "data-component": "autocomplete-addonclearbuttonicon", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
334
+ export const AddonClearButtonIcon = /* @__PURE__ */ forwardRef(function AddonClearButtonIcon(props, ref) {
335
+ return _jsx(BuiltInIcon, { ...props, ref: ref, icon: X, component: "autocomplete-addonclearbuttonicon" });
333
336
  });
334
337
  /** Optional spinner inside Addon. Does not detect requests: you decide when to render it. Defaults to strokeWidth 1.5. */
335
- export const AddonLoadingIcon = /* @__PURE__ */ forwardRef(function AddonLoadingIcon({ disableStyle, className, strokeWidth = 1.5, ...props }, ref) {
338
+ export const AddonLoadingIcon = /* @__PURE__ */ forwardRef(function AddonLoadingIcon(props, ref) {
339
+ return _jsx(BuiltInIcon, { ...props, ref: ref, icon: LoaderCircle, component: "autocomplete-addonloadingicon" });
340
+ });
341
+ // The shared body of the built-in decorative icons above, which only differ by their icon and component name
342
+ const BuiltInIcon = /* @__PURE__ */ forwardRef(function BuiltInIcon({ disableStyle, className, strokeWidth = 1.5, icon: Icon, component, ...props }, ref) {
336
343
  const attributes = usePartAttributes();
337
- return (_jsx(LoaderCircle, { ...attributes, "aria-hidden": true, ...props, ref: ref, strokeWidth: strokeWidth, "data-component": "autocomplete-addonloadingicon", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
344
+ return _jsx(Icon, { ...attributes, "aria-hidden": true, ...props, ref: ref, strokeWidth: strokeWidth, "data-component": component, "data-style-disabled": disableStyle ? '' : undefined, className: className });
338
345
  });
339
346
  /** Optional async status inside Popup, below Empty and above ScrollArea. Omit entirely for synchronous items. For async items, keep Loading mounted and conditionally render only LoadingIcon and LoadingText from your request state. Does not detect requests or manage visibility. */
340
347
  export const Loading = /* @__PURE__ */ forwardRef(function Loading({ disableStyle, className, ...props }, ref) {
@@ -345,8 +352,8 @@ export const LoadingText = /* @__PURE__ */ forwardRef(function LoadingText({ dis
345
352
  return (_jsx("div", { ...props, ref: ref, "data-component": "autocomplete-loadingtext", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
346
353
  });
347
354
  /** Built-in decorative spinner for Loading. No children needed; you control when it is rendered. */
348
- export const LoadingIcon = /* @__PURE__ */ forwardRef(function LoadingIcon({ disableStyle, className, ...props }, ref) {
349
- return (_jsx(LoaderCircle, { "aria-hidden": true, strokeWidth: undefined, ...props, ref: ref, "data-component": "autocomplete-loadingicon", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
355
+ export const LoadingIcon = /* @__PURE__ */ forwardRef(function LoadingIcon({ disableStyle, className, strokeWidth = 2, ...props }, ref) {
356
+ return (_jsx(LoaderCircle, { "aria-hidden": true, strokeWidth: strokeWidth, ...props, ref: ref, "data-component": "autocomplete-loadingicon", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
350
357
  });
351
358
  const AutocompleteContext =
352
359
  /* @__PURE__ */ createContext(null);
@@ -357,14 +364,23 @@ function useAutocompleteContext() {
357
364
  return context;
358
365
  }
359
366
  function usePartAttributes() {
360
- const { open, disabled, readOnly, required } = useAutocompleteContext();
361
- const tone = useToneContext();
367
+ const context = useAutocompleteContext();
362
368
  return {
363
- 'data-open': open ? '' : undefined,
364
- 'data-disabled': disabled ? '' : undefined,
365
- 'data-readonly': readOnly ? '' : undefined,
366
- 'data-required': required ? '' : undefined,
367
- 'data-tone': tone,
369
+ 'data-open': context.open ? '' : undefined,
370
+ 'data-disabled': context.disabled ? '' : undefined,
371
+ 'data-readonly': context.readOnly ? '' : undefined,
372
+ 'data-required': context.required ? '' : undefined,
373
+ ...validationAttributes(context.validation),
368
374
  };
369
375
  }
370
- //# sourceMappingURL=index.js.map
376
+ // Registering a part's id in Input's aria-describedby while the part is mounted
377
+ function useDescribedById(id) {
378
+ const context = useAutocompleteContext();
379
+ const generatedId = useId();
380
+ const describedById = id ?? generatedId;
381
+ useEffect(() => {
382
+ context.setDescribedByIds((current) => [...current, describedById]);
383
+ return () => context.setDescribedByIds((current) => current.filter((currentId) => currentId !== describedById));
384
+ }, [describedById, context.setDescribedByIds]);
385
+ return describedById;
386
+ }
@@ -37,7 +37,7 @@ export declare const List: import("react").ForwardRefExoticComponent<Omit<import
37
37
  export declare const Image: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").AvatarImageProps, "className"> & {
38
38
  className?: string;
39
39
  } & StyleProps, "ref"> & import("react").RefAttributes<HTMLImageElement>>;
40
- export declare const FallbackNameInitials: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").AvatarFallbackProps, "children" | "className"> & {
40
+ export declare const FallbackNameInitials: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").AvatarFallbackProps, "className" | "children"> & {
41
41
  className?: string;
42
42
  /** Choose the initials background. The name-to-initials conversion is automatic. */
43
43
  color: string;
@@ -45,4 +45,3 @@ export declare const FallbackNameInitials: import("react").ForwardRefExoticCompo
45
45
  children: string;
46
46
  } & StyleProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
47
47
  export declare const FallbackImage: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLImageElement> & import("react").ImgHTMLAttributes<HTMLImageElement> & Pick<import("@base-ui/react").AvatarFallbackProps, "delay"> & StyleProps, "ref"> & import("react").RefAttributes<HTMLImageElement>>;
48
- //# sourceMappingURL=index.d.ts.map
@@ -58,4 +58,3 @@ export const FallbackImage = /* @__PURE__ */ forwardRef(function FallbackImage({
58
58
  });
59
59
  const SizeContext =
60
60
  /* @__PURE__ */ createContext('medium');
61
- //# sourceMappingURL=index.js.map
@@ -26,4 +26,3 @@ export declare function Icon({ disableStyle, children, className, ...props }: (O
26
26
  /** Supply the decorative icon; the wrapper forwards the relevant state and preserves its classes. */
27
27
  children: ReactElement<ComponentProps<'svg'>>;
28
28
  }) & StyleProps): ReactElement<import("react").SVGProps<SVGSVGElement>, string | import("react").JSXElementConstructor<any>>;
29
- //# sourceMappingURL=index.d.ts.map
@@ -23,9 +23,10 @@ export default function Badge({ disableStyle, className, tone, ...props }) {
23
23
  }
24
24
  /** Supply the decorative icon as a child. Its classes are preserved; interaction belongs to the surrounding control. */
25
25
  export function Icon({ disableStyle, children, className, ...props }) {
26
+ // cloneElement keeps the icon's own props, so only the added ones are passed
26
27
  return cloneElement(children, {
27
- ...children.props,
28
28
  ...props,
29
+ // Spread from an object so the data-* keys pass the element props' excess property check
29
30
  ...{
30
31
  'data-component': 'badge-icon',
31
32
  'data-style-disabled': disableStyle ? '' : undefined,
@@ -33,4 +34,3 @@ export function Icon({ disableStyle, children, className, ...props }) {
33
34
  className: twMerge(children.props.className, className),
34
35
  });
35
36
  }
36
- //# sourceMappingURL=index.js.map
@@ -57,6 +57,7 @@ export declare function Icon({ disableStyle, children, className, ...props }: (O
57
57
  'data-tone'?: BannerTone;
58
58
  }, string | import("react").JSXElementConstructor<any>>;
59
59
  export declare function Title({ disableStyle, className, ...props }: ComponentProps<'h2'> & StyleProps): import("react").JSX.Element;
60
+ /** Icon-only: put just a CloseButtonIcon inside, never text like "Close". Name it for screen readers with aria-label instead, e.g. aria-label="Dismiss". */
60
61
  export declare function CloseButton({ disableStyle, type, className, onClick, ...props }: ComponentProps<'button'> & StyleProps): import("react").JSX.Element;
61
62
  /** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
62
63
  export declare function CloseButtonIcon({ disableStyle, children, className, ...props }: (Omit<ComponentProps<'svg'>, 'children'> & {
@@ -68,4 +69,3 @@ export declare function CloseButtonIcon({ disableStyle, children, className, ...
68
69
  export declare function Body({ disableStyle, className, ...props }: ComponentProps<'div'> & StyleProps): import("react").JSX.Element;
69
70
  export declare function Description({ disableStyle, className, ...props }: ComponentProps<'div'> & StyleProps): import("react").JSX.Element;
70
71
  export {};
71
- //# sourceMappingURL=index.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { CircleAlert, CircleCheck, Info, Text, TriangleAlert, X, } from 'lucide-react';
2
+ import { CircleAlert, CircleCheck, Info, Text, TriangleAlert, X, } from "../../utils/icons.js";
3
3
  import { cloneElement, createContext, useContext } from 'react';
4
4
  import { twMerge } from 'tailwind-merge';
5
5
  const BannerContext = /* @__PURE__ */ createContext({
@@ -48,32 +48,31 @@ export function Root({ tone = 'neutral', onClose, children, }) {
48
48
  return (_jsx(BannerContext.Provider, { value: { tone, onClose }, children: children }));
49
49
  }
50
50
  export function Surface({ disableStyle, className, ...props }) {
51
- const { tone } = useContext(BannerContext);
52
- return (_jsx("div", { ...props, "data-tone": tone, "data-component": "banner-surface", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
51
+ const context = useContext(BannerContext);
52
+ return (_jsx("div", { ...props, "data-tone": context.tone, "data-component": "banner-surface", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
53
53
  }
54
54
  export function Header({ disableStyle, className, ...props }) {
55
- const { tone } = useContext(BannerContext);
56
- return (_jsx("div", { ...props, "data-tone": tone, "data-component": "banner-header", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
55
+ const context = useContext(BannerContext);
56
+ return (_jsx("div", { ...props, "data-tone": context.tone, "data-component": "banner-header", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
57
57
  }
58
58
  /** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
59
59
  export function Icon({ disableStyle, children, className, ...props }) {
60
- const { tone } = useContext(BannerContext);
60
+ const context = useContext(BannerContext);
61
61
  const icon = children ??
62
62
  (() => {
63
- if (tone === 'danger')
63
+ if (context.tone === 'danger')
64
64
  return _jsx(CircleAlert, {});
65
- if (tone === 'informative')
65
+ if (context.tone === 'informative')
66
66
  return _jsx(Info, {});
67
- if (tone === 'success')
67
+ if (context.tone === 'success')
68
68
  return _jsx(CircleCheck, {});
69
- if (tone === 'caution')
69
+ if (context.tone === 'caution')
70
70
  return _jsx(TriangleAlert, {});
71
71
  return _jsx(Text, {});
72
72
  })();
73
73
  return cloneElement(icon, {
74
- ...icon.props,
75
74
  ...props,
76
- 'data-tone': tone,
75
+ 'data-tone': context.tone,
77
76
  ...{
78
77
  'data-component': 'banner-icon',
79
78
  'data-style-disabled': disableStyle ? '' : undefined,
@@ -82,24 +81,24 @@ export function Icon({ disableStyle, children, className, ...props }) {
82
81
  });
83
82
  }
84
83
  export function Title({ disableStyle, className, ...props }) {
85
- const { tone } = useContext(BannerContext);
86
- return (_jsx("h2", { ...props, "data-tone": tone, "data-component": "banner-title", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
84
+ const context = useContext(BannerContext);
85
+ return (_jsx("h2", { ...props, "data-tone": context.tone, "data-component": "banner-title", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
87
86
  }
87
+ /** Icon-only: put just a CloseButtonIcon inside, never text like "Close". Name it for screen readers with aria-label instead, e.g. aria-label="Dismiss". */
88
88
  export function CloseButton({ disableStyle, type = 'button', className, onClick, ...props }) {
89
- const { tone, onClose } = useContext(BannerContext);
90
- return (_jsx("button", { ...props, type: type, "data-tone": tone, onClick: (event) => {
89
+ const context = useContext(BannerContext);
90
+ return (_jsx("button", { ...props, type: type, "data-tone": context.tone, onClick: (event) => {
91
91
  onClick?.(event);
92
92
  if (!event.defaultPrevented)
93
- onClose?.();
93
+ context.onClose?.();
94
94
  }, "data-component": "banner-closebutton", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
95
95
  }
96
96
  /** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
97
97
  export function CloseButtonIcon({ disableStyle, children = _jsx(X, {}), className, ...props }) {
98
- const { tone } = useContext(BannerContext);
98
+ const context = useContext(BannerContext);
99
99
  return cloneElement(children, {
100
- ...children.props,
101
100
  ...props,
102
- 'data-tone': tone,
101
+ 'data-tone': context.tone,
103
102
  ...{
104
103
  'data-component': 'banner-closebuttonicon',
105
104
  'data-style-disabled': disableStyle ? '' : undefined,
@@ -109,11 +108,10 @@ export function CloseButtonIcon({ disableStyle, children = _jsx(X, {}), classNam
109
108
  });
110
109
  }
111
110
  export function Body({ disableStyle, className, ...props }) {
112
- const { tone } = useContext(BannerContext);
113
- return (_jsx("div", { ...props, "data-tone": tone, "data-component": "banner-body", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
111
+ const context = useContext(BannerContext);
112
+ return (_jsx("div", { ...props, "data-tone": context.tone, "data-component": "banner-body", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
114
113
  }
115
114
  export function Description({ disableStyle, className, ...props }) {
116
- const { tone } = useContext(BannerContext);
117
- return (_jsx("div", { ...props, "data-tone": tone, "data-component": "banner-description", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
115
+ const context = useContext(BannerContext);
116
+ return (_jsx("div", { ...props, "data-tone": context.tone, "data-component": "banner-description", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
118
117
  }
119
- //# sourceMappingURL=index.js.map