@central-ui/react 0.1.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (287) hide show
  1. package/LICENSE +49 -0
  2. package/dist/components/accordion/index.d.ts +4 -3
  3. package/dist/components/accordion/index.js +7 -4
  4. package/dist/components/autocomplete/index.d.ts +23 -30
  5. package/dist/components/autocomplete/index.js +81 -56
  6. package/dist/components/avatar/index.d.ts +1 -2
  7. package/dist/components/avatar/index.js +0 -1
  8. package/dist/components/badge/index.d.ts +0 -1
  9. package/dist/components/badge/index.js +2 -2
  10. package/dist/components/banner/index.d.ts +1 -1
  11. package/dist/components/banner/index.js +23 -25
  12. package/dist/components/barchart/index.d.ts +106 -0
  13. package/dist/components/barchart/index.js +122 -0
  14. package/dist/components/breadcrumb/index.d.ts +0 -1
  15. package/dist/components/breadcrumb/index.js +6 -7
  16. package/dist/components/button/index.d.ts +2 -3
  17. package/dist/components/button/index.js +11 -12
  18. package/dist/components/card/index.d.ts +0 -1
  19. package/dist/components/card/index.js +0 -1
  20. package/dist/components/carousel/index.d.ts +169 -0
  21. package/dist/components/carousel/index.js +299 -0
  22. package/dist/components/checkbox/index.d.ts +13 -11
  23. package/dist/components/checkbox/index.js +51 -31
  24. package/dist/components/chip/index.d.ts +1 -1
  25. package/dist/components/chip/index.js +2 -3
  26. package/dist/components/combobox/index.d.ts +33 -49
  27. package/dist/components/combobox/index.js +102 -70
  28. package/dist/components/datepicker/index.d.ts +18 -31
  29. package/dist/components/datepicker/index.js +81 -99
  30. package/dist/components/dialog/index.d.ts +14 -27
  31. package/dist/components/dialog/index.js +17 -18
  32. package/dist/components/divider/index.d.ts +0 -1
  33. package/dist/components/divider/index.js +0 -1
  34. package/dist/components/donutchart/index.d.ts +100 -0
  35. package/dist/components/donutchart/index.js +178 -0
  36. package/dist/components/drawer/index.d.ts +12 -21
  37. package/dist/components/drawer/index.js +34 -36
  38. package/dist/components/empty/index.d.ts +3 -3
  39. package/dist/components/empty/index.js +4 -5
  40. package/dist/components/exception/index.d.ts +86 -0
  41. package/dist/components/exception/index.js +116 -0
  42. package/dist/components/fileupload/index.d.ts +4 -9
  43. package/dist/components/fileupload/index.js +26 -38
  44. package/dist/components/form/index.d.ts +0 -1
  45. package/dist/components/form/index.js +0 -1
  46. package/dist/components/horizontalbarchart/index.d.ts +120 -0
  47. package/dist/components/horizontalbarchart/index.js +193 -0
  48. package/dist/components/input/index.d.ts +22 -22
  49. package/dist/components/input/index.js +76 -105
  50. package/dist/components/linechart/index.d.ts +114 -0
  51. package/dist/components/linechart/index.js +139 -0
  52. package/dist/components/menu/index.d.ts +9 -11
  53. package/dist/components/menu/index.js +42 -39
  54. package/dist/components/metric/index.d.ts +0 -1
  55. package/dist/components/metric/index.js +0 -1
  56. package/dist/components/numberinput/index.d.ts +14 -21
  57. package/dist/components/numberinput/index.js +40 -53
  58. package/dist/components/otpinput/index.d.ts +14 -9
  59. package/dist/components/otpinput/index.js +25 -18
  60. package/dist/components/page/index.d.ts +0 -1
  61. package/dist/components/page/index.js +1 -3
  62. package/dist/components/passwordinput/index.d.ts +14 -11
  63. package/dist/components/passwordinput/index.js +36 -45
  64. package/dist/components/popover/index.d.ts +21 -19
  65. package/dist/components/popover/index.js +34 -15
  66. package/dist/components/radio/index.d.ts +13 -9
  67. package/dist/components/radio/index.js +69 -60
  68. package/dist/components/ratinginput/index.d.ts +13 -8
  69. package/dist/components/ratinginput/index.js +37 -17
  70. package/dist/components/select/index.d.ts +30 -30
  71. package/dist/components/select/index.js +80 -41
  72. package/dist/components/skeleton/index.d.ts +0 -1
  73. package/dist/components/skeleton/index.js +0 -1
  74. package/dist/components/slider/index.d.ts +14 -9
  75. package/dist/components/slider/index.js +64 -63
  76. package/dist/components/spinner/index.d.ts +1 -2
  77. package/dist/components/spinner/index.js +2 -3
  78. package/dist/components/splitter/index.d.ts +1 -2
  79. package/dist/components/splitter/index.js +5 -6
  80. package/dist/components/stepper/index.d.ts +8 -20
  81. package/dist/components/stepper/index.js +15 -16
  82. package/dist/components/switch/index.d.ts +12 -10
  83. package/dist/components/switch/index.js +46 -30
  84. package/dist/components/table/index.d.ts +3 -3
  85. package/dist/components/table/index.js +14 -13
  86. package/dist/components/tabs/index.d.ts +0 -1
  87. package/dist/components/tabs/index.js +1 -2
  88. package/dist/components/textarea/index.d.ts +14 -11
  89. package/dist/components/textarea/index.js +37 -46
  90. package/dist/components/textlink/index.d.ts +3 -1
  91. package/dist/components/textlink/index.js +4 -1
  92. package/dist/components/toast/index.d.ts +8 -14
  93. package/dist/components/toast/index.js +48 -48
  94. package/dist/components/toggle/index.d.ts +0 -1
  95. package/dist/components/toggle/index.js +17 -24
  96. package/dist/components/tooltip/index.d.ts +11 -13
  97. package/dist/components/tooltip/index.js +12 -9
  98. package/dist/components/tour/index.d.ts +154 -0
  99. package/dist/components/tour/index.js +280 -0
  100. package/dist/index.d.ts +7 -2
  101. package/dist/index.js +7 -1
  102. package/dist/types/Icon.d.ts +0 -1
  103. package/dist/types/Icon.js +0 -1
  104. package/dist/types/Style.d.ts +0 -1
  105. package/dist/types/Style.js +0 -1
  106. package/dist/types/Validation.d.ts +12 -0
  107. package/dist/types/Validation.js +1 -0
  108. package/dist/utils/ArkStateToDataAttributes.d.ts +0 -1
  109. package/dist/utils/ArkStateToDataAttributes.js +0 -1
  110. package/dist/utils/Validation.d.ts +14 -0
  111. package/dist/utils/Validation.js +23 -0
  112. package/dist/utils/asChild.d.ts +41 -0
  113. package/dist/utils/asChild.js +15 -0
  114. package/dist/utils/icons.d.ts +24 -0
  115. package/dist/utils/icons.js +160 -0
  116. package/dist/utils/useForwardClickToInput.d.ts +0 -1
  117. package/dist/utils/useForwardClickToInput.js +0 -1
  118. package/dist/utils/virtualization/useVirtualizedAutocomplete.d.ts +0 -1
  119. package/dist/utils/virtualization/useVirtualizedAutocomplete.js +0 -1
  120. package/dist/utils/virtualization/useVirtualizedCombobox.d.ts +0 -1
  121. package/dist/utils/virtualization/useVirtualizedCombobox.js +0 -1
  122. package/dist/utils/virtualization/useVirtualizedTable.d.ts +0 -1
  123. package/dist/utils/virtualization/useVirtualizedTable.js +0 -1
  124. package/package.json +14 -11
  125. package/src/presets/shopify-polaris/shopify-polaris-autocomplete.css +2 -2
  126. package/src/presets/shopify-polaris/shopify-polaris-barchart.css +64 -0
  127. package/src/presets/shopify-polaris/shopify-polaris-carousel.css +62 -0
  128. package/src/presets/shopify-polaris/shopify-polaris-checkbox.css +2 -2
  129. package/src/presets/shopify-polaris/shopify-polaris-combobox.css +2 -2
  130. package/src/presets/shopify-polaris/shopify-polaris-datepicker.css +4 -4
  131. package/src/presets/shopify-polaris/shopify-polaris-dialog.css +16 -0
  132. package/src/presets/shopify-polaris/shopify-polaris-donutchart.css +172 -0
  133. package/src/presets/shopify-polaris/shopify-polaris-drawer.css +16 -0
  134. package/src/presets/shopify-polaris/shopify-polaris-exception.css +40 -0
  135. package/src/presets/shopify-polaris/shopify-polaris-fileupload.css +1 -1
  136. package/src/presets/shopify-polaris/shopify-polaris-horizontalbarchart.css +60 -0
  137. package/src/presets/shopify-polaris/shopify-polaris-input.css +2 -2
  138. package/src/presets/shopify-polaris/shopify-polaris-linechart.css +68 -0
  139. package/src/presets/shopify-polaris/shopify-polaris-menu.css +16 -0
  140. package/src/presets/shopify-polaris/shopify-polaris-numberinput.css +2 -2
  141. package/src/presets/shopify-polaris/shopify-polaris-otpinput.css +2 -2
  142. package/src/presets/shopify-polaris/shopify-polaris-passwordinput.css +2 -2
  143. package/src/presets/shopify-polaris/shopify-polaris-popover.css +29 -0
  144. package/src/presets/shopify-polaris/shopify-polaris-radio.css +2 -2
  145. package/src/presets/shopify-polaris/shopify-polaris-ratinginput.css +2 -2
  146. package/src/presets/shopify-polaris/shopify-polaris-select.css +2 -2
  147. package/src/presets/shopify-polaris/shopify-polaris-slider.css +2 -2
  148. package/src/presets/shopify-polaris/shopify-polaris-stepper.css +16 -0
  149. package/src/presets/shopify-polaris/shopify-polaris-switch.css +2 -2
  150. package/src/presets/shopify-polaris/shopify-polaris-textarea.css +2 -2
  151. package/src/presets/shopify-polaris/shopify-polaris-tooltip.css +16 -0
  152. package/src/presets/shopify-polaris/shopify-polaris.css +6 -0
  153. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-autocomplete.css +2 -2
  154. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-barchart.css +64 -0
  155. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-carousel.css +55 -0
  156. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-checkbox.css +2 -2
  157. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-combobox.css +2 -2
  158. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-datepicker.css +2 -2
  159. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-dialog.css +9 -0
  160. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-donutchart.css +172 -0
  161. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-drawer.css +9 -0
  162. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-exception.css +40 -0
  163. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-fileupload.css +1 -1
  164. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-horizontalbarchart.css +60 -0
  165. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-input.css +2 -2
  166. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-linechart.css +68 -0
  167. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-menu.css +9 -0
  168. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-numberinput.css +2 -2
  169. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-otpinput.css +2 -2
  170. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-passwordinput.css +2 -2
  171. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-popover.css +22 -0
  172. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-radio.css +2 -2
  173. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-ratinginput.css +2 -2
  174. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-slider.css +2 -2
  175. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-stepper.css +9 -0
  176. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-switch.css +2 -2
  177. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-textarea.css +2 -2
  178. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-tooltip.css +9 -0
  179. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy.css +6 -0
  180. package/dist/components/accordion/index.d.ts.map +0 -1
  181. package/dist/components/accordion/index.js.map +0 -1
  182. package/dist/components/autocomplete/index.d.ts.map +0 -1
  183. package/dist/components/autocomplete/index.js.map +0 -1
  184. package/dist/components/avatar/index.d.ts.map +0 -1
  185. package/dist/components/avatar/index.js.map +0 -1
  186. package/dist/components/badge/index.d.ts.map +0 -1
  187. package/dist/components/badge/index.js.map +0 -1
  188. package/dist/components/banner/index.d.ts.map +0 -1
  189. package/dist/components/banner/index.js.map +0 -1
  190. package/dist/components/breadcrumb/index.d.ts.map +0 -1
  191. package/dist/components/breadcrumb/index.js.map +0 -1
  192. package/dist/components/button/index.d.ts.map +0 -1
  193. package/dist/components/button/index.js.map +0 -1
  194. package/dist/components/card/index.d.ts.map +0 -1
  195. package/dist/components/card/index.js.map +0 -1
  196. package/dist/components/checkbox/index.d.ts.map +0 -1
  197. package/dist/components/checkbox/index.js.map +0 -1
  198. package/dist/components/chip/index.d.ts.map +0 -1
  199. package/dist/components/chip/index.js.map +0 -1
  200. package/dist/components/combobox/index.d.ts.map +0 -1
  201. package/dist/components/combobox/index.js.map +0 -1
  202. package/dist/components/datepicker/index.d.ts.map +0 -1
  203. package/dist/components/datepicker/index.js.map +0 -1
  204. package/dist/components/dialog/index.d.ts.map +0 -1
  205. package/dist/components/dialog/index.js.map +0 -1
  206. package/dist/components/divider/index.d.ts.map +0 -1
  207. package/dist/components/divider/index.js.map +0 -1
  208. package/dist/components/drawer/index.d.ts.map +0 -1
  209. package/dist/components/drawer/index.js.map +0 -1
  210. package/dist/components/empty/index.d.ts.map +0 -1
  211. package/dist/components/empty/index.js.map +0 -1
  212. package/dist/components/fileupload/index.d.ts.map +0 -1
  213. package/dist/components/fileupload/index.js.map +0 -1
  214. package/dist/components/form/index.d.ts.map +0 -1
  215. package/dist/components/form/index.js.map +0 -1
  216. package/dist/components/input/index.d.ts.map +0 -1
  217. package/dist/components/input/index.js.map +0 -1
  218. package/dist/components/menu/index.d.ts.map +0 -1
  219. package/dist/components/menu/index.js.map +0 -1
  220. package/dist/components/metric/index.d.ts.map +0 -1
  221. package/dist/components/metric/index.js.map +0 -1
  222. package/dist/components/numberinput/index.d.ts.map +0 -1
  223. package/dist/components/numberinput/index.js.map +0 -1
  224. package/dist/components/otpinput/index.d.ts.map +0 -1
  225. package/dist/components/otpinput/index.js.map +0 -1
  226. package/dist/components/page/index.d.ts.map +0 -1
  227. package/dist/components/page/index.js.map +0 -1
  228. package/dist/components/passwordinput/index.d.ts.map +0 -1
  229. package/dist/components/passwordinput/index.js.map +0 -1
  230. package/dist/components/popover/index.d.ts.map +0 -1
  231. package/dist/components/popover/index.js.map +0 -1
  232. package/dist/components/radio/index.d.ts.map +0 -1
  233. package/dist/components/radio/index.js.map +0 -1
  234. package/dist/components/ratinginput/index.d.ts.map +0 -1
  235. package/dist/components/ratinginput/index.js.map +0 -1
  236. package/dist/components/select/index.d.ts.map +0 -1
  237. package/dist/components/select/index.js.map +0 -1
  238. package/dist/components/skeleton/index.d.ts.map +0 -1
  239. package/dist/components/skeleton/index.js.map +0 -1
  240. package/dist/components/slider/index.d.ts.map +0 -1
  241. package/dist/components/slider/index.js.map +0 -1
  242. package/dist/components/spinner/index.d.ts.map +0 -1
  243. package/dist/components/spinner/index.js.map +0 -1
  244. package/dist/components/splitter/index.d.ts.map +0 -1
  245. package/dist/components/splitter/index.js.map +0 -1
  246. package/dist/components/stepper/index.d.ts.map +0 -1
  247. package/dist/components/stepper/index.js.map +0 -1
  248. package/dist/components/switch/index.d.ts.map +0 -1
  249. package/dist/components/switch/index.js.map +0 -1
  250. package/dist/components/table/index.d.ts.map +0 -1
  251. package/dist/components/table/index.js.map +0 -1
  252. package/dist/components/tabs/index.d.ts.map +0 -1
  253. package/dist/components/tabs/index.js.map +0 -1
  254. package/dist/components/textarea/index.d.ts.map +0 -1
  255. package/dist/components/textarea/index.js.map +0 -1
  256. package/dist/components/textlink/index.d.ts.map +0 -1
  257. package/dist/components/textlink/index.js.map +0 -1
  258. package/dist/components/toast/index.d.ts.map +0 -1
  259. package/dist/components/toast/index.js.map +0 -1
  260. package/dist/components/toggle/index.d.ts.map +0 -1
  261. package/dist/components/toggle/index.js.map +0 -1
  262. package/dist/components/tooltip/index.d.ts.map +0 -1
  263. package/dist/components/tooltip/index.js.map +0 -1
  264. package/dist/index.d.ts.map +0 -1
  265. package/dist/index.js.map +0 -1
  266. package/dist/types/Icon.d.ts.map +0 -1
  267. package/dist/types/Icon.js.map +0 -1
  268. package/dist/types/Style.d.ts.map +0 -1
  269. package/dist/types/Style.js.map +0 -1
  270. package/dist/types/Tone.d.ts +0 -4
  271. package/dist/types/Tone.d.ts.map +0 -1
  272. package/dist/types/Tone.js +0 -2
  273. package/dist/types/Tone.js.map +0 -1
  274. package/dist/utils/ArkStateToDataAttributes.d.ts.map +0 -1
  275. package/dist/utils/ArkStateToDataAttributes.js.map +0 -1
  276. package/dist/utils/Tone.d.ts +0 -3
  277. package/dist/utils/Tone.d.ts.map +0 -1
  278. package/dist/utils/Tone.js +0 -7
  279. package/dist/utils/Tone.js.map +0 -1
  280. package/dist/utils/useForwardClickToInput.d.ts.map +0 -1
  281. package/dist/utils/useForwardClickToInput.js.map +0 -1
  282. package/dist/utils/virtualization/useVirtualizedAutocomplete.d.ts.map +0 -1
  283. package/dist/utils/virtualization/useVirtualizedAutocomplete.js.map +0 -1
  284. package/dist/utils/virtualization/useVirtualizedCombobox.d.ts.map +0 -1
  285. package/dist/utils/virtualization/useVirtualizedCombobox.js.map +0 -1
  286. package/dist/utils/virtualization/useVirtualizedTable.d.ts.map +0 -1
  287. package/dist/utils/virtualization/useVirtualizedTable.js.map +0 -1
@@ -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,20 +36,19 @@ import { ToneProvider, useToneContext } from "../../utils/Tone.js";
36
36
  * }
37
37
  * </OtpInput.Root>
38
38
  */
39
- export const Root = /* @__PURE__ */ 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
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
  });
@@ -76,17 +75,27 @@ export const Description = /* @__PURE__ */ forwardRef(function Description({ dis
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 = /* @__PURE__ */ 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 = /* @__PURE__ */ 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
101
  export const List = /* @__PURE__ */ forwardRef(function List({ disableStyle, className, children, ...props }, ref) {
@@ -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,5 +1,5 @@
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
5
  const SizeContext = /* @__PURE__ */ createContext('medium');
@@ -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
@@ -3,9 +3,11 @@ import { Root as RadixRoot, Input as RadixInput } from '@radix-ui/react-password
3
3
  import { Input as BaseInput } from '@base-ui/react/input';
4
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";
@@ -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 {};
@@ -1,12 +1,12 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Root as RadixRoot, Input as RadixInput, Toggle as RadixToggle, Slot as RadixSlot, } from '@radix-ui/react-password-toggle-field';
3
3
  import { Input as BaseInput } from '@base-ui/react/input';
4
- import { Eye, EyeOff, LoaderCircle } from 'lucide-react';
4
+ import { Eye, EyeOff, LoaderCircle } from "../../utils/icons.js";
5
5
  import { useRef } from 'react';
6
6
  import { useForwardClickToInput } from "../../utils/useForwardClickToInput.js";
7
7
  import { cloneElement, createContext, forwardRef, useContext, useEffect, useId, useState, } from 'react';
8
8
  import { twMerge } from 'tailwind-merge';
9
- import { ToneProvider, useToneContext } from "../../utils/Tone.js";
9
+ import { readValidation, validationAttributes, validationMessageContent } from "../../utils/Validation.js";
10
10
  /**
11
11
  * 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.
12
12
  *
@@ -44,13 +44,12 @@ import { ToneProvider, useToneContext } from "../../utils/Tone.js";
44
44
  * }
45
45
  * </PasswordInput.Root>
46
46
  */
47
- export function Root({ children, id, tone = 'neutral', value, defaultValue, onValueChange, disabled = false, readOnly = false, required = false, name, form, ...props }) {
47
+ export function Root({ children, id, validation, value, defaultValue, onValueChange, disabled = false, readOnly = false, required = false, name, form, ...props }) {
48
48
  const generatedId = useId();
49
49
  const inputId = id ?? generatedId;
50
50
  const [valueInternalState, setValueInternalState] = useState(defaultValue ?? '');
51
- const [connections, setConnections] = useState({
52
- descriptionIds: [],
53
- });
51
+ // Holding the ids of Description, Error and Success, so the control announces them to screen readers through aria-describedby
52
+ const [describedByIds, setDescribedByIds] = useState([]);
54
53
  return (_jsx(RadixRoot, { ...props, id: inputId, children: _jsx(InputContext.Provider, { value: {
55
54
  inputId,
56
55
  disabled,
@@ -62,24 +61,20 @@ export function Root({ children, id, tone = 'neutral', value, defaultValue, onVa
62
61
  setValueInternalState,
63
62
  onValueChange,
64
63
  coreProps: { name, form },
65
- connections,
66
- setConnections,
67
- }, children: _jsx(ToneProvider, { value: tone, children: children }) }) }));
64
+ describedByIds,
65
+ setDescribedByIds,
66
+ validation: readValidation(validation),
67
+ }, children: children }) }));
68
68
  }
69
69
  export const Input = /* @__PURE__ */ forwardRef(function Input({ disableStyle, className, 'aria-describedby': describedBy, ...props }, ref) {
70
70
  const context = useInputContext();
71
- const tone = useToneContext();
72
71
  const inputRef = useRef(null);
72
+ // Resetting the internal value when the surrounding html form resets, since the control is always controlled by Root's value
73
73
  useEffect(() => {
74
74
  const form = inputRef.current?.form;
75
75
  if (!form || context.controlled)
76
76
  return;
77
- const reset = (event) => {
78
- queueMicrotask(() => {
79
- if (!event.defaultPrevented)
80
- context.setValueInternalState(context.defaultValue ?? '');
81
- });
82
- };
77
+ const reset = (event) => queueMicrotask(() => !event.defaultPrevented && context.setValueInternalState(context.defaultValue ?? ''));
83
78
  form.addEventListener('reset', reset);
84
79
  return () => form.removeEventListener('reset', reset);
85
80
  }, [
@@ -88,7 +83,7 @@ export const Input = /* @__PURE__ */ forwardRef(function Input({ disableStyle, c
88
83
  context.setValueInternalState,
89
84
  context.coreProps.form,
90
85
  ]);
91
- return (_jsx(RadixInput, { asChild: true, id: context.inputId, children: _jsx(BaseInput, { ...context.coreProps, ...props, id: context.inputId, disabled: context.disabled, readOnly: context.readOnly, required: context.required, value: context.value, "data-tone": tone, "aria-invalid": tone === 'invalid' || props['aria-invalid'] || undefined, "aria-describedby": [describedBy, ...context.connections.descriptionIds]
86
+ return (_jsx(RadixInput, { asChild: true, id: context.inputId, children: _jsx(BaseInput, { ...context.coreProps, ...props, id: context.inputId, disabled: context.disabled, readOnly: context.readOnly, required: context.required, value: context.value, ...validationAttributes(context.validation), "aria-invalid": context.validation.state === 'error' || props['aria-invalid'] || undefined, "aria-describedby": [describedBy, ...context.describedByIds]
92
87
  .filter(Boolean)
93
88
  .join(' ') || undefined, ref: (element) => {
94
89
  inputRef.current = element;
@@ -116,13 +111,6 @@ export const Label = /* @__PURE__ */ forwardRef(function Label({ disableStyle, c
116
111
  const context = useInputContext();
117
112
  const labelId = id ?? context.inputId + '-label';
118
113
  const attributes = usePartAttributes();
119
- useEffect(() => {
120
- context.setConnections((current) => ({ ...current, labelId }));
121
- return () => context.setConnections((current) => ({
122
- ...current,
123
- labelId: current.labelId === labelId ? undefined : current.labelId,
124
- }));
125
- }, [labelId, context.setConnections]);
126
114
  return (_jsx("label", { ...attributes, ...props, id: labelId, ref: ref, htmlFor: context.inputId, "data-component": "passwordinput-label", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
127
115
  });
128
116
  export const Description = /* @__PURE__ */ forwardRef(function Description({ disableStyle, className, id, ...props }, ref) {
@@ -130,17 +118,27 @@ export const Description = /* @__PURE__ */ forwardRef(function Description({ dis
130
118
  const attributes = usePartAttributes();
131
119
  return (_jsx("div", { ...attributes, ...props, id: messageId, ref: ref, "data-component": "passwordinput-description", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
132
120
  });
133
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
134
- export const Error = /* @__PURE__ */ forwardRef(function Error({ disableStyle, className, id, ...props }, ref) {
135
- const messageId = useMessageId(id);
136
- const attributes = usePartAttributes();
137
- return (_jsx("div", { role: "alert", "aria-atomic": "true", ...attributes, ...props, id: messageId, ref: ref, "data-component": "passwordinput-error", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
121
+ /** 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. */
122
+ export const Error = /* @__PURE__ */ forwardRef(function Error({ children, ...props }, ref) {
123
+ const context = useInputContext();
124
+ const content = validationMessageContent(context.validation, 'error', children);
125
+ if (content === undefined)
126
+ return null;
127
+ return _jsx(Message, { ...props, ref: ref, role: "alert", component: "passwordinput-error", children: content });
138
128
  });
139
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
140
- export const Success = /* @__PURE__ */ forwardRef(function Success({ disableStyle, className, id, ...props }, ref) {
129
+ /** 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. */
130
+ export const Success = /* @__PURE__ */ forwardRef(function Success({ children, ...props }, ref) {
131
+ const context = useInputContext();
132
+ const content = validationMessageContent(context.validation, 'success', children);
133
+ if (content === undefined)
134
+ return null;
135
+ return _jsx(Message, { ...props, ref: ref, role: "status", component: "passwordinput-success", children: content });
136
+ });
137
+ // The shared body of Error and Success, mounted only while they show, so only visible messages describe the password input
138
+ const Message = /* @__PURE__ */ forwardRef(function Message({ disableStyle, className, id, component, ...props }, ref) {
141
139
  const messageId = useMessageId(id);
142
140
  const attributes = usePartAttributes();
143
- return (_jsx("div", { role: "status", "aria-atomic": "true", ...attributes, ...props, id: messageId, ref: ref, "data-component": "passwordinput-success", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
141
+ return _jsx("div", { "aria-atomic": "true", ...attributes, ...props, id: messageId, ref: ref, "data-component": component, "data-style-disabled": disableStyle ? '' : undefined, className: className });
144
142
  });
145
143
  export const Addon = /* @__PURE__ */ forwardRef(function Addon({ disableStyle, className, variant = 'normal', ...props }, ref) {
146
144
  const attributes = usePartAttributes();
@@ -224,28 +222,21 @@ function useInputContext() {
224
222
  }
225
223
  function usePartAttributes() {
226
224
  const context = useInputContext();
227
- const tone = useToneContext();
228
225
  return {
229
226
  'data-disabled': context.disabled ? '' : undefined,
230
227
  'data-readonly': context.readOnly ? '' : undefined,
231
228
  'data-required': context.required ? '' : undefined,
232
- 'data-tone': tone,
229
+ ...validationAttributes(context.validation),
233
230
  };
234
231
  }
232
+ // Registering a message part's id in the control's aria-describedby while the part is mounted
235
233
  function useMessageId(id) {
234
+ const context = useInputContext();
236
235
  const generatedId = useId();
237
236
  const messageId = id ?? generatedId;
238
- const context = useInputContext();
239
237
  useEffect(() => {
240
- context.setConnections((current) => ({
241
- ...current,
242
- descriptionIds: [...current.descriptionIds, messageId],
243
- }));
244
- return () => context.setConnections((current) => ({
245
- ...current,
246
- descriptionIds: current.descriptionIds.filter((id) => id !== messageId),
247
- }));
248
- }, [messageId, context.setConnections]);
238
+ context.setDescribedByIds((current) => [...current, messageId]);
239
+ return () => context.setDescribedByIds((current) => current.filter((currentId) => currentId !== messageId));
240
+ }, [messageId, context.setDescribedByIds]);
249
241
  return messageId;
250
242
  }
251
- //# sourceMappingURL=index.js.map
@@ -1,8 +1,10 @@
1
1
  import type { StyleProps } from '../../types/Style.ts';
2
+ import type { AsChildProps } from '../../utils/asChild.ts';
2
3
  import { Popover as BasePopover } from '@base-ui/react/popover';
3
4
  import type { ComponentPropsWithRef, ReactElement } from 'react';
5
+ import type { SVGIconProps } from '../../types/Icon.ts';
4
6
  /**
5
- * OpenHandler and CloseHandler add behavior to their button children. Popup already includes its portal and positioner. Use Header/Body/Footer as needed; an Arrow is optional.
7
+ * OpenButton and CloseButton render their own buttons; pass asChild to give their behavior to your own button instead. Popup already includes its portal and positioner. Use Header/Body/Footer as needed; an Arrow is optional.
6
8
  *
7
9
  * @example Complete composition
8
10
  * import { Button, Popover } from '@central-ui/react'
@@ -10,9 +12,9 @@ import type { ComponentPropsWithRef, ReactElement } from 'react';
10
12
  * function Example() {
11
13
  * return (
12
14
  * <Popover.Root>
13
- * <Popover.OpenHandler>
15
+ * <Popover.OpenButton asChild>
14
16
  * <Button.default variant="secondary">Account</Button.default>
15
- * </Popover.OpenHandler>
17
+ * </Popover.OpenButton>
16
18
  * <Popover.Popup>
17
19
  * <Popover.Header>
18
20
  * <Popover.Title>Account</Popover.Title>
@@ -20,9 +22,9 @@ import type { ComponentPropsWithRef, ReactElement } from 'react';
20
22
  * </Popover.Header>
21
23
  * <Popover.Body>Account settings go here.</Popover.Body>
22
24
  * <Popover.Footer>
23
- * <Popover.CloseHandler>
25
+ * <Popover.CloseButton asChild>
24
26
  * <Button.default variant="primary">Done</Button.default>
25
- * </Popover.CloseHandler>
27
+ * </Popover.CloseButton>
26
28
  * </Popover.Footer>
27
29
  * </Popover.Popup>
28
30
  * </Popover.Root>
@@ -36,25 +38,17 @@ import type { ComponentPropsWithRef, ReactElement } from 'react';
36
38
  * Details
37
39
  * </Popover.Popup>
38
40
  */
39
- export declare const Root: typeof BasePopover.Root;
40
- /** Behavior only: give your child control this action. Style the child itself; this wrapper has no preset appearance or disableStyle prop. */
41
- export declare const OpenHandler: import("react").ForwardRefExoticComponent<Omit<Omit<BasePopover.Trigger.Props<unknown>, "children" | "className" | "render"> & {
41
+ export declare function Root<Payload = unknown>(props: BasePopover.Root.Props<Payload>): import("react").JSX.Element;
42
+ /** Opens the popover. Pass asChild to give this behavior to your own element, like your app's Button. */
43
+ export declare const OpenButton: import("react").ForwardRefExoticComponent<Omit<Omit<BasePopover.Trigger.Props<unknown>, "className" | "render"> & {
42
44
  className?: string;
43
- /** Supply your own accessible control. It receives the behavior; its own className owns the appearance. */
44
- children: ReactElement;
45
- }, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
45
+ } & AsChildProps & StyleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
46
46
  export type PopupProps = Omit<ComponentPropsWithRef<typeof BasePopover.Popup>, 'className'> & {
47
47
  className?: string;
48
48
  } & Pick<BasePopover.Portal.Props, 'container' | 'keepMounted'> & Pick<BasePopover.Positioner.Props, 'anchor' | 'positionMethod' | 'side' | 'sideOffset' | 'align' | 'alignOffset' | 'collisionBoundary' | 'collisionPadding' | 'sticky' | 'arrowPadding' | 'disableAnchorTracking' | 'collisionAvoidance'> & StyleProps;
49
49
  /** Already includes the portal and positioner. Keep it in the matching Root and let the native open state control visibility. */
50
- export declare function Popup({ disableStyle, container, keepMounted, anchor, positionMethod, side, sideOffset, align, alignOffset, collisionBoundary, collisionPadding, sticky, arrowPadding, disableAnchorTracking, collisionAvoidance, className, style, ...props }: PopupProps & StyleProps): import("react").JSX.Element;
50
+ export declare function Popup({ disableStyle, container, keepMounted, anchor, positionMethod, side, sideOffset, align, alignOffset, collisionBoundary, collisionPadding, sticky, arrowPadding, disableAnchorTracking, collisionAvoidance, className, style, ...props }: PopupProps): import("react").JSX.Element;
51
51
  export declare const Arrow: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").SVGProps<SVGSVGElement>, "children" | "dangerouslySetInnerHTML"> & StyleProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
52
- /** Behavior only: give your child control this action. Style the child itself; this wrapper has no preset appearance or disableStyle prop. */
53
- export declare const CloseHandler: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").PopoverCloseProps, "children" | "className" | "render"> & {
54
- className?: string;
55
- /** Supply your own accessible control. It receives the behavior; its own className owns the appearance. */
56
- children: ReactElement;
57
- }, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
58
52
  export declare const Header: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
59
53
  export declare const Body: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
60
54
  export declare const Footer: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
@@ -64,4 +58,12 @@ export declare const Title: import("react").ForwardRefExoticComponent<Omit<Omit<
64
58
  export declare const Description: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").PopoverDescriptionProps, "className"> & {
65
59
  className?: string;
66
60
  } & StyleProps, "ref"> & import("react").RefAttributes<HTMLParagraphElement>>;
67
- //# sourceMappingURL=index.d.ts.map
61
+ /** Icon-only: put just a CloseButtonIcon inside, never text like "Close". Name it for screen readers with aria-label instead, e.g. aria-label="Close". Pass asChild to give closing behavior to your own button instead, like a "Done" Button. */
62
+ export declare const CloseButton: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").PopoverCloseProps, "className" | "render"> & {
63
+ className?: string;
64
+ } & AsChildProps & StyleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
65
+ /** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
66
+ export declare const CloseButtonIcon: import("react").ForwardRefExoticComponent<Omit<SVGIconProps & {
67
+ /** Omit for the supplied default icon; pass a child only to replace it. */
68
+ children?: ReactElement<SVGIconProps>;
69
+ } & StyleProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
@@ -1,8 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { asChildRendering } from "../../utils/asChild.js";
2
3
  import { Popover as BasePopover } from '@base-ui/react/popover';
3
- import { forwardRef } from 'react';
4
+ import { cloneElement, forwardRef } from 'react';
5
+ import { twMerge } from 'tailwind-merge';
6
+ import { X } from "../../utils/icons.js";
4
7
  /**
5
- * OpenHandler and CloseHandler add behavior to their button children. Popup already includes its portal and positioner. Use Header/Body/Footer as needed; an Arrow is optional.
8
+ * OpenButton and CloseButton render their own buttons; pass asChild to give their behavior to your own button instead. Popup already includes its portal and positioner. Use Header/Body/Footer as needed; an Arrow is optional.
6
9
  *
7
10
  * @example Complete composition
8
11
  * import { Button, Popover } from '@central-ui/react'
@@ -10,9 +13,9 @@ import { forwardRef } from 'react';
10
13
  * function Example() {
11
14
  * return (
12
15
  * <Popover.Root>
13
- * <Popover.OpenHandler>
16
+ * <Popover.OpenButton asChild>
14
17
  * <Button.default variant="secondary">Account</Button.default>
15
- * </Popover.OpenHandler>
18
+ * </Popover.OpenButton>
16
19
  * <Popover.Popup>
17
20
  * <Popover.Header>
18
21
  * <Popover.Title>Account</Popover.Title>
@@ -20,9 +23,9 @@ import { forwardRef } from 'react';
20
23
  * </Popover.Header>
21
24
  * <Popover.Body>Account settings go here.</Popover.Body>
22
25
  * <Popover.Footer>
23
- * <Popover.CloseHandler>
26
+ * <Popover.CloseButton asChild>
24
27
  * <Button.default variant="primary">Done</Button.default>
25
- * </Popover.CloseHandler>
28
+ * </Popover.CloseButton>
26
29
  * </Popover.Footer>
27
30
  * </Popover.Popup>
28
31
  * </Popover.Root>
@@ -36,10 +39,13 @@ import { forwardRef } from 'react';
36
39
  * Details
37
40
  * </Popover.Popup>
38
41
  */
39
- export const Root = BasePopover.Root;
40
- /** Behavior only: give your child control this action. Style the child itself; this wrapper has no preset appearance or disableStyle prop. */
41
- export const OpenHandler = /* @__PURE__ */ forwardRef(function OpenHandler({ children, ...props }, ref) {
42
- return _jsx(BasePopover.Trigger, { ...props, ref: ref, render: children });
42
+ export function Root(props) {
43
+ return _jsx(BasePopover.Root, { ...props });
44
+ }
45
+ /** Opens the popover. Pass asChild to give this behavior to your own element, like your app's Button. */
46
+ export const OpenButton = /* @__PURE__ */ forwardRef(function OpenButton({ asChild, disableStyle, children, ...props }, ref) {
47
+ const rendering = asChildRendering({ asChild, children, component: 'popover-openbutton', disableStyle });
48
+ return _jsx(BasePopover.Trigger, { ...props, ref: ref, ...rendering });
43
49
  });
44
50
  /** Already includes the portal and positioner. Keep it in the matching Root and let the native open state control visibility. */
45
51
  export function Popup({ disableStyle, container, keepMounted, anchor, positionMethod, side = 'bottom', sideOffset = 5, align = 'start', alignOffset, collisionBoundary, collisionPadding, sticky, arrowPadding, disableAnchorTracking, collisionAvoidance, className, style, ...props }) {
@@ -54,10 +60,6 @@ export function Popup({ disableStyle, container, keepMounted, anchor, positionMe
54
60
  export const Arrow = /* @__PURE__ */ forwardRef(function Arrow({ disableStyle, className, style, ...props }, ref) {
55
61
  return (_jsxs(BasePopover.Arrow, { style: style, render: _jsx("svg", { ...props, ref: ref, "aria-hidden": true, width: "20", height: "10", viewBox: "0 0 20 10" }), "data-component": "popover-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": "popover-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": "popover-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": "popover-arrow-3" })] }));
56
62
  });
57
- /** Behavior only: give your child control this action. Style the child itself; this wrapper has no preset appearance or disableStyle prop. */
58
- export const CloseHandler = /* @__PURE__ */ forwardRef(function CloseHandler({ children, ...props }, ref) {
59
- return _jsx(BasePopover.Close, { ...props, ref: ref, render: children });
60
- });
61
63
  export const Header = /* @__PURE__ */ forwardRef(function Header({ disableStyle, className, ...props }, ref) {
62
64
  return (_jsx("div", { ...props, ref: ref, "data-component": "popover-header", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
63
65
  });
@@ -73,4 +75,21 @@ export const Title = /* @__PURE__ */ forwardRef(function Title({ disableStyle, c
73
75
  export const Description = /* @__PURE__ */ forwardRef(function Description({ disableStyle, className, ...props }, ref) {
74
76
  return (_jsx(BasePopover.Description, { ...props, ref: ref, "data-component": "popover-description", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
75
77
  });
76
- //# sourceMappingURL=index.js.map
78
+ /** Icon-only: put just a CloseButtonIcon inside, never text like "Close". Name it for screen readers with aria-label instead, e.g. aria-label="Close". Pass asChild to give closing behavior to your own button instead, like a "Done" Button. */
79
+ export const CloseButton = /* @__PURE__ */ forwardRef(function CloseButton({ asChild, disableStyle, children, ...props }, ref) {
80
+ const rendering = asChildRendering({ asChild, children, component: 'popover-closebutton', disableStyle });
81
+ return _jsx(BasePopover.Close, { ...props, ref: ref, ...rendering });
82
+ });
83
+ /** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
84
+ export const CloseButtonIcon = /* @__PURE__ */ forwardRef(function CloseButtonIcon({ disableStyle, children, className, ...props }, ref) {
85
+ return cloneElement(children ?? _jsx(X, {}), {
86
+ ...props,
87
+ ref,
88
+ 'aria-hidden': true,
89
+ ...{
90
+ 'data-component': 'popover-closebuttonicon',
91
+ 'data-style-disabled': disableStyle ? '' : undefined,
92
+ },
93
+ className: twMerge(children?.props.className, className),
94
+ });
95
+ });