@central-ui/react 0.1.1 → 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 (281) hide show
  1. package/LICENSE +49 -0
  2. package/README.md +1 -1
  3. package/dist/components/accordion/index.d.ts +7 -6
  4. package/dist/components/accordion/index.js +13 -10
  5. package/dist/components/autocomplete/index.d.ts +22 -33
  6. package/dist/components/autocomplete/index.js +90 -73
  7. package/dist/components/avatar/index.d.ts +1 -2
  8. package/dist/components/avatar/index.js +6 -6
  9. package/dist/components/badge/index.d.ts +0 -1
  10. package/dist/components/badge/index.js +2 -2
  11. package/dist/components/banner/index.d.ts +1 -1
  12. package/dist/components/banner/index.js +24 -26
  13. package/dist/components/barchart/index.d.ts +106 -0
  14. package/dist/components/barchart/index.js +122 -0
  15. package/dist/components/breadcrumb/index.d.ts +0 -1
  16. package/dist/components/breadcrumb/index.js +6 -7
  17. package/dist/components/button/index.d.ts +3 -4
  18. package/dist/components/button/index.js +11 -12
  19. package/dist/components/card/index.d.ts +0 -1
  20. package/dist/components/card/index.js +0 -1
  21. package/dist/components/checkbox/index.d.ts +13 -11
  22. package/dist/components/checkbox/index.js +59 -39
  23. package/dist/components/chip/index.d.ts +1 -1
  24. package/dist/components/chip/index.js +2 -3
  25. package/dist/components/combobox/index.d.ts +32 -44
  26. package/dist/components/combobox/index.js +112 -88
  27. package/dist/components/datepicker/index.d.ts +54 -55
  28. package/dist/components/datepicker/index.js +105 -100
  29. package/dist/components/dialog/index.d.ts +17 -30
  30. package/dist/components/dialog/index.js +25 -26
  31. package/dist/components/divider/index.d.ts +0 -1
  32. package/dist/components/divider/index.js +0 -1
  33. package/dist/components/donutchart/index.d.ts +100 -0
  34. package/dist/components/donutchart/index.js +178 -0
  35. package/dist/components/drawer/index.d.ts +15 -24
  36. package/dist/components/drawer/index.js +45 -47
  37. package/dist/components/empty/index.d.ts +1 -2
  38. package/dist/components/empty/index.js +2 -4
  39. package/dist/components/fileupload/index.d.ts +4 -9
  40. package/dist/components/fileupload/index.js +27 -39
  41. package/dist/components/form/index.d.ts +0 -1
  42. package/dist/components/form/index.js +0 -1
  43. package/dist/components/horizontalbarchart/index.d.ts +120 -0
  44. package/dist/components/horizontalbarchart/index.js +193 -0
  45. package/dist/components/input/index.d.ts +23 -23
  46. package/dist/components/input/index.js +86 -115
  47. package/dist/components/linechart/index.d.ts +114 -0
  48. package/dist/components/linechart/index.js +139 -0
  49. package/dist/components/menu/index.d.ts +14 -16
  50. package/dist/components/menu/index.js +56 -53
  51. package/dist/components/metric/index.d.ts +0 -1
  52. package/dist/components/metric/index.js +0 -1
  53. package/dist/components/numberinput/index.d.ts +16 -23
  54. package/dist/components/numberinput/index.js +55 -68
  55. package/dist/components/otpinput/index.d.ts +14 -9
  56. package/dist/components/otpinput/index.js +32 -25
  57. package/dist/components/page/index.d.ts +0 -1
  58. package/dist/components/page/index.js +2 -4
  59. package/dist/components/passwordinput/index.d.ts +16 -13
  60. package/dist/components/passwordinput/index.js +47 -56
  61. package/dist/components/popover/index.d.ts +21 -19
  62. package/dist/components/popover/index.js +40 -21
  63. package/dist/components/radio/index.d.ts +13 -9
  64. package/dist/components/radio/index.js +80 -71
  65. package/dist/components/ratinginput/index.d.ts +15 -10
  66. package/dist/components/ratinginput/index.js +38 -18
  67. package/dist/components/select/index.d.ts +29 -32
  68. package/dist/components/select/index.js +79 -50
  69. package/dist/components/skeleton/index.d.ts +0 -1
  70. package/dist/components/skeleton/index.js +0 -1
  71. package/dist/components/slider/index.d.ts +14 -9
  72. package/dist/components/slider/index.js +75 -74
  73. package/dist/components/spinner/index.d.ts +2 -3
  74. package/dist/components/spinner/index.js +2 -3
  75. package/dist/components/splitter/index.d.ts +1 -2
  76. package/dist/components/splitter/index.js +6 -7
  77. package/dist/components/stepper/index.d.ts +8 -20
  78. package/dist/components/stepper/index.js +15 -16
  79. package/dist/components/switch/index.d.ts +12 -10
  80. package/dist/components/switch/index.js +52 -36
  81. package/dist/components/table/index.d.ts +3 -3
  82. package/dist/components/table/index.js +17 -16
  83. package/dist/components/tabs/index.d.ts +3 -4
  84. package/dist/components/tabs/index.js +6 -7
  85. package/dist/components/textarea/index.d.ts +16 -13
  86. package/dist/components/textarea/index.js +46 -55
  87. package/dist/components/textlink/index.d.ts +3 -1
  88. package/dist/components/textlink/index.js +4 -1
  89. package/dist/components/toast/index.d.ts +8 -14
  90. package/dist/components/toast/index.js +54 -54
  91. package/dist/components/toggle/index.d.ts +5 -6
  92. package/dist/components/toggle/index.js +19 -26
  93. package/dist/components/tooltip/index.d.ts +11 -13
  94. package/dist/components/tooltip/index.js +14 -11
  95. package/dist/components/tour/index.d.ts +154 -0
  96. package/dist/components/tour/index.js +280 -0
  97. package/dist/index.d.ts +5 -2
  98. package/dist/index.js +5 -1
  99. package/dist/types/Icon.d.ts +10 -0
  100. package/dist/types/Icon.js +1 -0
  101. package/dist/types/Style.d.ts +0 -1
  102. package/dist/types/Style.js +0 -1
  103. package/dist/types/Tone.d.ts +0 -1
  104. package/dist/types/Tone.js +0 -1
  105. package/dist/types/Validation.d.ts +12 -0
  106. package/dist/types/Validation.js +1 -0
  107. package/dist/utils/ArkStateToDataAttributes.d.ts +0 -1
  108. package/dist/utils/ArkStateToDataAttributes.js +3 -2
  109. package/dist/utils/Tone.d.ts +0 -1
  110. package/dist/utils/Tone.js +1 -2
  111. package/dist/utils/Validation.d.ts +14 -0
  112. package/dist/utils/Validation.js +23 -0
  113. package/dist/utils/asChild.d.ts +41 -0
  114. package/dist/utils/asChild.js +15 -0
  115. package/dist/utils/icons.d.ts +24 -0
  116. package/dist/utils/icons.js +160 -0
  117. package/dist/utils/useForwardClickToInput.d.ts +0 -1
  118. package/dist/utils/useForwardClickToInput.js +4 -3
  119. package/dist/utils/virtualization/useVirtualizedAutocomplete.d.ts +0 -1
  120. package/dist/utils/virtualization/useVirtualizedAutocomplete.js +0 -1
  121. package/dist/utils/virtualization/useVirtualizedCombobox.d.ts +0 -1
  122. package/dist/utils/virtualization/useVirtualizedCombobox.js +0 -1
  123. package/dist/utils/virtualization/useVirtualizedTable.d.ts +0 -1
  124. package/dist/utils/virtualization/useVirtualizedTable.js +0 -1
  125. package/package.json +12 -11
  126. package/src/presets/shopify-polaris/shopify-polaris-autocomplete.css +15 -6
  127. package/src/presets/shopify-polaris/shopify-polaris-badge.css +1 -1
  128. package/src/presets/shopify-polaris/shopify-polaris-barchart.css +64 -0
  129. package/src/presets/shopify-polaris/shopify-polaris-checkbox.css +2 -2
  130. package/src/presets/shopify-polaris/shopify-polaris-chip.css +3 -3
  131. package/src/presets/shopify-polaris/shopify-polaris-combobox.css +19 -10
  132. package/src/presets/shopify-polaris/shopify-polaris-datepicker.css +20 -11
  133. package/src/presets/shopify-polaris/shopify-polaris-dialog.css +16 -0
  134. package/src/presets/shopify-polaris/shopify-polaris-donutchart.css +172 -0
  135. package/src/presets/shopify-polaris/shopify-polaris-drawer.css +16 -0
  136. package/src/presets/shopify-polaris/shopify-polaris-fileupload.css +1 -1
  137. package/src/presets/shopify-polaris/shopify-polaris-horizontalbarchart.css +60 -0
  138. package/src/presets/shopify-polaris/shopify-polaris-input.css +14 -5
  139. package/src/presets/shopify-polaris/shopify-polaris-linechart.css +68 -0
  140. package/src/presets/shopify-polaris/shopify-polaris-menu.css +47 -6
  141. package/src/presets/shopify-polaris/shopify-polaris-numberinput.css +16 -7
  142. package/src/presets/shopify-polaris/shopify-polaris-otpinput.css +3 -3
  143. package/src/presets/shopify-polaris/shopify-polaris-passwordinput.css +14 -5
  144. package/src/presets/shopify-polaris/shopify-polaris-popover.css +29 -0
  145. package/src/presets/shopify-polaris/shopify-polaris-radio.css +2 -2
  146. package/src/presets/shopify-polaris/shopify-polaris-ratinginput.css +2 -2
  147. package/src/presets/shopify-polaris/shopify-polaris-select.css +15 -6
  148. package/src/presets/shopify-polaris/shopify-polaris-slider.css +2 -2
  149. package/src/presets/shopify-polaris/shopify-polaris-stepper.css +16 -0
  150. package/src/presets/shopify-polaris/shopify-polaris-switch.css +2 -2
  151. package/src/presets/shopify-polaris/shopify-polaris-textarea.css +13 -4
  152. package/src/presets/shopify-polaris/shopify-polaris-toast.css +43 -0
  153. package/src/presets/shopify-polaris/shopify-polaris-tooltip.css +16 -0
  154. package/src/presets/shopify-polaris/shopify-polaris.css +5 -0
  155. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-autocomplete.css +2 -2
  156. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-barchart.css +64 -0
  157. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-checkbox.css +2 -2
  158. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-combobox.css +2 -2
  159. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-datepicker.css +2 -2
  160. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-dialog.css +9 -0
  161. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-donutchart.css +172 -0
  162. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-drawer.css +9 -0
  163. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-fileupload.css +1 -1
  164. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-horizontalbarchart.css +60 -0
  165. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-input.css +2 -2
  166. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-linechart.css +68 -0
  167. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-menu.css +9 -0
  168. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-numberinput.css +2 -2
  169. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-otpinput.css +2 -2
  170. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-passwordinput.css +2 -2
  171. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-popover.css +22 -0
  172. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-radio.css +2 -2
  173. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-ratinginput.css +2 -2
  174. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-slider.css +2 -2
  175. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-stepper.css +9 -0
  176. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-switch.css +2 -2
  177. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-textarea.css +2 -2
  178. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-tooltip.css +9 -0
  179. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy.css +4 -0
  180. package/dist/components/accordion/index.d.ts.map +0 -1
  181. package/dist/components/accordion/index.js.map +0 -1
  182. package/dist/components/autocomplete/index.d.ts.map +0 -1
  183. package/dist/components/autocomplete/index.js.map +0 -1
  184. package/dist/components/avatar/index.d.ts.map +0 -1
  185. package/dist/components/avatar/index.js.map +0 -1
  186. package/dist/components/badge/index.d.ts.map +0 -1
  187. package/dist/components/badge/index.js.map +0 -1
  188. package/dist/components/banner/index.d.ts.map +0 -1
  189. package/dist/components/banner/index.js.map +0 -1
  190. package/dist/components/breadcrumb/index.d.ts.map +0 -1
  191. package/dist/components/breadcrumb/index.js.map +0 -1
  192. package/dist/components/button/index.d.ts.map +0 -1
  193. package/dist/components/button/index.js.map +0 -1
  194. package/dist/components/card/index.d.ts.map +0 -1
  195. package/dist/components/card/index.js.map +0 -1
  196. package/dist/components/checkbox/index.d.ts.map +0 -1
  197. package/dist/components/checkbox/index.js.map +0 -1
  198. package/dist/components/chip/index.d.ts.map +0 -1
  199. package/dist/components/chip/index.js.map +0 -1
  200. package/dist/components/combobox/index.d.ts.map +0 -1
  201. package/dist/components/combobox/index.js.map +0 -1
  202. package/dist/components/datepicker/index.d.ts.map +0 -1
  203. package/dist/components/datepicker/index.js.map +0 -1
  204. package/dist/components/dialog/index.d.ts.map +0 -1
  205. package/dist/components/dialog/index.js.map +0 -1
  206. package/dist/components/divider/index.d.ts.map +0 -1
  207. package/dist/components/divider/index.js.map +0 -1
  208. package/dist/components/drawer/index.d.ts.map +0 -1
  209. package/dist/components/drawer/index.js.map +0 -1
  210. package/dist/components/empty/index.d.ts.map +0 -1
  211. package/dist/components/empty/index.js.map +0 -1
  212. package/dist/components/fileupload/index.d.ts.map +0 -1
  213. package/dist/components/fileupload/index.js.map +0 -1
  214. package/dist/components/form/index.d.ts.map +0 -1
  215. package/dist/components/form/index.js.map +0 -1
  216. package/dist/components/input/index.d.ts.map +0 -1
  217. package/dist/components/input/index.js.map +0 -1
  218. package/dist/components/menu/index.d.ts.map +0 -1
  219. package/dist/components/menu/index.js.map +0 -1
  220. package/dist/components/metric/index.d.ts.map +0 -1
  221. package/dist/components/metric/index.js.map +0 -1
  222. package/dist/components/numberinput/index.d.ts.map +0 -1
  223. package/dist/components/numberinput/index.js.map +0 -1
  224. package/dist/components/otpinput/index.d.ts.map +0 -1
  225. package/dist/components/otpinput/index.js.map +0 -1
  226. package/dist/components/page/index.d.ts.map +0 -1
  227. package/dist/components/page/index.js.map +0 -1
  228. package/dist/components/passwordinput/index.d.ts.map +0 -1
  229. package/dist/components/passwordinput/index.js.map +0 -1
  230. package/dist/components/popover/index.d.ts.map +0 -1
  231. package/dist/components/popover/index.js.map +0 -1
  232. package/dist/components/radio/index.d.ts.map +0 -1
  233. package/dist/components/radio/index.js.map +0 -1
  234. package/dist/components/ratinginput/index.d.ts.map +0 -1
  235. package/dist/components/ratinginput/index.js.map +0 -1
  236. package/dist/components/select/index.d.ts.map +0 -1
  237. package/dist/components/select/index.js.map +0 -1
  238. package/dist/components/skeleton/index.d.ts.map +0 -1
  239. package/dist/components/skeleton/index.js.map +0 -1
  240. package/dist/components/slider/index.d.ts.map +0 -1
  241. package/dist/components/slider/index.js.map +0 -1
  242. package/dist/components/spinner/index.d.ts.map +0 -1
  243. package/dist/components/spinner/index.js.map +0 -1
  244. package/dist/components/splitter/index.d.ts.map +0 -1
  245. package/dist/components/splitter/index.js.map +0 -1
  246. package/dist/components/stepper/index.d.ts.map +0 -1
  247. package/dist/components/stepper/index.js.map +0 -1
  248. package/dist/components/switch/index.d.ts.map +0 -1
  249. package/dist/components/switch/index.js.map +0 -1
  250. package/dist/components/table/index.d.ts.map +0 -1
  251. package/dist/components/table/index.js.map +0 -1
  252. package/dist/components/tabs/index.d.ts.map +0 -1
  253. package/dist/components/tabs/index.js.map +0 -1
  254. package/dist/components/textarea/index.d.ts.map +0 -1
  255. package/dist/components/textarea/index.js.map +0 -1
  256. package/dist/components/textlink/index.d.ts.map +0 -1
  257. package/dist/components/textlink/index.js.map +0 -1
  258. package/dist/components/toast/index.d.ts.map +0 -1
  259. package/dist/components/toast/index.js.map +0 -1
  260. package/dist/components/toggle/index.d.ts.map +0 -1
  261. package/dist/components/toggle/index.js.map +0 -1
  262. package/dist/components/tooltip/index.d.ts.map +0 -1
  263. package/dist/components/tooltip/index.js.map +0 -1
  264. package/dist/index.d.ts.map +0 -1
  265. package/dist/index.js.map +0 -1
  266. package/dist/types/Style.d.ts.map +0 -1
  267. package/dist/types/Style.js.map +0 -1
  268. package/dist/types/Tone.d.ts.map +0 -1
  269. package/dist/types/Tone.js.map +0 -1
  270. package/dist/utils/ArkStateToDataAttributes.d.ts.map +0 -1
  271. package/dist/utils/ArkStateToDataAttributes.js.map +0 -1
  272. package/dist/utils/Tone.d.ts.map +0 -1
  273. package/dist/utils/Tone.js.map +0 -1
  274. package/dist/utils/useForwardClickToInput.d.ts.map +0 -1
  275. package/dist/utils/useForwardClickToInput.js.map +0 -1
  276. package/dist/utils/virtualization/useVirtualizedAutocomplete.d.ts.map +0 -1
  277. package/dist/utils/virtualization/useVirtualizedAutocomplete.js.map +0 -1
  278. package/dist/utils/virtualization/useVirtualizedCombobox.d.ts.map +0 -1
  279. package/dist/utils/virtualization/useVirtualizedCombobox.js.map +0 -1
  280. package/dist/utils/virtualization/useVirtualizedTable.d.ts.map +0 -1
  281. package/dist/utils/virtualization/useVirtualizedTable.js.map +0 -1
@@ -1,12 +1,12 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { NumberField as BaseNumber } from '@base-ui/react/number-field';
3
- import { ChevronUp, ChevronDown, LoaderCircle } from 'lucide-react';
3
+ import { ChevronUp, ChevronDown, LoaderCircle } from "../../utils/icons.js";
4
4
  import { useForwardClickToInput } from "../../utils/useForwardClickToInput.js";
5
5
  import { cloneElement, createContext, forwardRef, useContext, useEffect, useId, useState, } from 'react';
6
6
  import { twMerge } from 'tailwind-merge';
7
- import { ToneProvider, useToneContext } from "../../utils/Tone.js";
7
+ import { readValidation, validationAttributes, validationMessageContent } from "../../utils/Validation.js";
8
8
  /**
9
- * Configure value, bounds, and step on Root. IncrementButton and DecrementButton update the number automatically; no custom arithmetic handlers needed. Use ButtonsList to organize them beside Input, or behavior-only handlers for custom buttons.
9
+ * Configure value, bounds, and step on Root. IncrementButton and DecrementButton update the number automatically; no custom arithmetic handlers needed. Use ButtonsList to organize them beside Input.
10
10
  *
11
11
  * @example Complete composition
12
12
  * import { NumberInput } from '@central-ui/react'
@@ -41,68 +41,70 @@ import { ToneProvider, useToneContext } from "../../utils/Tone.js";
41
41
  * }
42
42
  * </NumberInput.Root>
43
43
  */
44
- export const Root = forwardRef(function Root({ id, tone = 'neutral', children, ...props }, ref) {
44
+ export const Root = /* @__PURE__ */ forwardRef(function Root({ id, validation, children, ...props }, ref) {
45
45
  const generatedId = useId();
46
46
  const inputId = id ?? generatedId;
47
- const [connections, setConnections] = useState({
48
- descriptionIds: [],
49
- });
50
- return (_jsx(ToneProvider, { value: tone, children: _jsx(BaseNumber.Root, { ...props, id: inputId, ref: ref, render: (rootProps, state) => (_jsx(InputContext.Provider, { value: {
51
- ...state,
52
- inputId,
53
- connections,
54
- setConnections,
55
- min: props.min,
56
- max: props.max,
57
- }, children: _jsx("div", { ...rootProps }) })), children: children }) }));
58
- });
59
- export const Input = forwardRef(function Input({ disableStyle, className, 'aria-describedby': describedBy, ...props }, ref) {
47
+ // Holding the ids of Description, Error and Success, so the control announces them to screen readers through aria-describedby
48
+ const [describedByIds, setDescribedByIds] = useState([]);
49
+ return (_jsx(BaseNumber.Root, { ...props, id: inputId, ref: ref, render: (rootProps, state) => (_jsx(InputContext.Provider, { value: {
50
+ ...state,
51
+ inputId,
52
+ describedByIds,
53
+ setDescribedByIds,
54
+ min: props.min,
55
+ max: props.max,
56
+ validation: readValidation(validation),
57
+ }, children: _jsx("div", { ...rootProps }) })), children: children }));
58
+ });
59
+ export const Input = /* @__PURE__ */ forwardRef(function Input({ disableStyle, className, 'aria-describedby': describedBy, ...props }, ref) {
60
60
  const context = useInputContext();
61
- const tone = useToneContext();
62
- return (_jsx(BaseNumber.Input, { ...props, ref: ref, "data-tone": tone, "aria-invalid": tone === 'invalid' || props['aria-invalid'] || undefined, "aria-describedby": [describedBy, ...context.connections.descriptionIds]
61
+ return (_jsx(BaseNumber.Input, { ...props, ref: ref, ...validationAttributes(context.validation), "aria-invalid": context.validation.state === 'error' || props['aria-invalid'] || undefined, "aria-describedby": [describedBy, ...context.describedByIds]
63
62
  .filter(Boolean)
64
63
  .join(' ') || undefined, "data-component": "numberinput-input", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
65
64
  });
66
- export const Container = forwardRef(function Container({ disableStyle, className, ...props }, ref) {
65
+ export const Container = /* @__PURE__ */ forwardRef(function Container({ disableStyle, className, ...props }, ref) {
67
66
  const attributes = usePartAttributes();
68
67
  return (_jsx("div", { ...attributes, ...props, ref: ref, "data-component": "numberinput-container", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
69
68
  });
70
69
  /** Labels the associated control automatically. Supply the visible text; do not wire a second label association. */
71
- export const Label = forwardRef(function Label({ disableStyle, className, id, ...props }, ref) {
70
+ export const Label = /* @__PURE__ */ forwardRef(function Label({ disableStyle, className, id, ...props }, ref) {
72
71
  const context = useInputContext();
73
72
  const labelId = id ?? context.inputId + '-label';
74
73
  const attributes = usePartAttributes();
75
- useEffect(() => {
76
- context.setConnections((current) => ({ ...current, labelId }));
77
- return () => context.setConnections((current) => ({
78
- ...current,
79
- labelId: current.labelId === labelId ? undefined : current.labelId,
80
- }));
81
- }, [labelId, context.setConnections]);
82
74
  return (_jsx("label", { ...attributes, ...props, id: labelId, ref: ref, htmlFor: context.inputId, "data-component": "numberinput-label", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
83
75
  });
84
- export const Description = forwardRef(function Description({ disableStyle, className, id, ...props }, ref) {
76
+ export const Description = /* @__PURE__ */ forwardRef(function Description({ disableStyle, className, id, ...props }, ref) {
85
77
  const messageId = useMessageId(id);
86
78
  const attributes = usePartAttributes();
87
79
  return (_jsx("div", { ...attributes, ...props, id: messageId, ref: ref, "data-component": "numberinput-description", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
88
80
  });
89
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
90
- export const Error = forwardRef(function Error({ disableStyle, className, id, ...props }, ref) {
91
- const messageId = useMessageId(id);
92
- const attributes = usePartAttributes();
93
- return (_jsx("div", { role: "alert", "aria-atomic": "true", ...attributes, ...props, id: messageId, ref: ref, "data-component": "numberinput-error", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
81
+ /** 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. */
82
+ export const Error = /* @__PURE__ */ forwardRef(function Error({ children, ...props }, ref) {
83
+ const context = useInputContext();
84
+ const content = validationMessageContent(context.validation, 'error', children);
85
+ if (content === undefined)
86
+ return null;
87
+ return _jsx(Message, { ...props, ref: ref, role: "alert", component: "numberinput-error", children: content });
94
88
  });
95
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
96
- export const Success = forwardRef(function Success({ disableStyle, className, id, ...props }, ref) {
89
+ /** 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. */
90
+ export const Success = /* @__PURE__ */ forwardRef(function Success({ children, ...props }, ref) {
91
+ const context = useInputContext();
92
+ const content = validationMessageContent(context.validation, 'success', children);
93
+ if (content === undefined)
94
+ return null;
95
+ return _jsx(Message, { ...props, ref: ref, role: "status", component: "numberinput-success", children: content });
96
+ });
97
+ // The shared body of Error and Success, mounted only while they show, so only visible messages describe the number input
98
+ const Message = /* @__PURE__ */ forwardRef(function Message({ disableStyle, className, id, component, ...props }, ref) {
97
99
  const messageId = useMessageId(id);
98
100
  const attributes = usePartAttributes();
99
- return (_jsx("div", { role: "status", "aria-atomic": "true", ...attributes, ...props, id: messageId, ref: ref, "data-component": "numberinput-success", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
101
+ return _jsx("div", { "aria-atomic": "true", ...attributes, ...props, id: messageId, ref: ref, "data-component": component, "data-style-disabled": disableStyle ? '' : undefined, className: className });
100
102
  });
101
- export const Addon = forwardRef(function Addon({ disableStyle, className, variant = 'normal', ...props }, ref) {
103
+ export const Addon = /* @__PURE__ */ forwardRef(function Addon({ disableStyle, className, variant = 'normal', ...props }, ref) {
102
104
  const attributes = usePartAttributes();
103
105
  return (_jsx("div", { ...attributes, ...props, ref: ref, "data-variant": variant, "data-component": "numberinput-addon", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
104
106
  });
105
- export const AddonText = forwardRef(function AddonText({ disableStyle, className, ...props }, ref) {
107
+ export const AddonText = /* @__PURE__ */ forwardRef(function AddonText({ disableStyle, className, ...props }, ref) {
106
108
  const attributes = usePartAttributes();
107
109
  return (_jsx("span", { ...attributes, ...props, ref: ref, "data-component": "numberinput-addontext", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
108
110
  });
@@ -121,38 +123,34 @@ export function AddonIcon({ disableStyle, children, className, ...props }) {
121
123
  className: twMerge(children.props.className, className),
122
124
  });
123
125
  }
124
- export const AddonButton = forwardRef(function AddonButton({ disableStyle, className, disabled, type = 'button', ...props }, ref) {
126
+ export const AddonButton = /* @__PURE__ */ forwardRef(function AddonButton({ disableStyle, className, disabled, type = 'button', ...props }, ref) {
125
127
  const context = useInputContext();
126
128
  const attributes = usePartAttributes();
127
129
  return (_jsx("button", { ...attributes, ...props, ref: ref, type: type, disabled: disabled || context.disabled || context.readOnly, "data-component": "numberinput-addonbutton", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
128
130
  });
129
131
  /** Built-in icon; no children needed. Use it inside its matching control. */
130
- export const AddonLoadingIcon = forwardRef(function AddonLoadingIcon({ disableStyle, className, strokeWidth = 1.5, ...props }, ref) {
132
+ export const AddonLoadingIcon = /* @__PURE__ */ forwardRef(function AddonLoadingIcon({ disableStyle, className, strokeWidth = 1.5, ...props }, ref) {
131
133
  const attributes = usePartAttributes();
132
134
  return (_jsx(LoaderCircle, { ...attributes, "aria-hidden": true, ...props, ref: ref, strokeWidth: strokeWidth, "data-component": "numberinput-addonloadingicon", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
133
135
  });
134
- export const InputGroup = forwardRef(function InputGroup({ disableStyle, className, onClick, ...props }, ref) {
136
+ export const InputGroup = /* @__PURE__ */ forwardRef(function InputGroup({ disableStyle, className, onClick, ...props }, ref) {
135
137
  const attributes = usePartAttributes();
136
138
  const forwardClick = useForwardClickToInput('input:not([type="hidden"])', onClick);
137
139
  return (_jsx(BaseNumber.Group, { ...attributes, ...props, ref: ref, onClick: forwardClick, "data-component": "numberinput-inputgroup", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
138
140
  });
139
- export const ButtonsList = forwardRef(function ButtonsList({ disableStyle, className, ...props }, ref) {
141
+ export const ButtonsList = /* @__PURE__ */ forwardRef(function ButtonsList({ disableStyle, className, ...props }, ref) {
140
142
  const attributes = usePartAttributes();
141
143
  return (_jsx("div", { ...attributes, ...props, ref: ref, "data-component": "numberinput-buttonslist", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
142
144
  });
143
145
  /** Formats the current number automatically. Omit children for the default display; customize only when the usual number formatting is insufficient. */
144
- export const ValueText = forwardRef(function ValueText({ disableStyle, className, ...props }, ref) {
146
+ export const ValueText = /* @__PURE__ */ forwardRef(function ValueText({ disableStyle, className, ...props }, ref) {
145
147
  const context = useInputContext();
146
148
  const attributes = usePartAttributes();
147
149
  return (_jsx("span", { ...attributes, ...props, ref: ref, "data-component": "numberinput-valuetext", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: context.inputValue }));
148
150
  });
149
- export const IncrementButton = forwardRef(function IncrementButton({ disableStyle, className, ...props }, ref) {
151
+ export const IncrementButton = /* @__PURE__ */ forwardRef(function IncrementButton({ disableStyle, className, ...props }, ref) {
150
152
  return (_jsx(BaseNumber.Increment, { ...props, ref: ref, "data-component": "numberinput-incrementbutton", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
151
153
  });
152
- /** Behavior only: give your child control this action. Style the child itself; this wrapper has no preset appearance or disableStyle prop. */
153
- export const IncrementHandler = forwardRef(function IncrementHandler({ children, ...props }, ref) {
154
- return _jsx(BaseNumber.Increment, { ...props, ref: ref, render: children });
155
- });
156
154
  /** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
157
155
  export function IncrementButtonIcon({ disableStyle, children = _jsx(ChevronUp, {}), className, ...props }) {
158
156
  const context = useInputContext();
@@ -175,13 +173,9 @@ export function IncrementButtonIcon({ disableStyle, children = _jsx(ChevronUp, {
175
173
  className: twMerge(children.props.className, className),
176
174
  });
177
175
  }
178
- export const DecrementButton = forwardRef(function DecrementButton({ disableStyle, className, ...props }, ref) {
176
+ export const DecrementButton = /* @__PURE__ */ forwardRef(function DecrementButton({ disableStyle, className, ...props }, ref) {
179
177
  return (_jsx(BaseNumber.Decrement, { ...props, ref: ref, "data-component": "numberinput-decrementbutton", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
180
178
  });
181
- /** Behavior only: give your child control this action. Style the child itself; this wrapper has no preset appearance or disableStyle prop. */
182
- export const DecrementHandler = forwardRef(function DecrementHandler({ children, ...props }, ref) {
183
- return _jsx(BaseNumber.Decrement, { ...props, ref: ref, render: children });
184
- });
185
179
  /** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
186
180
  export function DecrementButtonIcon({ disableStyle, children = _jsx(ChevronDown, {}), className, ...props }) {
187
181
  const context = useInputContext();
@@ -204,7 +198,7 @@ export function DecrementButtonIcon({ disableStyle, children = _jsx(ChevronDown,
204
198
  className: twMerge(children.props.className, className),
205
199
  });
206
200
  }
207
- const InputContext = createContext(null);
201
+ const InputContext = /* @__PURE__ */ createContext(null);
208
202
  function useInputContext() {
209
203
  const context = useContext(InputContext);
210
204
  if (!context)
@@ -213,28 +207,21 @@ function useInputContext() {
213
207
  }
214
208
  function usePartAttributes() {
215
209
  const context = useInputContext();
216
- const tone = useToneContext();
217
210
  return {
218
211
  'data-disabled': context.disabled ? '' : undefined,
219
212
  'data-readonly': context.readOnly ? '' : undefined,
220
213
  'data-required': context.required ? '' : undefined,
221
- 'data-tone': tone,
214
+ ...validationAttributes(context.validation),
222
215
  };
223
216
  }
217
+ // Registering a message part's id in the control's aria-describedby while the part is mounted
224
218
  function useMessageId(id) {
219
+ const context = useInputContext();
225
220
  const generatedId = useId();
226
221
  const messageId = id ?? generatedId;
227
- const context = useInputContext();
228
222
  useEffect(() => {
229
- context.setConnections((current) => ({
230
- ...current,
231
- descriptionIds: [...current.descriptionIds, messageId],
232
- }));
233
- return () => context.setConnections((current) => ({
234
- ...current,
235
- descriptionIds: current.descriptionIds.filter((id) => id !== messageId),
236
- }));
237
- }, [messageId, context.setConnections]);
223
+ context.setDescribedByIds((current) => [...current, messageId]);
224
+ return () => context.setDescribedByIds((current) => current.filter((currentId) => currentId !== messageId));
225
+ }, [messageId, context.setDescribedByIds]);
238
226
  return messageId;
239
227
  }
240
- //# sourceMappingURL=index.js.map
@@ -1,10 +1,12 @@
1
1
  import type { StyleProps } from '../../types/Style.ts';
2
2
  import { OTPField as BaseOtp } from '@base-ui/react/otp-field';
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 = Omit<BaseOtp.Root.Props, 'className' | 'render'> & {
5
7
  className?: string;
6
- /** Choose the visual tone. This does not validate data or show/hide feedback messages. */
7
- tone?: 'neutral' | 'valid' | 'invalid';
8
+ /** The field's validation state, with an optional message: `'error'` styles it as invalid, `['error', 'Email is required']` also shows that message in Error. Same for `'success'` and Success. Omit it for a neutral field. */
9
+ validation?: Validation;
8
10
  };
9
11
  /**
10
12
  * Configure length and value on Root. Render an Input for each callback invocation from List; slot order is managed automatically. Keyboard navigation and paste distribution are built in; do not split or synchronize the code yourself.
@@ -41,17 +43,20 @@ export type RootProps = Omit<BaseOtp.Root.Props, 'className' | 'render'> & {
41
43
  * </OtpInput.Root>
42
44
  */
43
45
  export declare const Root: import("react").ForwardRefExoticComponent<Omit<RootProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
44
- export declare const Input: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").OTPFieldInputProps, "form" | "className" | "defaultValue" | "id" | "name" | "disabled" | "value" | "render" | "required" | "readOnly"> & {
46
+ export declare const Input: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").OTPFieldInputProps, "className" | "id" | "name" | "form" | "defaultValue" | "disabled" | "value" | "render" | "required" | "readOnly"> & {
45
47
  className?: string;
46
48
  } & StyleProps, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
47
49
  export declare const Container: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
48
50
  /** Labels the associated control automatically. Supply the visible text; do not wire a second label association. */
49
51
  export declare const Label: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, "htmlFor"> & StyleProps, "ref"> & import("react").RefAttributes<HTMLLabelElement>>;
50
52
  export declare const Description: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
51
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
52
- export declare const Error: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
53
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
54
- export declare const Success: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
53
+ type MessageProps = Omit<ComponentProps<'div'>, 'children'> & StyleProps & {
54
+ children?: ValidationMessageChildren;
55
+ };
56
+ /** 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. */
57
+ export declare const Error: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
58
+ /** 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. */
59
+ export declare const Success: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
55
60
  /** Calls children for each code slot. Render Input inside each callback; the component handles slot ordering and keyboard/paste behavior. */
56
61
  export declare const List: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "children"> & {
57
62
  /** Render an Input for each slot. Use the index for keys or separator placement; input ordering is automatic. */
@@ -60,4 +65,4 @@ export declare const List: import("react").ForwardRefExoticComponent<Omit<Omit<i
60
65
  export declare const Separator: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").SeparatorProps, "className"> & {
61
66
  className?: string;
62
67
  } & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
63
- //# sourceMappingURL=index.d.ts.map
68
+ export {};
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { OTPField as BaseOtp } from '@base-ui/react/otp-field';
3
3
  import { Fragment, createContext, forwardRef, useContext, useEffect, useId, useState, } from 'react';
4
- import { ToneProvider, useToneContext } from "../../utils/Tone.js";
4
+ import { readValidation, validationAttributes, validationMessageContent } from "../../utils/Validation.js";
5
5
  /**
6
6
  * Configure length and value on Root. Render an Input for each callback invocation from List; slot order is managed automatically. Keyboard navigation and paste distribution are built in; do not split or synchronize the code yourself.
7
7
  *
@@ -36,29 +36,28 @@ import { ToneProvider, useToneContext } from "../../utils/Tone.js";
36
36
  * }
37
37
  * </OtpInput.Root>
38
38
  */
39
- export const Root = forwardRef(function Root({ id, tone = 'neutral', children, ...props }, ref) {
39
+ export const Root = /* @__PURE__ */ forwardRef(function Root({ id, validation, children, ...props }, ref) {
40
40
  const generatedId = useId();
41
41
  const inputId = id ?? generatedId;
42
42
  const [connections, setConnections] = useState({
43
43
  descriptionIds: [],
44
44
  });
45
- return (_jsx(ToneProvider, { value: tone, children: _jsx(BaseOtp.Root, { ...props, id: inputId, ref: ref, "aria-labelledby": connections.labelId ?? props['aria-labelledby'], "aria-describedby": [props['aria-describedby'], ...connections.descriptionIds]
46
- .filter(Boolean)
47
- .join(' ') || undefined, render: (rootProps, state) => (_jsx(InputContext.Provider, { value: { ...state, inputId, connections, setConnections }, children: _jsx("div", { ...rootProps }) })), children: children }) }));
45
+ return (_jsx(BaseOtp.Root, { ...props, id: inputId, ref: ref, "aria-labelledby": connections.labelId ?? props['aria-labelledby'], "aria-describedby": [props['aria-describedby'], ...connections.descriptionIds]
46
+ .filter(Boolean)
47
+ .join(' ') || undefined, render: (rootProps, state) => (_jsx(InputContext.Provider, { value: { ...state, inputId, connections, setConnections, validation: readValidation(validation) }, children: _jsx("div", { ...rootProps }) })), children: children }));
48
48
  });
49
- export const Input = forwardRef(function Input({ disableStyle, className, 'aria-describedby': describedBy, ...props }, ref) {
49
+ export const Input = /* @__PURE__ */ forwardRef(function Input({ disableStyle, className, 'aria-describedby': describedBy, ...props }, ref) {
50
50
  const context = useInputContext();
51
- const tone = useToneContext();
52
- return (_jsx(BaseOtp.Input, { ...props, ref: ref, "data-tone": tone, "aria-invalid": tone === 'invalid' || props['aria-invalid'] || undefined, "aria-describedby": [describedBy, ...context.connections.descriptionIds]
51
+ return (_jsx(BaseOtp.Input, { ...props, ref: ref, ...validationAttributes(context.validation), "aria-invalid": context.validation.state === 'error' || props['aria-invalid'] || undefined, "aria-describedby": [describedBy, ...context.connections.descriptionIds]
53
52
  .filter(Boolean)
54
53
  .join(' ') || undefined, "aria-labelledby": props['aria-labelledby'] ?? context.connections.labelId, "data-component": "otpinput-input", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
55
54
  });
56
- export const Container = forwardRef(function Container({ disableStyle, className, ...props }, ref) {
55
+ export const Container = /* @__PURE__ */ forwardRef(function Container({ disableStyle, className, ...props }, ref) {
57
56
  const attributes = usePartAttributes();
58
57
  return (_jsx("div", { ...attributes, ...props, ref: ref, "data-component": "otpinput-container", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
59
58
  });
60
59
  /** Labels the associated control automatically. Supply the visible text; do not wire a second label association. */
61
- export const Label = forwardRef(function Label({ disableStyle, className, id, ...props }, ref) {
60
+ export const Label = /* @__PURE__ */ forwardRef(function Label({ disableStyle, className, id, ...props }, ref) {
62
61
  const context = useInputContext();
63
62
  const labelId = id ?? context.inputId + '-label';
64
63
  const attributes = usePartAttributes();
@@ -71,33 +70,43 @@ export const Label = forwardRef(function Label({ disableStyle, className, id, ..
71
70
  }, [labelId, context.setConnections]);
72
71
  return (_jsx("label", { ...attributes, ...props, id: labelId, ref: ref, htmlFor: context.inputId, "data-component": "otpinput-label", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
73
72
  });
74
- export const Description = forwardRef(function Description({ disableStyle, className, id, ...props }, ref) {
73
+ export const Description = /* @__PURE__ */ forwardRef(function Description({ disableStyle, className, id, ...props }, ref) {
75
74
  const messageId = useMessageId(id);
76
75
  const attributes = usePartAttributes();
77
76
  return (_jsx("div", { ...attributes, ...props, id: messageId, ref: ref, "data-component": "otpinput-description", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
78
77
  });
79
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
80
- export const Error = forwardRef(function Error({ disableStyle, className, id, ...props }, ref) {
81
- const messageId = useMessageId(id);
82
- const attributes = usePartAttributes();
83
- return (_jsx("div", { role: "alert", "aria-atomic": "true", ...attributes, ...props, id: messageId, ref: ref, "data-component": "otpinput-error", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
78
+ /** 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. */
79
+ export const Error = /* @__PURE__ */ forwardRef(function Error({ children, ...props }, ref) {
80
+ const context = useInputContext();
81
+ const content = validationMessageContent(context.validation, 'error', children);
82
+ if (content === undefined)
83
+ return null;
84
+ return _jsx(Message, { ...props, ref: ref, role: "alert", component: "otpinput-error", children: content });
85
+ });
86
+ /** 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. */
87
+ export const Success = /* @__PURE__ */ forwardRef(function Success({ children, ...props }, ref) {
88
+ const context = useInputContext();
89
+ const content = validationMessageContent(context.validation, 'success', children);
90
+ if (content === undefined)
91
+ return null;
92
+ return _jsx(Message, { ...props, ref: ref, role: "status", component: "otpinput-success", children: content });
84
93
  });
85
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
86
- export const Success = forwardRef(function Success({ disableStyle, className, id, ...props }, ref) {
94
+ // The shared body of Error and Success, mounted only while they show, so only visible messages describe the otp input
95
+ const Message = /* @__PURE__ */ forwardRef(function Message({ disableStyle, className, id, component, ...props }, ref) {
87
96
  const messageId = useMessageId(id);
88
97
  const attributes = usePartAttributes();
89
- return (_jsx("div", { role: "status", "aria-atomic": "true", ...attributes, ...props, id: messageId, ref: ref, "data-component": "otpinput-success", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
98
+ return _jsx("div", { "aria-atomic": "true", ...attributes, ...props, id: messageId, ref: ref, "data-component": component, "data-style-disabled": disableStyle ? '' : undefined, className: className });
90
99
  });
91
100
  /** Calls children for each code slot. Render Input inside each callback; the component handles slot ordering and keyboard/paste behavior. */
92
- export const List = forwardRef(function List({ disableStyle, className, children, ...props }, ref) {
101
+ export const List = /* @__PURE__ */ forwardRef(function List({ disableStyle, className, children, ...props }, ref) {
93
102
  const context = useInputContext();
94
103
  const attributes = usePartAttributes();
95
104
  return (_jsx("div", { ...attributes, ...props, ref: ref, "data-component": "otpinput-list", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: Array.from({ length: context.length }, (_, index) => (_jsx(Fragment, { children: children(index) }, index))) }));
96
105
  });
97
- export const Separator = forwardRef(function Separator({ disableStyle, className, ...props }, ref) {
106
+ export const Separator = /* @__PURE__ */ forwardRef(function Separator({ disableStyle, className, ...props }, ref) {
98
107
  return (_jsx(BaseOtp.Separator, { ...props, ref: ref, "data-component": "otpinput-separator", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
99
108
  });
100
- const InputContext = createContext(null);
109
+ const InputContext = /* @__PURE__ */ createContext(null);
101
110
  function useInputContext() {
102
111
  const context = useContext(InputContext);
103
112
  if (!context)
@@ -106,12 +115,11 @@ function useInputContext() {
106
115
  }
107
116
  function usePartAttributes() {
108
117
  const context = useInputContext();
109
- const tone = useToneContext();
110
118
  return {
111
119
  'data-disabled': context.disabled ? '' : undefined,
112
120
  'data-readonly': context.readOnly ? '' : undefined,
113
121
  'data-required': context.required ? '' : undefined,
114
- 'data-tone': tone,
122
+ ...validationAttributes(context.validation),
115
123
  };
116
124
  }
117
125
  function useMessageId(id) {
@@ -130,4 +138,3 @@ function useMessageId(id) {
130
138
  }, [messageId, context.setConnections]);
131
139
  return messageId;
132
140
  }
133
- //# sourceMappingURL=index.js.map
@@ -51,4 +51,3 @@ export declare function BodySectionHeader({ disableStyle, className, ...props }:
51
51
  export declare function BodySectionTitle({ disableStyle, className, ...props }: ComponentProps<'h2'> & StyleProps): import("react").JSX.Element;
52
52
  export declare function Footer({ disableStyle, className, ...props }: ComponentProps<'div'> & StyleProps): import("react").JSX.Element;
53
53
  export {};
54
- //# sourceMappingURL=index.d.ts.map
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { ArrowLeft } from 'lucide-react';
2
+ import { ArrowLeft } from "../../utils/icons.js";
3
3
  import { cloneElement, createContext, useContext } from 'react';
4
4
  import { twMerge } from 'tailwind-merge';
5
- const SizeContext = createContext('medium');
5
+ const SizeContext = /* @__PURE__ */ createContext('medium');
6
6
  /**
7
7
  * Root configures the page width; Surface renders it. Choose the Header, Body sections, and Footer needed by the screen. Action areas take your own controls; they do not create actions automatically.
8
8
  *
@@ -58,7 +58,6 @@ export function HeaderBackButton({ disableStyle, type = 'button', className, ...
58
58
  export function HeaderBackButtonIcon({ disableStyle, children = _jsx(ArrowLeft, {}), className, ...props }) {
59
59
  const size = useContext(SizeContext);
60
60
  return cloneElement(children, {
61
- ...children.props,
62
61
  ...props,
63
62
  'data-size': size,
64
63
  ...{
@@ -97,4 +96,3 @@ export function Footer({ disableStyle, className, ...props }) {
97
96
  const size = useContext(SizeContext);
98
97
  return (_jsx("div", { ...props, "data-size": size, "data-component": "page-footer", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
99
98
  }
100
- //# sourceMappingURL=index.js.map
@@ -1,11 +1,13 @@
1
1
  import type { StyleProps } from '../../types/Style.ts';
2
2
  import { Root as RadixRoot, Input as RadixInput } from '@radix-ui/react-password-toggle-field';
3
3
  import { Input as BaseInput } from '@base-ui/react/input';
4
- import type { LucideProps } from 'lucide-react';
4
+ import type { SVGIconProps } from '../../types/Icon.ts';
5
5
  import type { ComponentProps, ComponentPropsWithRef, ReactElement } from 'react';
6
+ import type { Validation } from '../../types/Validation.ts';
7
+ import type { ValidationMessageChildren } from '../../utils/Validation.ts';
6
8
  export type RootProps = ComponentProps<typeof RadixRoot> & Pick<ComponentProps<typeof RadixInput>, 'name' | 'form' | 'value' | 'defaultValue' | 'disabled' | 'readOnly' | 'required'> & Pick<BaseInput.Props, 'onValueChange'> & {
7
- /** Choose the visual tone. This does not validate data or show/hide feedback messages. */
8
- tone?: 'neutral' | 'valid' | 'invalid';
9
+ /** The field's validation state, with an optional message: `'error'` styles it as invalid, `['error', 'Email is required']` also shows that message in Error. Same for `'success'` and Success. Omit it for a neutral field. */
10
+ validation?: Validation;
9
11
  };
10
12
  /**
11
13
  * Configure the password on Root and use Input inside InputGroup. AddonVisibilityButton toggles visibility automatically; its visible/hidden icons follow that state. Do not maintain a second visibility state.
@@ -44,22 +46,23 @@ export type RootProps = ComponentProps<typeof RadixRoot> & Pick<ComponentProps<t
44
46
  * }
45
47
  * </PasswordInput.Root>
46
48
  */
47
- export declare function Root({ children, id, tone, value, defaultValue, onValueChange, disabled, readOnly, required, name, form, ...props }: RootProps): import("react").JSX.Element;
49
+ export declare function Root({ children, id, validation, value, defaultValue, onValueChange, disabled, readOnly, required, name, form, ...props }: RootProps): import("react").JSX.Element;
48
50
  export type InputProps = Omit<ComponentPropsWithRef<typeof RadixInput>, keyof Pick<RootProps, 'id' | 'name' | 'form' | 'value' | 'defaultValue' | 'onValueChange' | 'disabled' | 'readOnly' | 'required'> | 'asChild'> & {
49
51
  className?: string;
50
52
  } & StyleProps;
51
- export declare const Input: import("react").ForwardRefExoticComponent<Omit<Omit<Omit<import("@radix-ui/react-password-toggle-field").PasswordToggleFieldInputProps, "ref"> & import("react").RefAttributes<HTMLInputElement>, "form" | "defaultValue" | "id" | "name" | "disabled" | "value" | "onValueChange" | "required" | "readOnly" | "asChild"> & {
52
- className?: string;
53
- } & StyleProps, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
53
+ export declare const Input: import("react").ForwardRefExoticComponent<Omit<InputProps, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
54
54
  export declare const InputGroup: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
55
55
  export declare const Container: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
56
56
  /** Labels the associated control automatically. Supply the visible text; do not wire a second label association. */
57
57
  export declare const Label: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, "htmlFor"> & StyleProps, "ref"> & import("react").RefAttributes<HTMLLabelElement>>;
58
58
  export declare const Description: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
59
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
60
- export declare const Error: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
61
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
62
- export declare const Success: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
59
+ type MessageProps = Omit<ComponentProps<'div'>, 'children'> & StyleProps & {
60
+ children?: ValidationMessageChildren;
61
+ };
62
+ /** 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. */
63
+ export declare const Error: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
64
+ /** 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. */
65
+ export declare const Success: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
63
66
  export declare const Addon: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & {
64
67
  /** Choose the preset appearance; this does not add action behavior. */
65
68
  variant?: "normal" | "emphasized";
@@ -72,7 +75,7 @@ export declare function AddonIcon({ disableStyle, children, className, ...props
72
75
  }) & StyleProps): ReactElement<import("react").SVGProps<SVGSVGElement>, string | import("react").JSXElementConstructor<any>>;
73
76
  export declare const AddonButton: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLButtonElement> & import("react").ButtonHTMLAttributes<HTMLButtonElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
74
77
  /** Built-in icon; no children needed. Use it inside its matching control. */
75
- export declare const AddonLoadingIcon: import("react").ForwardRefExoticComponent<Omit<Omit<LucideProps, "children"> & StyleProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
78
+ export declare const AddonLoadingIcon: import("react").ForwardRefExoticComponent<Omit<Omit<SVGIconProps, "children"> & StyleProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
76
79
  /** Toggles password visibility automatically; do not maintain another visibility state. */
77
80
  export declare const AddonVisibilityButton: import("react").ForwardRefExoticComponent<Omit<Omit<import("@radix-ui/react-password-toggle-field").PasswordToggleFieldToggleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
78
81
  /** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
@@ -85,4 +88,4 @@ export declare function AddonHiddenIcon({ disableStyle, children, className, ...
85
88
  /** Omit for the supplied default icon; pass a child only to replace it. */
86
89
  children?: ReactElement<ComponentProps<'svg'>>;
87
90
  }) & StyleProps): import("react").JSX.Element;
88
- //# sourceMappingURL=index.d.ts.map
91
+ export {};