@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 { 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
- export const Input = forwardRef(function Input({ disableStyle, className, 'aria-describedby': describedBy, ...props }, ref) {
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 = forwardRef(function Input({ disableStyle, className, 'aria-
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;
@@ -102,51 +97,54 @@ export const Input = forwardRef(function Input({ disableStyle, className, 'aria-
102
97
  context.setValueInternalState(nextValue);
103
98
  }, "data-component": "passwordinput-input", "data-style-disabled": disableStyle ? '' : undefined, className: className }) }));
104
99
  });
105
- export const InputGroup = forwardRef(function InputGroup({ disableStyle, className, onClick, ...props }, ref) {
100
+ export const InputGroup = /* @__PURE__ */ forwardRef(function InputGroup({ disableStyle, className, onClick, ...props }, ref) {
106
101
  const attributes = usePartAttributes();
107
102
  const forwardClick = useForwardClickToInput('input:not([type="hidden"])', onClick);
108
103
  return (_jsx("div", { ...attributes, ...props, ref: ref, onClick: forwardClick, "data-component": "passwordinput-inputgroup", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
109
104
  });
110
- export const Container = forwardRef(function Container({ disableStyle, className, ...props }, ref) {
105
+ export const Container = /* @__PURE__ */ forwardRef(function Container({ disableStyle, className, ...props }, ref) {
111
106
  const attributes = usePartAttributes();
112
107
  return (_jsx("div", { ...attributes, ...props, ref: ref, "data-component": "passwordinput-container", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
113
108
  });
114
109
  /** Labels the associated control automatically. Supply the visible text; do not wire a second label association. */
115
- export const Label = forwardRef(function Label({ disableStyle, className, id, ...props }, ref) {
110
+ export const Label = /* @__PURE__ */ forwardRef(function Label({ disableStyle, className, id, ...props }, ref) {
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
- export const Description = forwardRef(function Description({ disableStyle, className, id, ...props }, ref) {
116
+ export const Description = /* @__PURE__ */ forwardRef(function Description({ disableStyle, className, id, ...props }, ref) {
129
117
  const messageId = useMessageId(id);
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 = 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 = 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
- export const Addon = forwardRef(function Addon({ disableStyle, className, variant = 'normal', ...props }, ref) {
143
+ export const Addon = /* @__PURE__ */ forwardRef(function Addon({ disableStyle, className, variant = 'normal', ...props }, ref) {
146
144
  const attributes = usePartAttributes();
147
145
  return (_jsx("div", { ...attributes, ...props, ref: ref, "data-variant": variant, "data-component": "passwordinput-addon", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
148
146
  });
149
- export const AddonText = forwardRef(function AddonText({ disableStyle, className, ...props }, ref) {
147
+ export const AddonText = /* @__PURE__ */ forwardRef(function AddonText({ disableStyle, className, ...props }, ref) {
150
148
  const attributes = usePartAttributes();
151
149
  return (_jsx("span", { ...attributes, ...props, ref: ref, "data-component": "passwordinput-addontext", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
152
150
  });
@@ -165,18 +163,18 @@ export function AddonIcon({ disableStyle, children, className, ...props }) {
165
163
  className: twMerge(children.props.className, className),
166
164
  });
167
165
  }
168
- export const AddonButton = forwardRef(function AddonButton({ disableStyle, className, disabled, type = 'button', ...props }, ref) {
166
+ export const AddonButton = /* @__PURE__ */ forwardRef(function AddonButton({ disableStyle, className, disabled, type = 'button', ...props }, ref) {
169
167
  const context = useInputContext();
170
168
  const attributes = usePartAttributes();
171
169
  return (_jsx("button", { ...attributes, ...props, ref: ref, type: type, disabled: disabled || context.disabled || context.readOnly, "data-component": "passwordinput-addonbutton", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
172
170
  });
173
171
  /** Built-in icon; no children needed. Use it inside its matching control. */
174
- export const AddonLoadingIcon = forwardRef(function AddonLoadingIcon({ disableStyle, className, strokeWidth = 1.5, ...props }, ref) {
172
+ export const AddonLoadingIcon = /* @__PURE__ */ forwardRef(function AddonLoadingIcon({ disableStyle, className, strokeWidth = 1.5, ...props }, ref) {
175
173
  const attributes = usePartAttributes();
176
174
  return (_jsx(LoaderCircle, { ...attributes, "aria-hidden": true, ...props, ref: ref, strokeWidth: strokeWidth, "data-component": "passwordinput-addonloadingicon", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
177
175
  });
178
176
  /** Toggles password visibility automatically; do not maintain another visibility state. */
179
- export const AddonVisibilityButton = forwardRef(function AddonVisibilityButton({ disableStyle, className, disabled, id, ...props }, ref) {
177
+ export const AddonVisibilityButton = /* @__PURE__ */ forwardRef(function AddonVisibilityButton({ disableStyle, className, disabled, id, ...props }, ref) {
180
178
  const context = useInputContext();
181
179
  const attributes = usePartAttributes();
182
180
  return (_jsx(RadixToggle, { ...attributes, ...props, id: id ?? context.inputId + '-toggle', ref: ref, disabled: disabled || context.disabled || context.readOnly, "data-component": "passwordinput-addonvisibilitybutton", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
@@ -215,7 +213,7 @@ export function AddonHiddenIcon({ disableStyle, children = _jsx(Eye, {}), classN
215
213
  });
216
214
  return _jsx(RadixSlot, { visible: null, hidden: icon });
217
215
  }
218
- const InputContext = createContext(null);
216
+ const InputContext = /* @__PURE__ */ createContext(null);
219
217
  function useInputContext() {
220
218
  const context = useContext(InputContext);
221
219
  if (!context)
@@ -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 = 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 }) {
@@ -51,26 +57,39 @@ export function Popup({ disableStyle, container, keepMounted, anchor, positionMe
51
57
  ? (state) => ({ ...baseStyle, ...style(state) })
52
58
  : { ...baseStyle, ...style } }) }) }));
53
59
  }
54
- export const Arrow = forwardRef(function Arrow({ disableStyle, className, style, ...props }, ref) {
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 = forwardRef(function CloseHandler({ children, ...props }, ref) {
59
- return _jsx(BasePopover.Close, { ...props, ref: ref, render: children });
60
- });
61
- export const Header = forwardRef(function Header({ disableStyle, className, ...props }, ref) {
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
  });
64
- export const Body = forwardRef(function Body({ disableStyle, className, ...props }, ref) {
66
+ export const Body = /* @__PURE__ */ forwardRef(function Body({ disableStyle, className, ...props }, ref) {
65
67
  return (_jsx("div", { ...props, ref: ref, "data-component": "popover-body", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
66
68
  });
67
- export const Footer = forwardRef(function Footer({ disableStyle, className, ...props }, ref) {
69
+ export const Footer = /* @__PURE__ */ forwardRef(function Footer({ disableStyle, className, ...props }, ref) {
68
70
  return (_jsx("div", { ...props, ref: ref, "data-component": "popover-footer", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
69
71
  });
70
- export const Title = forwardRef(function Title({ disableStyle, className, ...props }, ref) {
72
+ export const Title = /* @__PURE__ */ forwardRef(function Title({ disableStyle, className, ...props }, ref) {
71
73
  return (_jsx(BasePopover.Title, { ...props, ref: ref, "data-component": "popover-title", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
72
74
  });
73
- export const Description = forwardRef(function Description({ disableStyle, className, ...props }, ref) {
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
+ });
@@ -2,9 +2,11 @@ import type { StyleProps } from '../../types/Style.ts';
2
2
  import { RadioGroup as BaseRadioGroup } from '@base-ui/react/radio-group';
3
3
  import { Radio as BaseRadio } from '@base-ui/react/radio';
4
4
  import type { ComponentProps, ReactNode } from 'react';
5
+ import type { Validation } from '../../types/Validation.ts';
6
+ import type { ValidationMessageChildren } from '../../utils/Validation.ts';
5
7
  export type RootProps<Value = string> = Omit<BaseRadioGroup.Props<Value>, 'render' | 'className'> & {
6
- /** Choose the visual tone. This does not validate data or show/hide feedback messages. */
7
- tone?: 'neutral' | 'valid' | 'invalid';
8
+ /** The group's validation state, with an optional message: `'error'` styles it as invalid, `['error', 'Pick a plan']` also shows that message in Error. Same for `'success'` and Success. Omit it for a neutral group. */
9
+ validation?: Validation;
8
10
  };
9
11
  /**
10
12
  * Root owns the chosen value. For each choice keep Item, ItemButton, ItemIndicator, and ItemLabel together. The indicator follows selection automatically; do not manage a separate checked state for each item.
@@ -62,7 +64,7 @@ export type RootProps<Value = string> = Omit<BaseRadioGroup.Props<Value>, 'rende
62
64
  * }
63
65
  * </Radio.Root>
64
66
  */
65
- export declare function Root<Value>({ children, tone, ...props }: RootProps<Value>): import("react").JSX.Element;
67
+ export declare function Root<Value>({ children, validation, ...props }: RootProps<Value>): import("react").JSX.Element;
66
68
  export declare const Container: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
67
69
  export declare const List: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
68
70
  /** Labels the associated control automatically. Supply the visible text; do not wire a second label association. */
@@ -71,7 +73,7 @@ type ItemCoreKeys = 'value' | 'disabled' | 'readOnly' | 'required' | 'inputRef';
71
73
  export type ItemProps<Value = string> = Omit<ComponentProps<'div'>, 'children'> & Pick<BaseRadio.Root.Props<Value>, ItemCoreKeys> & {
72
74
  children: ReactNode;
73
75
  } & StyleProps;
74
- export declare function Item<Value>({ disableStyle, children, value, disabled, readOnly, required, inputRef, id, className, ...props }: ItemProps<Value> & StyleProps): import("react").JSX.Element;
76
+ export declare function Item<Value>({ disableStyle, children, value, disabled, readOnly, required, inputRef, id, className, ...props }: ItemProps<Value>): import("react").JSX.Element;
75
77
  export declare const ItemButton: import("react").ForwardRefExoticComponent<Omit<Omit<BaseRadio.Root.Props<any>, "className" | "id" | "disabled" | "value" | "render" | "nativeButton" | "required" | "readOnly" | "inputRef"> & {
76
78
  className?: string;
77
79
  } & StyleProps, "ref"> & import("react").RefAttributes<HTMLElement>>;
@@ -82,9 +84,11 @@ export declare const ItemIndicator: import("react").ForwardRefExoticComponent<Om
82
84
  export declare const ItemLabel: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, "htmlFor"> & StyleProps, "ref"> & import("react").RefAttributes<HTMLLabelElement>>;
83
85
  export declare const ItemDescription: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLSpanElement> & import("react").HTMLAttributes<HTMLSpanElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
84
86
  export declare const Description: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
85
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
86
- export declare const Error: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
87
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
88
- export declare const Success: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
87
+ type MessageProps = Omit<ComponentProps<'div'>, 'children'> & StyleProps & {
88
+ children?: ValidationMessageChildren;
89
+ };
90
+ /** 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. */
91
+ export declare const Error: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
92
+ /** 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. */
93
+ export declare const Success: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
89
94
  export {};
90
- //# sourceMappingURL=index.d.ts.map