@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
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { asChildRendering } from "../../utils/asChild.js";
2
3
  import { Select as BaseSelect } from '@base-ui/react/select';
3
- import { Check, ChevronDown, ChevronUp, ChevronsUpDown } from 'lucide-react';
4
- import { cloneElement, createContext, forwardRef, useContext, useId, useState, } from 'react';
5
- import { ToneProvider, useToneContext } from "../../utils/Tone.js";
4
+ import { Check, ChevronDown, ChevronUp, ChevronsUpDown } from "../../utils/icons.js";
5
+ import { cloneElement, createContext, forwardRef, useContext, useEffect, useId, useState, } from 'react';
6
+ import { readValidation, validationAttributes, validationMessageContent } from "../../utils/Validation.js";
6
7
  /**
7
8
  * Prepare groups in items. A flat-looking list is one group with an empty label and no GroupLabel; keep Group around ItemsList. OpenButtonValue already formats the selection: omit children unless a custom display is needed. Keep ScrollArea → GroupsList → Group → ItemsList → Item in Popup.
8
9
  *
@@ -88,22 +89,29 @@ import { ToneProvider, useToneContext } from "../../utils/Tone.js";
88
89
  * }
89
90
  * </Select.Root>
90
91
  */
91
- export function Root({ children, items, id, tone = 'neutral', open, defaultOpen = false, onOpenChange, ...props }) {
92
+ export function Root({ children, items, id, validation, defaultOpen = false, onOpenChange, ...props }) {
93
+ //1. Tracking the open state even when uncontrolled, so parts can carry data-open
94
+ const [openInternalState, setOpenInternalState] = useState(defaultOpen);
95
+ //2. Holding the ids of Description, Error and Success, so OpenButton announces them to screen readers through aria-describedby
96
+ const [describedByIds, setDescribedByIds] = useState([]);
97
+ //3. Sharing everything with the parts
92
98
  const generatedId = useId();
93
99
  const inputId = id ?? generatedId;
94
- const [openInternalState, setOpenInternalState] = useState(defaultOpen);
95
- return (_jsx(BaseSelect.Root, { ...props, items: items, id: inputId, open: open, defaultOpen: defaultOpen, isItemEqualToValue: (item, selected) => item.value === selected.value, onOpenChange: (nextOpen, details) => {
100
+ return (_jsx(BaseSelect.Root, { ...props, items: items, id: inputId, defaultOpen: defaultOpen, isItemEqualToValue: (item, selected) => item.value === selected.value, onOpenChange: (nextOpen, details) => {
96
101
  onOpenChange?.(nextOpen, details);
97
102
  if (!details.isCanceled)
98
103
  setOpenInternalState(nextOpen);
99
104
  }, children: _jsx(SelectContext.Provider, { value: {
100
105
  inputId,
101
106
  groups: items,
102
- open: open ?? openInternalState,
107
+ open: props.open ?? openInternalState,
103
108
  disabled: props.disabled ?? false,
104
109
  readOnly: props.readOnly ?? false,
105
110
  required: props.required ?? false,
106
- }, children: _jsx(ToneProvider, { value: tone, children: children }) }) }));
111
+ validation: readValidation(validation),
112
+ describedByIds,
113
+ setDescribedByIds,
114
+ }, children: children }) }));
107
115
  }
108
116
  export const Container = /* @__PURE__ */ forwardRef(function Container({ disableStyle, className, ...props }, ref) {
109
117
  return (_jsx("div", { ...props, ref: ref, "data-component": "select-container", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
@@ -117,14 +125,14 @@ export const Value = BaseSelect.Value;
117
125
  export function OpenButtonValue({ disableStyle, className, ...props }) {
118
126
  return (_jsx(BaseSelect.Value, { ...props, "data-component": "select-openbuttonvalue", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
119
127
  }
120
- export const ScrollArea = /* @__PURE__ */ forwardRef(function ScrollArea({ disableStyle, className, style, ...props }, ref) {
121
- return (_jsx(BaseSelect.List, { ...props, ref: ref, style: style, "data-component": "select-scrollarea", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
128
+ export const ScrollArea = /* @__PURE__ */ forwardRef(function ScrollArea({ disableStyle, className, ...props }, ref) {
129
+ return (_jsx(BaseSelect.List, { ...props, ref: ref, "data-component": "select-scrollarea", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
122
130
  });
123
131
  /** Let this list render the groups. Manually annotate its children callback with Select.GroupType<typeof rootItems>, using the SAME items variable passed to Root. */
124
- export function GroupsList({ disableStyle, children, className, style, ...props }) {
125
- const { groups } = useSelectContext();
126
- return (_jsx("div", { ...props, style: style, "data-component": "select-groupslist", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: typeof children === 'function'
127
- ? groups.map((group, index) => children(group, index))
132
+ export function GroupsList({ disableStyle, children, className, ...props }) {
133
+ const context = useSelectContext();
134
+ return (_jsx("div", { ...props, "data-component": "select-groupslist", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: typeof children === 'function'
135
+ ? context.groups.map((group, index) => children(group, index))
128
136
  : children }));
129
137
  }
130
138
  /** Let this list render the surrounding group. Manually annotate its callback with Select.ItemType<typeof rootItems>, using the SAME items variable passed to Root. */
@@ -151,13 +159,11 @@ export function Popup({ disableStyle, container, anchor, positionMethod, side =
151
159
  export const Arrow = /* @__PURE__ */ forwardRef(function Arrow({ disableStyle, className, style, ...props }, ref) {
152
160
  return (_jsxs(BaseSelect.Arrow, { style: style, render: _jsx("svg", { ...props, ref: ref, "aria-hidden": true, width: "20", height: "10", viewBox: "0 0 20 10" }), "data-component": "select-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": "select-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": "select-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": "select-arrow-3" })] }));
153
161
  });
154
- /** Behavior only: give your child control this action. Style the child itself; this wrapper has no preset appearance or disableStyle prop. */
155
- export const PopupOpenHandler = /* @__PURE__ */ forwardRef(function PopupOpenHandler({ children, ...props }, ref) {
156
- return _jsx(BaseSelect.Trigger, { ...props, ref: ref, render: children });
157
- });
158
- export const OpenButton = /* @__PURE__ */ forwardRef(function OpenButton({ disableStyle, className, ...props }, ref) {
159
- const tone = useToneContext();
160
- return (_jsx(BaseSelect.Trigger, { "data-tone": tone, ...props, ref: ref, "data-component": "select-openbutton", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
162
+ /** Opens the select. Pass asChild to make your own button the trigger instead, like a "Sort" Button. */
163
+ export const OpenButton = /* @__PURE__ */ forwardRef(function OpenButton({ asChild, disableStyle, children, 'aria-describedby': describedBy, ...props }, ref) {
164
+ const context = useSelectContext();
165
+ const rendering = asChildRendering({ asChild, children, component: 'select-openbutton', disableStyle });
166
+ return _jsx(BaseSelect.Trigger, { ...validationAttributes(context.validation), "aria-invalid": context.validation.state === 'error' || props['aria-invalid'] || undefined, "aria-describedby": [describedBy, ...context.describedByIds].filter(Boolean).join(' ') || undefined, ...props, ref: ref, ...rendering });
161
167
  });
162
168
  /** Omit for an unlabeled/flat-looking group; keep the Group wrapper. Supply the heading only when grouping should be visible. */
163
169
  export const GroupLabel = /* @__PURE__ */ forwardRef(function GroupLabel({ disableStyle, className, ...props }, ref) {
@@ -169,19 +175,32 @@ export const Separator = /* @__PURE__ */ forwardRef(function Separator({ disable
169
175
  export const ItemText = /* @__PURE__ */ forwardRef(function ItemText({ disableStyle, className, ...props }, ref) {
170
176
  return (_jsx(BaseSelect.ItemText, { ...props, ref: ref, "data-component": "select-itemtext", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
171
177
  });
172
- export const Description = /* @__PURE__ */ forwardRef(function Description({ disableStyle, className, ...props }, ref) {
178
+ export const Description = /* @__PURE__ */ forwardRef(function Description({ disableStyle, className, id, ...props }, ref) {
179
+ const describedById = useDescribedById(id);
173
180
  const attributes = usePartAttributes();
174
- return (_jsx("div", { ...attributes, ...props, ref: ref, "data-component": "select-description", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
181
+ return (_jsx("div", { ...attributes, ...props, id: describedById, ref: ref, "data-component": "select-description", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
175
182
  });
176
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
177
- export const Error = /* @__PURE__ */ forwardRef(function Error({ disableStyle, className, ...props }, ref) {
178
- const attributes = usePartAttributes();
179
- return (_jsx("div", { role: "alert", "aria-atomic": "true", ...attributes, ...props, ref: ref, "data-component": "select-error", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
183
+ /** 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. */
184
+ export const Error = /* @__PURE__ */ forwardRef(function Error({ children, ...props }, ref) {
185
+ const context = useSelectContext();
186
+ const content = validationMessageContent(context.validation, 'error', children);
187
+ if (content === undefined)
188
+ return null;
189
+ return _jsx(Message, { ...props, ref: ref, role: "alert", component: "select-error", children: content });
180
190
  });
181
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
182
- export const Success = /* @__PURE__ */ forwardRef(function Success({ disableStyle, className, ...props }, ref) {
191
+ /** 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. */
192
+ export const Success = /* @__PURE__ */ forwardRef(function Success({ children, ...props }, ref) {
193
+ const context = useSelectContext();
194
+ const content = validationMessageContent(context.validation, 'success', children);
195
+ if (content === undefined)
196
+ return null;
197
+ return _jsx(Message, { ...props, ref: ref, role: "status", component: "select-success", children: content });
198
+ });
199
+ // The shared body of Error and Success, mounted only while they show, so only visible messages describe the select
200
+ const Message = /* @__PURE__ */ forwardRef(function Message({ disableStyle, className, id, component, ...props }, ref) {
201
+ const describedById = useDescribedById(id);
183
202
  const attributes = usePartAttributes();
184
- return (_jsx("div", { role: "status", "aria-atomic": "true", ...attributes, ...props, ref: ref, "data-component": "select-success", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
203
+ return _jsx("div", { "aria-atomic": "true", ...attributes, ...props, id: describedById, ref: ref, "data-component": component, "data-style-disabled": disableStyle ? '' : undefined, className: className });
185
204
  });
186
205
  /** Built-in icon; no children needed. Use it inside its matching control. */
187
206
  export const OpenButtonIcon = /* @__PURE__ */ forwardRef(function OpenButtonIcon({ disableStyle, className, strokeWidth = 1.5, ...props }, ref) {
@@ -220,15 +239,25 @@ function useSelectContext() {
220
239
  throw new globalThis.Error('Select parts must be inside Select.Root');
221
240
  return context;
222
241
  }
242
+ // The state attributes every part carries, so presets can style any part from Root's state
223
243
  function usePartAttributes() {
224
- const { open, disabled, readOnly, required } = useSelectContext();
225
- const tone = useToneContext();
244
+ const context = useSelectContext();
226
245
  return {
227
- 'data-open': open ? '' : undefined,
228
- 'data-disabled': disabled ? '' : undefined,
229
- 'data-readonly': readOnly ? '' : undefined,
230
- 'data-required': required ? '' : undefined,
231
- 'data-tone': tone,
246
+ 'data-open': context.open ? '' : undefined,
247
+ 'data-disabled': context.disabled ? '' : undefined,
248
+ 'data-readonly': context.readOnly ? '' : undefined,
249
+ 'data-required': context.required ? '' : undefined,
250
+ ...validationAttributes(context.validation),
232
251
  };
233
252
  }
234
- //# sourceMappingURL=index.js.map
253
+ // Registering a part's id in OpenButton's aria-describedby while the part is mounted
254
+ function useDescribedById(id) {
255
+ const context = useSelectContext();
256
+ const generatedId = useId();
257
+ const describedById = id ?? generatedId;
258
+ useEffect(() => {
259
+ context.setDescribedByIds((current) => [...current, describedById]);
260
+ return () => context.setDescribedByIds((current) => current.filter((currentId) => currentId !== describedById));
261
+ }, [describedById, context.setDescribedByIds]);
262
+ return describedById;
263
+ }
@@ -16,4 +16,3 @@ import type { HTMLAttributes } from 'react';
16
16
  * }
17
17
  */
18
18
  export default function Skeleton({ disableStyle, className, ...props }: HTMLAttributes<HTMLDivElement> & StyleProps): import("react").JSX.Element;
19
- //# sourceMappingURL=index.d.ts.map
@@ -17,4 +17,3 @@ import { jsx as _jsx } from "react/jsx-runtime";
17
17
  export default function Skeleton({ disableStyle, className, ...props }) {
18
18
  return (_jsx("div", { "data-component": "skeleton-skeleton", "data-style-disabled": disableStyle ? '' : undefined, className: className, ...props }));
19
19
  }
20
- //# sourceMappingURL=index.js.map
@@ -1,9 +1,11 @@
1
1
  import type { StyleProps } from '../../types/Style.ts';
2
2
  import { Slider as BaseSlider } from '@base-ui/react/slider';
3
- import type { ReactNode } from 'react';
3
+ import type { ComponentProps, ReactNode } from 'react';
4
+ import type { Validation } from '../../types/Validation.ts';
5
+ import type { ValidationMessageChildren } from '../../utils/Validation.ts';
4
6
  export type RootProps<Value extends number | readonly number[] = number | readonly number[]> = Omit<BaseSlider.Root.Props<Value>, 'render' | 'className'> & {
5
- /** Choose the visual tone. This does not validate data or show/hide feedback messages. */
6
- tone?: 'neutral' | 'valid' | 'invalid';
7
+ /** The slider's validation state, with an optional message: `'error'` styles it as invalid, `['error', 'Pick at least 10']` also shows that message in Error. Same for `'success'` and Success. Omit it for a neutral slider. */
8
+ validation?: Validation;
7
9
  };
8
10
  /**
9
11
  * Configure bounds and value on Root. Keep Track inside TrackGroup, then Indicator and indexed DragHandles inside Track. One handle adjusts a single value; a range needs a handle for each end. MarksList/Mark are optional labels, not interactive handles.
@@ -37,7 +39,7 @@ export type RootProps<Value extends number | readonly number[] = number | readon
37
39
  * <Slider.DragHandle index={1} aria-label="Maximum" />
38
40
  * </Slider.Track>
39
41
  */
40
- export declare function Root<Value extends number | readonly number[]>({ children, tone, ...props }: RootProps<Value>): import("react").JSX.Element;
42
+ export declare function Root<Value extends number | readonly number[]>({ children, validation, ...props }: RootProps<Value>): import("react").JSX.Element;
41
43
  export declare const Container: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
42
44
  export declare const Label: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").SliderLabelProps, "className"> & {
43
45
  className?: string;
@@ -65,8 +67,11 @@ export declare const Mark: import("react").ForwardRefExoticComponent<Omit<import
65
67
  value: number;
66
68
  } & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
67
69
  export declare const Description: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
68
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
69
- export declare const Error: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
70
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
71
- export declare const Success: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
72
- //# sourceMappingURL=index.d.ts.map
70
+ type MessageProps = Omit<ComponentProps<'div'>, 'children'> & StyleProps & {
71
+ children?: ValidationMessageChildren;
72
+ };
73
+ /** 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. */
74
+ export declare const Error: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
75
+ /** 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. */
76
+ export declare const Success: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
77
+ export {};
@@ -2,7 +2,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
2
2
  import { Slider as BaseSlider } from '@base-ui/react/slider';
3
3
  import { useDirection } from '@base-ui/react/direction-provider';
4
4
  import { Fragment as ReactFragment, createContext, useCallback, forwardRef, useContext, useEffect, useId, useState, } from 'react';
5
- import { ToneProvider, useToneContext } from "../../utils/Tone.js";
5
+ import { readValidation, validationAttributes, validationMessageContent } from "../../utils/Validation.js";
6
6
  /**
7
7
  * Configure bounds and value on Root. Keep Track inside TrackGroup, then Indicator and indexed DragHandles inside Track. One handle adjusts a single value; a range needs a handle for each end. MarksList/Mark are optional labels, not interactive handles.
8
8
  *
@@ -35,18 +35,17 @@ import { ToneProvider, useToneContext } from "../../utils/Tone.js";
35
35
  * <Slider.DragHandle index={1} aria-label="Maximum" />
36
36
  * </Slider.Track>
37
37
  */
38
- export function Root({ children, tone = 'neutral', ...props }) {
38
+ export function Root({ children, validation, ...props }) {
39
39
  const [messageIds, setMessageIds] = useState([]);
40
- return (_jsx(ToneProvider, { value: tone, children: _jsx(BaseSlider.Root, { ...props, render: (rootProps, state) => {
41
- const { children, ...elementProps } = rootProps;
42
- return (_jsx(SliderContext.Provider, { value: { elementProps, state, messageIds, setMessageIds }, children: _jsx(_Fragment, { children: children }) }));
43
- }, children: children }) }));
40
+ return (_jsx(BaseSlider.Root, { ...props, render: (rootProps, state) => {
41
+ const { children, ...elementProps } = rootProps;
42
+ return (_jsx(SliderContext.Provider, { value: { elementProps, state, messageIds, setMessageIds, validation: readValidation(validation) }, children: _jsx(_Fragment, { children: children }) }));
43
+ }, children: children }));
44
44
  }
45
45
  export const Container = /* @__PURE__ */ forwardRef(function Container({ disableStyle, ...props }, ref) {
46
46
  const context = useSliderContext();
47
- const tone = useToneContext();
48
47
  const { ref: nativeRef, ...nativeProps } = context.elementProps;
49
- return (_jsx("div", { ...nativeProps, ...props, ref: useRootRef(nativeRef, ref), "data-tone": tone, "data-component": "slider-container", "data-style-disabled": disableStyle ? '' : undefined, className: props.className }));
48
+ return (_jsx("div", { ...nativeProps, ...props, ref: useRootRef(nativeRef, ref), ...validationAttributes(context.validation), "data-component": "slider-container", "data-style-disabled": disableStyle ? '' : undefined, className: props.className }));
50
49
  });
51
50
  export const Label = /* @__PURE__ */ forwardRef(function Label({ disableStyle, className, ...props }, ref) {
52
51
  return (_jsx(BaseSlider.Label, { ...props, ref: ref, "data-component": "slider-label", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
@@ -61,53 +60,60 @@ export const Track = /* @__PURE__ */ forwardRef(function Track({ disableStyle, c
61
60
  return (_jsx(BaseSlider.Track, { ...props, ref: ref, "data-component": "slider-track", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
62
61
  });
63
62
  export const Indicator = /* @__PURE__ */ forwardRef(function Indicator({ disableStyle, className, ...props }, ref) {
64
- const tone = useToneContext();
65
- return (_jsx(BaseSlider.Indicator, { ...props, ref: ref, "data-tone": tone, "data-component": "slider-indicator", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
63
+ const context = useSliderContext();
64
+ return (_jsx(BaseSlider.Indicator, { ...props, ref: ref, ...validationAttributes(context.validation), "data-component": "slider-indicator", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
66
65
  });
67
66
  export const DragHandle = /* @__PURE__ */ forwardRef(function DragHandle({ disableStyle, className, ...props }, ref) {
68
- const { messageIds } = useSliderContext();
69
- return (_jsx(BaseSlider.Thumb, { ...props, ref: ref, "aria-describedby": [props['aria-describedby'], ...messageIds].filter(Boolean).join(' ') ||
67
+ const context = useSliderContext();
68
+ return (_jsx(BaseSlider.Thumb, { ...props, ref: ref, "aria-invalid": context.validation.state === 'error' || props['aria-invalid'] || undefined, "aria-describedby": [props['aria-describedby'], ...context.messageIds].filter(Boolean).join(' ') ||
70
69
  undefined, "data-component": "slider-draghandle", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
71
70
  });
72
71
  export const MarksList = /* @__PURE__ */ forwardRef(function MarksList({ disableStyle, children, className, ...props }, ref) {
73
- const { state } = useSliderContext();
74
- const count = Math.floor(Number(((state.max - state.min) / state.step).toPrecision(15))) +
72
+ const context = useSliderContext();
73
+ const count = Math.floor(Number(((context.state.max - context.state.min) / context.state.step).toPrecision(15))) +
75
74
  1;
76
- return (_jsx("div", { ...props, ref: ref, "aria-hidden": true, "data-orientation": state.orientation, "data-component": "slider-markslist", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: Array.from({ length: count }, (_, index) => {
77
- const value = Number((state.min + index * state.step).toPrecision(15));
75
+ return (_jsx("div", { ...props, ref: ref, "aria-hidden": true, "data-orientation": context.state.orientation, "data-component": "slider-markslist", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: Array.from({ length: count }, (_, index) => {
76
+ const value = Number((context.state.min + index * context.state.step).toPrecision(15));
78
77
  return _jsx(ReactFragment, { children: children(value) }, value);
79
78
  }) }));
80
79
  });
81
80
  export const Mark = /* @__PURE__ */ forwardRef(function Mark({ disableStyle, value, children, className, style, ...props }, ref) {
82
- const { state } = useSliderContext();
81
+ const context = useSliderContext();
83
82
  const direction = useDirection();
84
- const percent = ((value - state.min) / (state.max - state.min)) * 100;
85
- return (_jsxs("div", { ...props, ref: ref, "aria-hidden": true, dir: direction, "data-orientation": state.orientation, style: {
86
- ...(state.orientation === 'vertical'
83
+ const percent = ((value - context.state.min) / (context.state.max - context.state.min)) * 100;
84
+ return (_jsxs("div", { ...props, ref: ref, "aria-hidden": true, dir: direction, "data-orientation": context.state.orientation, style: {
85
+ ...(context.state.orientation === 'vertical'
87
86
  ? { bottom: percent + '%' }
88
87
  : { insetInlineStart: percent + '%' }),
89
88
  ...style,
90
- }, "data-component": "slider-mark", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: [_jsx("span", { "data-component": "slider-mark-1", "data-orientation": state.orientation }), children != null && (_jsx("span", { "data-orientation": state.orientation, "data-component": "slider-mark-2", children: children }))] }));
89
+ }, "data-component": "slider-mark", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: [_jsx("span", { "data-component": "slider-mark-1", "data-orientation": context.state.orientation }), children != null && (_jsx("span", { "data-orientation": context.state.orientation, "data-component": "slider-mark-2", children: children }))] }));
91
90
  });
92
91
  export const Description = /* @__PURE__ */ forwardRef(function Description({ disableStyle, className, id, ...props }, ref) {
93
92
  const messageId = useMessageId(id);
94
93
  const context = useSliderContext();
95
- const tone = useToneContext();
96
- return (_jsx("div", { ...props, ref: ref, id: messageId, "data-disabled": context.state.disabled ? '' : undefined, "data-tone": tone, "data-component": "slider-description", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
94
+ return (_jsx("div", { ...props, ref: ref, id: messageId, "data-disabled": context.state.disabled ? '' : undefined, ...validationAttributes(context.validation), "data-component": "slider-description", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
97
95
  });
98
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
99
- export const Error = /* @__PURE__ */ forwardRef(function Error({ disableStyle, className, id, ...props }, ref) {
100
- const messageId = useMessageId(id);
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 = useSliderContext();
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: "slider-error", children: content });
103
+ });
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) {
101
106
  const context = useSliderContext();
102
- const tone = useToneContext();
103
- return (_jsx("div", { role: "alert", "aria-atomic": "true", ...props, ref: ref, id: messageId, "data-disabled": context.state.disabled ? '' : undefined, "data-tone": tone, "data-component": "slider-error", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
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: "slider-success", children: content });
104
111
  });
105
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
106
- export const Success = /* @__PURE__ */ forwardRef(function Success({ disableStyle, className, id, ...props }, ref) {
112
+ // The shared body of Error and Success, mounted only while they show, so only visible messages describe the slider
113
+ const Message = /* @__PURE__ */ forwardRef(function Message({ disableStyle, className, id, component, ...props }, ref) {
107
114
  const messageId = useMessageId(id);
108
115
  const context = useSliderContext();
109
- const tone = useToneContext();
110
- return (_jsx("div", { role: "status", "aria-atomic": "true", ...props, ref: ref, id: messageId, "data-disabled": context.state.disabled ? '' : undefined, "data-tone": tone, "data-component": "slider-success", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
116
+ return _jsx("div", { "aria-atomic": "true", ...props, ref: ref, id: messageId, "data-disabled": context.state.disabled ? '' : undefined, ...validationAttributes(context.validation), "data-component": component, "data-style-disabled": disableStyle ? '' : undefined, className: className });
111
117
  });
112
118
  const SliderContext = /* @__PURE__ */ createContext(null);
113
119
  function useSliderContext() {
@@ -119,41 +125,36 @@ function useSliderContext() {
119
125
  function useMessageId(id) {
120
126
  const generatedId = useId();
121
127
  const messageId = id ?? generatedId;
122
- const { setMessageIds } = useSliderContext();
128
+ const context = useSliderContext();
123
129
  useEffect(() => {
124
- setMessageIds((current) => [...current, messageId]);
125
- return () => setMessageIds((current) => current.filter((value) => value !== messageId));
126
- }, [messageId, setMessageIds]);
130
+ context.setMessageIds((current) => [...current, messageId]);
131
+ return () => context.setMessageIds((current) => current.filter((value) => value !== messageId));
132
+ }, [messageId, context.setMessageIds]);
127
133
  return messageId;
128
134
  }
135
+ // Merging Base UI's ref with the consumer's one onto the same element
129
136
  function useRootRef(nativeRef, forwardedRef) {
130
137
  return useCallback((element) => {
131
- const nativeCleanup = typeof nativeRef === 'function'
132
- ? nativeRef(element)
133
- : nativeRef
134
- ? ((nativeRef.current = element), undefined)
135
- : undefined;
136
- const forwardedCleanup = typeof forwardedRef === 'function'
137
- ? forwardedRef(element)
138
- : forwardedRef
139
- ? ((forwardedRef.current = element), undefined)
140
- : undefined;
141
- if (typeof nativeCleanup === 'function' ||
142
- typeof forwardedCleanup === 'function')
143
- return () => {
144
- if (typeof nativeCleanup === 'function')
145
- nativeCleanup();
146
- else if (typeof nativeRef === 'function')
147
- nativeRef(null);
148
- else if (nativeRef)
149
- nativeRef.current = null;
150
- if (typeof forwardedCleanup === 'function')
151
- forwardedCleanup();
152
- else if (typeof forwardedRef === 'function')
153
- forwardedRef(null);
154
- else if (forwardedRef)
155
- forwardedRef.current = null;
156
- };
138
+ const refs = [nativeRef, forwardedRef];
139
+ //1. Setting both refs, keeping the cleanups that callback refs may return
140
+ const cleanups = refs.map((ref) => {
141
+ if (typeof ref === 'function')
142
+ return ref(element);
143
+ if (ref)
144
+ ref.current = element;
145
+ return undefined;
146
+ });
147
+ //2. Returning a cleanup only when a ref asked for one, since React then stops calling refs with null itself
148
+ if (!cleanups.some((cleanup) => typeof cleanup === 'function'))
149
+ return;
150
+ return () => refs.forEach((ref, index) => {
151
+ const cleanup = cleanups[index];
152
+ if (typeof cleanup === 'function')
153
+ return cleanup();
154
+ if (typeof ref === 'function')
155
+ return ref(null);
156
+ if (ref)
157
+ ref.current = null;
158
+ });
157
159
  }, [nativeRef, forwardedRef]);
158
160
  }
159
- //# sourceMappingURL=index.js.map
@@ -10,5 +10,4 @@ import type { SVGIconProps } from '../../types/Icon.ts';
10
10
  * return <Spinner.Spinner />
11
11
  * }
12
12
  */
13
- export declare function Spinner({ disableStyle, className, ...props }: SVGIconProps & StyleProps): import("react").JSX.Element;
14
- //# sourceMappingURL=index.d.ts.map
13
+ export declare function Spinner({ disableStyle, className, children, ...props }: SVGIconProps & StyleProps): import("react").JSX.Element;
@@ -9,7 +9,6 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
9
9
  * return <Spinner.Spinner />
10
10
  * }
11
11
  */
12
- export function Spinner({ disableStyle, className, ...props }) {
13
- return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", "data-component": "spinner-spinner", "data-style-disabled": disableStyle ? '' : undefined, className: className, strokeWidth: 3, ...props, children: [_jsx("circle", { cx: 12, cy: 12, r: 10, "data-component": "spinner-track" }), _jsx("circle", { cx: 12, cy: 12, r: 10, pathLength: 1, "data-component": "spinner-indicator" }), props.children] }));
12
+ export function Spinner({ disableStyle, className, children, ...props }) {
13
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeLinecap: "round", strokeLinejoin: "round", "data-component": "spinner-spinner", "data-style-disabled": disableStyle ? '' : undefined, className: className, strokeWidth: 3, ...props, children: [_jsx("circle", { cx: 12, cy: 12, r: 10, "data-component": "spinner-track" }), _jsx("circle", { cx: 12, cy: 12, r: 10, pathLength: 1, "data-component": "spinner-indicator" }), children] }));
14
14
  }
15
- //# sourceMappingURL=index.js.map
@@ -42,8 +42,7 @@ export type RootProps = Pick<GroupProps, CoreKeys> & {
42
42
  */
43
43
  export declare function Root({ children, orientation, ...props }: RootProps): import("react").JSX.Element;
44
44
  export type ContentListProps = Omit<GroupProps, CoreKeys> & StyleProps;
45
- export declare function ContentList({ disableStyle, className, ...props }: ContentListProps & StyleProps): import("react").JSX.Element;
45
+ export declare function ContentList({ disableStyle, className, ...props }: ContentListProps): import("react").JSX.Element;
46
46
  export declare function Content({ disableStyle, className, ...props }: PanelProps & StyleProps): import("react").JSX.Element;
47
47
  export declare function Separator({ disableStyle, className, ...props }: SeparatorProps & StyleProps): import("react").JSX.Element;
48
48
  export declare function Handle({ disableStyle, className, children, ...props }: ComponentProps<'div'> & StyleProps): import("react").JSX.Element;
49
- //# sourceMappingURL=index.d.ts.map
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Group as ResizableGroup, Panel as ResizablePanel, Separator as ResizableSeparator, } from 'react-resizable-panels';
3
3
  import { createContext, useContext } from 'react';
4
- import { GripVertical } from 'lucide-react';
4
+ import { GripVertical } from "../../utils/icons.js";
5
5
  export { useGroupRef, useGroupCallbackRef, usePanelRef, usePanelCallbackRef, } from 'react-resizable-panels';
6
6
  // Only configuration lives here. ContentList renders the measured native Group.
7
7
  /**
@@ -49,13 +49,13 @@ export function Content({ disableStyle, className, ...props }) {
49
49
  return (_jsx(ResizablePanel, { ...props, "data-component": "splitter-content", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
50
50
  }
51
51
  export function Separator({ disableStyle, className, ...props }) {
52
- const { orientation } = useSplitterContext();
53
- return (_jsx(ResizableSeparator, { ...props, "data-orientation": orientation, "data-component": "splitter-separator", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
52
+ const context = useSplitterContext();
53
+ return (_jsx(ResizableSeparator, { ...props, "data-orientation": context.orientation, "data-component": "splitter-separator", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
54
54
  }
55
55
  // Native Separator explicitly supports children for a custom grip; all resize behavior stays native.
56
56
  export function Handle({ disableStyle, className, children = (_jsx(GripVertical, { "data-component": "splitter-handle-1", strokeWidth: 2, "aria-hidden": true })), ...props }) {
57
- const { orientation } = useSplitterContext();
58
- return (_jsx("div", { ...props, "data-orientation": orientation, "data-component": "splitter-handle", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: children }));
57
+ const context = useSplitterContext();
58
+ return (_jsx("div", { ...props, "data-orientation": context.orientation, "data-component": "splitter-handle", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: children }));
59
59
  }
60
60
  const SplitterContext = /* @__PURE__ */ createContext(null);
61
61
  function useSplitterContext() {
@@ -64,4 +64,3 @@ function useSplitterContext() {
64
64
  throw new Error('Splitter parts must be inside Splitter.Root');
65
65
  return context;
66
66
  }
67
- //# sourceMappingURL=index.js.map
@@ -1,12 +1,11 @@
1
1
  import type { StyleProps } from '../../types/Style.ts';
2
2
  import type { UseStepsProps } from '@ark-ui/react/steps';
3
3
  import { Steps } from '@ark-ui/react/steps';
4
- import type { ReactElement } from 'react';
5
4
  export declare function useSteps(props: UseStepsProps): import("@ark-ui/react/steps").UseStepsReturn;
6
5
  export { useStepsContext } from '@ark-ui/react/steps';
7
6
  export { useStepsItemContext } from '@ark-ui/react/steps';
8
7
  /**
9
- * Root owns the active step. Keep each Item in List with its index, and match Content indices to those items. NextHandler/PreviousHandler supply navigation to your buttons. Indicator reflects progress automatically; CompletedContent is shown after the last step.
8
+ * Root owns the active step. Keep each Item in List with its index, and match Content indices to those items. NextButton/PreviousButton navigate between steps; pass asChild to give their behavior to your own buttons instead. Indicator reflects progress automatically; CompletedContent is shown after the last step.
10
9
  *
11
10
  * @example Complete composition
12
11
  * import { Button, Stepper } from '@central-ui/react'
@@ -35,16 +34,12 @@ export { useStepsItemContext } from '@ark-ui/react/steps';
35
34
  * <Stepper.Content index={1}>Check everything.</Stepper.Content>
36
35
  * <Stepper.CompletedContent>Done.</Stepper.CompletedContent>
37
36
  * <div className="flex gap-2">
38
- * <Stepper.PreviousHandler>
39
- * <Button.default variant="secondary" size="small">
40
- * Previous
41
- * </Button.default>
42
- * </Stepper.PreviousHandler>
43
- * <Stepper.NextHandler>
37
+ * <Stepper.PreviousButton>Previous</Stepper.PreviousButton>
38
+ * <Stepper.NextButton asChild>
44
39
  * <Button.default variant="primary" size="small">
45
40
  * Next
46
41
  * </Button.default>
47
- * </Stepper.NextHandler>
42
+ * </Stepper.NextButton>
48
43
  * </div>
49
44
  * </div>
50
45
  * </div>
@@ -61,16 +56,10 @@ export { useStepsItemContext } from '@ark-ui/react/steps';
61
56
  * </Stepper.Root>
62
57
  */
63
58
  export declare function Root({ children, className, orientation, ...props }: Omit<Steps.RootProps, 'asChild'>): import("react").JSX.Element;
64
- /** Behavior only: give your child control this action. Style the child itself; this wrapper has no preset appearance or disableStyle prop. */
65
- export declare function NextHandler({ children, ...props }: Omit<Steps.NextTriggerProps, 'asChild' | 'children'> & {
66
- /** Supply your own accessible control. It receives the behavior; its own className owns the appearance. */
67
- children: ReactElement;
68
- }): import("react").JSX.Element;
69
- /** Behavior only: give your child control this action. Style the child itself; this wrapper has no preset appearance or disableStyle prop. */
70
- export declare function PreviousHandler({ children, ...props }: Omit<Steps.PrevTriggerProps, 'asChild' | 'children'> & {
71
- /** Supply your own accessible control. It receives the behavior; its own className owns the appearance. */
72
- children: ReactElement;
73
- }): import("react").JSX.Element;
59
+ /** Moves to the next step. Pass asChild to give this behavior to your own button, like a "Continue" Button; it keeps the state data attributes but none of this part's styling. */
60
+ export declare function NextButton({ asChild, disableStyle, ...props }: Steps.NextTriggerProps & StyleProps): import("react").JSX.Element;
61
+ /** Moves to the previous step. Pass asChild to give this behavior to your own button, like a "Back" Button; it keeps the state data attributes but none of this part's styling. */
62
+ export declare function PreviousButton({ asChild, disableStyle, ...props }: Steps.PrevTriggerProps & StyleProps): import("react").JSX.Element;
74
63
  export declare function List({ disableStyle, className, ...props }: Steps.ListProps & StyleProps): import("react").JSX.Element;
75
64
  export declare function Item({ disableStyle, className, ...props }: Steps.ItemProps & StyleProps): import("react").JSX.Element;
76
65
  /** 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. */
@@ -79,4 +68,3 @@ export declare function Separator({ disableStyle, className, ...props }: Steps.S
79
68
  export declare function Content({ disableStyle, className, ...props }: Steps.ContentProps & StyleProps): import("react").JSX.Element;
80
69
  export declare function CompletedContent({ disableStyle, className, ...props }: Steps.CompletedContentProps & StyleProps): import("react").JSX.Element;
81
70
  export declare function OpenButton({ disableStyle, className, ...props }: Steps.TriggerProps & StyleProps): import("react").JSX.Element;
82
- //# sourceMappingURL=index.d.ts.map