@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,11 +1,11 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Input as BaseInput } from '@base-ui/react/input';
3
- import { LoaderCircle } from 'lucide-react';
3
+ import { LoaderCircle } from "../../utils/icons.js";
4
4
  import { useRef } from 'react';
5
5
  import { useForwardClickToInput } from "../../utils/useForwardClickToInput.js";
6
6
  import { cloneElement, createContext, forwardRef, useContext, useEffect, useId, useState, } from 'react';
7
7
  import { twMerge } from 'tailwind-merge';
8
- import { ToneProvider, useToneContext } from "../../utils/Tone.js";
8
+ import { readValidation, validationAttributes, validationMessageContent } from "../../utils/Validation.js";
9
9
  /**
10
10
  * Keep value, name, and validation configuration on Root. Textarea is the editable control inside TextareaGroup. Optional Addon parts hold your supporting text or actions; they do not implement submission.
11
11
  *
@@ -39,12 +39,11 @@ import { ToneProvider, useToneContext } from "../../utils/Tone.js";
39
39
  * )
40
40
  * }
41
41
  */
42
- export function Root({ children, id, tone = 'neutral', value, defaultValue, onValueChange, disabled = false, readOnly = false, required = false, ...coreProps }) {
42
+ export function Root({ children, id, validation, value, defaultValue, onValueChange, disabled = false, readOnly = false, required = false, ...coreProps }) {
43
43
  const generatedId = useId();
44
44
  const [valueInternalState, setValueInternalState] = useState(defaultValue ?? '');
45
- const [connections, setConnections] = useState({
46
- descriptionIds: [],
47
- });
45
+ // Holding the ids of Description, Error and Success, so the control announces them to screen readers through aria-describedby
46
+ const [describedByIds, setDescribedByIds] = useState([]);
48
47
  return (_jsx(InputContext.Provider, { value: {
49
48
  inputId: id ?? generatedId,
50
49
  disabled,
@@ -56,24 +55,20 @@ export function Root({ children, id, tone = 'neutral', value, defaultValue, onVa
56
55
  controlled: value !== undefined,
57
56
  onValueChange,
58
57
  coreProps,
59
- connections,
60
- setConnections,
61
- }, children: _jsx(ToneProvider, { value: tone, children: children }) }));
58
+ describedByIds,
59
+ setDescribedByIds,
60
+ validation: readValidation(validation),
61
+ }, children: children }));
62
62
  }
63
- export const Textarea = forwardRef(function Textarea({ disableStyle, className, onChange, 'aria-describedby': describedBy, ...props }, ref) {
63
+ export const Textarea = /* @__PURE__ */ forwardRef(function Textarea({ disableStyle, className, 'aria-describedby': describedBy, ...props }, ref) {
64
64
  const context = useInputContext();
65
- const tone = useToneContext();
66
65
  const inputRef = useRef(null);
66
+ // Resetting the internal value when the surrounding html form resets, since the control is always controlled by Root's value
67
67
  useEffect(() => {
68
68
  const form = inputRef.current?.form;
69
69
  if (!form || context.controlled)
70
70
  return;
71
- const reset = (event) => {
72
- queueMicrotask(() => {
73
- if (!event.defaultPrevented)
74
- context.setValueInternalState(context.defaultValue ?? '');
75
- });
76
- };
71
+ const reset = (event) => queueMicrotask(() => !event.defaultPrevented && context.setValueInternalState(context.defaultValue ?? ''));
77
72
  form.addEventListener('reset', reset);
78
73
  return () => form.removeEventListener('reset', reset);
79
74
  }, [
@@ -82,7 +77,7 @@ export const Textarea = forwardRef(function Textarea({ disableStyle, className,
82
77
  context.setValueInternalState,
83
78
  context.coreProps.form,
84
79
  ]);
85
- return (_jsx(BaseInput, { ...context.coreProps, render: _jsx("textarea", { ...props, onChange: onChange }), 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]
80
+ return (_jsx(BaseInput, { ...context.coreProps, render: _jsx("textarea", { ...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]
86
81
  .filter(Boolean)
87
82
  .join(' ') || undefined, ref: (element) => {
88
83
  inputRef.current = element;
@@ -96,51 +91,54 @@ export const Textarea = forwardRef(function Textarea({ disableStyle, className,
96
91
  context.setValueInternalState(nextValue);
97
92
  }, "data-component": "textarea-textarea", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
98
93
  });
99
- export const TextareaGroup = forwardRef(function TextareaGroup({ disableStyle, className, onClick, ...props }, ref) {
94
+ export const TextareaGroup = /* @__PURE__ */ forwardRef(function TextareaGroup({ disableStyle, className, onClick, ...props }, ref) {
100
95
  const attributes = usePartAttributes();
101
96
  const forwardClick = useForwardClickToInput('textarea', onClick);
102
97
  return (_jsx("div", { ...attributes, ...props, ref: ref, onClick: forwardClick, "data-component": "textarea-textareagroup", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
103
98
  });
104
- export const Container = forwardRef(function Container({ disableStyle, className, ...props }, ref) {
99
+ export const Container = /* @__PURE__ */ forwardRef(function Container({ disableStyle, className, ...props }, ref) {
105
100
  const attributes = usePartAttributes();
106
101
  return (_jsx("div", { ...attributes, ...props, ref: ref, "data-component": "textarea-container", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
107
102
  });
108
103
  /** Labels the associated control automatically. Supply the visible text; do not wire a second label association. */
109
- export const Label = forwardRef(function Label({ disableStyle, className, id, ...props }, ref) {
104
+ export const Label = /* @__PURE__ */ forwardRef(function Label({ disableStyle, className, id, ...props }, ref) {
110
105
  const context = useInputContext();
111
106
  const labelId = id ?? context.inputId + '-label';
112
107
  const attributes = usePartAttributes();
113
- useEffect(() => {
114
- context.setConnections((current) => ({ ...current, labelId }));
115
- return () => context.setConnections((current) => ({
116
- ...current,
117
- labelId: current.labelId === labelId ? undefined : current.labelId,
118
- }));
119
- }, [labelId, context.setConnections]);
120
108
  return (_jsx("label", { ...attributes, ...props, id: labelId, ref: ref, htmlFor: context.inputId, "data-component": "textarea-label", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
121
109
  });
122
- export const Description = forwardRef(function Description({ disableStyle, className, id, ...props }, ref) {
110
+ export const Description = /* @__PURE__ */ forwardRef(function Description({ disableStyle, className, id, ...props }, ref) {
123
111
  const messageId = useMessageId(id);
124
112
  const attributes = usePartAttributes();
125
113
  return (_jsx("div", { ...attributes, ...props, id: messageId, ref: ref, "data-component": "textarea-description", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
126
114
  });
127
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
128
- export const Error = forwardRef(function Error({ disableStyle, className, id, ...props }, ref) {
129
- const messageId = useMessageId(id);
130
- const attributes = usePartAttributes();
131
- return (_jsx("div", { role: "alert", "aria-atomic": "true", ...attributes, ...props, id: messageId, ref: ref, "data-component": "textarea-error", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
115
+ /** 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. */
116
+ export const Error = /* @__PURE__ */ forwardRef(function Error({ children, ...props }, ref) {
117
+ const context = useInputContext();
118
+ const content = validationMessageContent(context.validation, 'error', children);
119
+ if (content === undefined)
120
+ return null;
121
+ return _jsx(Message, { ...props, ref: ref, role: "alert", component: "textarea-error", children: content });
132
122
  });
133
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
134
- export const Success = forwardRef(function Success({ disableStyle, className, id, ...props }, ref) {
123
+ /** 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. */
124
+ export const Success = /* @__PURE__ */ forwardRef(function Success({ children, ...props }, ref) {
125
+ const context = useInputContext();
126
+ const content = validationMessageContent(context.validation, 'success', children);
127
+ if (content === undefined)
128
+ return null;
129
+ return _jsx(Message, { ...props, ref: ref, role: "status", component: "textarea-success", children: content });
130
+ });
131
+ // The shared body of Error and Success, mounted only while they show, so only visible messages describe the textarea
132
+ const Message = /* @__PURE__ */ forwardRef(function Message({ disableStyle, className, id, component, ...props }, ref) {
135
133
  const messageId = useMessageId(id);
136
134
  const attributes = usePartAttributes();
137
- return (_jsx("div", { role: "status", "aria-atomic": "true", ...attributes, ...props, id: messageId, ref: ref, "data-component": "textarea-success", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
135
+ return _jsx("div", { "aria-atomic": "true", ...attributes, ...props, id: messageId, ref: ref, "data-component": component, "data-style-disabled": disableStyle ? '' : undefined, className: className });
138
136
  });
139
- export const Addon = forwardRef(function Addon({ disableStyle, className, variant = 'normal', ...props }, ref) {
137
+ export const Addon = /* @__PURE__ */ forwardRef(function Addon({ disableStyle, className, variant = 'normal', ...props }, ref) {
140
138
  const attributes = usePartAttributes();
141
139
  return (_jsx("div", { ...attributes, ...props, ref: ref, "data-variant": variant, "data-component": "textarea-addon", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
142
140
  });
143
- export const AddonText = forwardRef(function AddonText({ disableStyle, className, ...props }, ref) {
141
+ export const AddonText = /* @__PURE__ */ forwardRef(function AddonText({ disableStyle, className, ...props }, ref) {
144
142
  const attributes = usePartAttributes();
145
143
  return (_jsx("span", { ...attributes, ...props, ref: ref, "data-component": "textarea-addontext", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
146
144
  });
@@ -159,17 +157,17 @@ export function AddonIcon({ disableStyle, children, className, ...props }) {
159
157
  className: twMerge(children.props.className, className),
160
158
  });
161
159
  }
162
- export const AddonButton = forwardRef(function AddonButton({ disableStyle, className, disabled, type = 'button', ...props }, ref) {
160
+ export const AddonButton = /* @__PURE__ */ forwardRef(function AddonButton({ disableStyle, className, disabled, type = 'button', ...props }, ref) {
163
161
  const context = useInputContext();
164
162
  const attributes = usePartAttributes();
165
163
  return (_jsx("button", { ...attributes, ...props, ref: ref, type: type, disabled: disabled || context.disabled || context.readOnly, "data-component": "textarea-addonbutton", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
166
164
  });
167
165
  /** Built-in icon; no children needed. Use it inside its matching control. */
168
- export const AddonLoadingIcon = forwardRef(function AddonLoadingIcon({ disableStyle, className, strokeWidth = 1.5, ...props }, ref) {
166
+ export const AddonLoadingIcon = /* @__PURE__ */ forwardRef(function AddonLoadingIcon({ disableStyle, className, strokeWidth = 1.5, ...props }, ref) {
169
167
  const attributes = usePartAttributes();
170
168
  return (_jsx(LoaderCircle, { ...attributes, "aria-hidden": true, ...props, ref: ref, strokeWidth: strokeWidth, "data-component": "textarea-addonloadingicon", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
171
169
  });
172
- const InputContext = createContext(null);
170
+ const InputContext = /* @__PURE__ */ createContext(null);
173
171
  function useInputContext() {
174
172
  const context = useContext(InputContext);
175
173
  if (!context)
@@ -178,28 +176,21 @@ function useInputContext() {
178
176
  }
179
177
  function usePartAttributes() {
180
178
  const context = useInputContext();
181
- const tone = useToneContext();
182
179
  return {
183
180
  'data-disabled': context.disabled ? '' : undefined,
184
181
  'data-readonly': context.readOnly ? '' : undefined,
185
182
  'data-required': context.required ? '' : undefined,
186
- 'data-tone': tone,
183
+ ...validationAttributes(context.validation),
187
184
  };
188
185
  }
186
+ // Registering a message part's id in the control's aria-describedby while the part is mounted
189
187
  function useMessageId(id) {
188
+ const context = useInputContext();
190
189
  const generatedId = useId();
191
190
  const messageId = id ?? generatedId;
192
- const context = useInputContext();
193
191
  useEffect(() => {
194
- context.setConnections((current) => ({
195
- ...current,
196
- descriptionIds: [...current.descriptionIds, messageId],
197
- }));
198
- return () => context.setConnections((current) => ({
199
- ...current,
200
- descriptionIds: current.descriptionIds.filter((id) => id !== messageId),
201
- }));
202
- }, [messageId, context.setConnections]);
192
+ context.setDescribedByIds((current) => [...current, messageId]);
193
+ return () => context.setDescribedByIds((current) => current.filter((currentId) => currentId !== messageId));
194
+ }, [messageId, context.setDescribedByIds]);
203
195
  return messageId;
204
196
  }
205
- //# sourceMappingURL=index.js.map
@@ -2,6 +2,9 @@ import type { StyleProps } from '../../types/Style.ts';
2
2
  import type { ComponentProps, HTMLAttributes, ReactElement } from 'react';
3
3
  /**
4
4
  * Adds preset styling to one link child without rendering a wrapper or handling navigation.
5
+ * Use it for a link presented as text, like "Read the guide" or "Create account" inside a
6
+ * sentence. To make a whole item clickable (a card, a list row), use your router's bare Link
7
+ * directly instead, without TextLink.
5
8
  * Pass a native anchor or your router's Link; put the destination and navigation props
6
9
  * on that child. Custom link components must forward className, style, and data-*
7
10
  * attributes to their anchor. Supply one element, not text, a fragment, or a list.
@@ -36,4 +39,3 @@ export default function TextLink({ disableStyle, children, className, style, ...
36
39
  */
37
40
  children: ReactElement<ComponentProps<'a'>>;
38
41
  }): ReactElement<import("react").DetailedHTMLProps<import("react").AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, string | import("react").JSXElementConstructor<any>>;
39
- //# sourceMappingURL=index.d.ts.map
@@ -2,6 +2,9 @@ import { cloneElement } from 'react';
2
2
  import { twMerge } from 'tailwind-merge';
3
3
  /**
4
4
  * Adds preset styling to one link child without rendering a wrapper or handling navigation.
5
+ * Use it for a link presented as text, like "Read the guide" or "Create account" inside a
6
+ * sentence. To make a whole item clickable (a card, a list row), use your router's bare Link
7
+ * directly instead, without TextLink.
5
8
  * Pass a native anchor or your router's Link; put the destination and navigation props
6
9
  * on that child. Custom link components must forward className, style, and data-*
7
10
  * attributes to their anchor. Supply one element, not text, a fragment, or a list.
@@ -31,6 +34,7 @@ import { twMerge } from 'tailwind-merge';
31
34
  export default function TextLink({ disableStyle, children, className, style, ...props }) {
32
35
  return cloneElement(children, {
33
36
  ...props,
37
+ // Spread from an object so the data-* keys pass the element props' excess property check
34
38
  ...{
35
39
  'data-component': 'textlink-textlink',
36
40
  'data-style-disabled': disableStyle ? '' : undefined,
@@ -39,4 +43,3 @@ export default function TextLink({ disableStyle, children, className, style, ...
39
43
  style: { ...children.props.style, ...style },
40
44
  });
41
45
  }
42
- //# sourceMappingURL=index.js.map
@@ -1,4 +1,5 @@
1
1
  import type { StyleProps } from '../../types/Style.ts';
2
+ import type { AsChildProps } from '../../utils/asChild.ts';
2
3
  import { Toast as BaseToast } from '@base-ui/react/toast';
3
4
  import type { ComponentProps, ReactElement, ReactNode } from 'react';
4
5
  export type ProviderProps = Omit<BaseToast.Provider.Props, 'toastManager'> & Pick<BaseToast.Viewport.Props, 'style'> & {
@@ -66,9 +67,7 @@ export declare function Root({ tone, children, }: {
66
67
  export type ToastProps = Omit<BaseToast.Root.Props, 'toast' | 'className'> & {
67
68
  className?: string;
68
69
  } & StyleProps;
69
- export declare const Toast: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").ToastRootProps, "className" | "toast"> & {
70
- className?: string;
71
- } & StyleProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
70
+ export declare const Toast: import("react").ForwardRefExoticComponent<Omit<ToastProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
72
71
  /** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
73
72
  export declare function Icon({ disableStyle, children, className, ...props }: (Omit<ComponentProps<'svg'>, 'children'> & {
74
73
  /** Omit for the supplied default icon; pass a child only to replace it. */
@@ -82,18 +81,14 @@ export declare const Title: import("react").ForwardRefExoticComponent<Omit<Omit<
82
81
  export declare const Description: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").ToastDescriptionProps, "className"> & {
83
82
  className?: string;
84
83
  } & StyleProps, "ref"> & import("react").RefAttributes<HTMLParagraphElement>>;
85
- /** Behavior only: give your child control this action. Style the child itself; this wrapper has no preset appearance or disableStyle prop. */
86
- export declare const CloseHandler: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").ToastCloseProps, "children" | "className" | "render"> & {
87
- className?: string;
88
- /** Supply your own accessible control. It receives the behavior; its own className owns the appearance. */
89
- children: ReactElement;
90
- }, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
91
- export declare const CloseButton: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").ToastCloseProps, "className"> & {
84
+ /** Icon-only: put just a CloseButtonIcon inside, never text like "Close". It is already named "Dismiss notification" for screen readers. Pass asChild to give dismissing behavior to your own button instead, like a "Dismiss" Button, which then names itself. */
85
+ export declare const CloseButton: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").ToastCloseProps, "className" | "render"> & {
92
86
  className?: string;
93
- } & StyleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
94
- export declare const ActionButton: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").ToastActionProps, "className"> & {
87
+ } & AsChildProps & StyleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
88
+ /** Runs the toast's action. Pass asChild to give this behavior to your own button instead; it keeps the state data attributes but none of this part's styling. */
89
+ export declare const ActionButton: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").ToastActionProps, "className" | "render"> & {
95
90
  className?: string;
96
- } & StyleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
91
+ } & AsChildProps & StyleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
97
92
  /** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
98
93
  export declare function CloseButtonIcon({ disableStyle, children, className, ...props }: (Omit<ComponentProps<'svg'>, 'children'> & {
99
94
  /** Omit for the supplied default icon; pass a child only to replace it. */
@@ -108,4 +103,3 @@ type NotificationData = {
108
103
  [key: string]: unknown;
109
104
  };
110
105
  export {};
111
- //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { asChildRendering } from "../../utils/asChild.js";
2
3
  import { Toast as BaseToast } from '@base-ui/react/toast';
3
- import { CircleCheck, Info, TriangleAlert, X } from 'lucide-react';
4
+ import { CircleCheck, Info, TriangleAlert, X } from "../../utils/icons.js";
4
5
  import { cloneElement, createContext, forwardRef, useContext, useEffect, useState, } from 'react';
5
6
  import { twMerge } from 'tailwind-merge';
6
7
  /**
@@ -73,41 +74,32 @@ export function Show(render, options) {
73
74
  export function Root({ tone = 'neutral', children, }) {
74
75
  return _jsx(ToneContext.Provider, { value: tone, children: children });
75
76
  }
76
- export const Toast = forwardRef(function Toast({ disableStyle, className, style, children, ...props }, ref) {
77
+ export const Toast = /* @__PURE__ */ forwardRef(function Toast({ disableStyle, className, style, children, ...props }, ref) {
77
78
  const notification = useNotificationContext();
78
79
  const tone = useContext(ToneContext);
79
80
  return (_jsx(BaseToast.Root, { ...props, ref: ref, toast: notification, "data-tone": tone, "data-component": "toast-toast", "data-style-disabled": disableStyle ? '' : undefined, className: className, style: (state) => {
80
- // Base UI measures heights and provides offsets; the legacy stack adds a 16px gap.
81
- const offsetY = state.expanded
82
- ? 'calc(-1 * (var(--toast-offset-y, 0px) + var(--toast-index) * 16px))'
83
- : 'calc(var(--toast-index) * -16px)';
84
81
  const starting = state.transitionStatus === 'starting';
85
82
  const ending = state.transitionStatus === 'ending';
86
- const horizontalExit = ending &&
87
- (state.swipeDirection === 'left' ||
88
- state.swipeDirection === 'right');
89
- const x = horizontalExit
90
- ? 'calc(var(--toast-swipe-movement-x, 0px) + ' +
91
- (state.swipeDirection === 'left' ? '-150%' : '150%') +
92
- ')'
93
- : 'var(--toast-swipe-movement-x, 0px)';
94
- const y = starting
95
- ? '150%'
96
- : ending && !horizontalExit
97
- ? 'calc(var(--toast-swipe-movement-y, 0px) + ' +
98
- (state.swipeDirection === 'up' ? '-150%' : '150%') +
99
- ')'
100
- : 'calc(' + offsetY + ' + var(--toast-swipe-movement-y, 0px))';
83
+ const horizontalExit = ending && (state.swipeDirection === 'left' || state.swipeDirection === 'right');
84
+ // Following the finger horizontally, and leaving off-screen on the swiped side
85
+ const x = (() => {
86
+ if (!horizontalExit)
87
+ return 'var(--toast-swipe-movement-x, 0px)';
88
+ return `calc(var(--toast-swipe-movement-x, 0px) + ${state.swipeDirection === 'left' ? '-150%' : '150%'})`;
89
+ })();
90
+ // Entering from below, leaving off-screen vertically, or else stacking: Base UI measures heights and provides offsets, and the legacy stack adds a 16px gap
91
+ const y = (() => {
92
+ if (starting)
93
+ return '150%';
94
+ if (ending && !horizontalExit)
95
+ return `calc(var(--toast-swipe-movement-y, 0px) + ${state.swipeDirection === 'up' ? '-150%' : '150%'})`;
96
+ const offsetY = state.expanded ? 'calc(-1 * (var(--toast-offset-y, 0px) + var(--toast-index) * 16px))' : 'calc(var(--toast-index) * -16px)';
97
+ return `calc(${offsetY} + var(--toast-swipe-movement-y, 0px))`;
98
+ })();
99
+ // Collapsed toasts behind the front one shrink a little each
100
+ const scale = state.expanded ? '1' : 'max(0, calc(1 - var(--toast-index) * 0.05))';
101
101
  return {
102
- transform: 'translateX(' +
103
- x +
104
- ') translateY(' +
105
- y +
106
- ') scale(' +
107
- (state.expanded
108
- ? '1'
109
- : 'max(0, calc(1 - var(--toast-index) * 0.05))') +
110
- ')',
102
+ transform: `translateX(${x}) translateY(${y}) scale(${scale})`,
111
103
  transformOrigin: 'bottom center',
112
104
  zIndex: 'calc(1000 - var(--toast-index))',
113
105
  height: state.expanded
@@ -127,10 +119,17 @@ export const Toast = forwardRef(function Toast({ disableStyle, className, style,
127
119
  /** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
128
120
  export function Icon({ disableStyle, children, className, ...props }) {
129
121
  const tone = useContext(ToneContext);
130
- const icon = children ??
131
- (tone === 'success' ? (_jsx(CircleCheck, {})) : tone === 'error' ? (_jsx(TriangleAlert, {})) : (_jsx(Info, {})));
122
+ // Choosing the tone's default icon, unless one is supplied
123
+ const icon = (() => {
124
+ if (children)
125
+ return children;
126
+ if (tone === 'success')
127
+ return _jsx(CircleCheck, {});
128
+ if (tone === 'error')
129
+ return _jsx(TriangleAlert, {});
130
+ return _jsx(Info, {});
131
+ })();
132
132
  return cloneElement(icon, {
133
- ...icon.props,
134
133
  ...props,
135
134
  'aria-hidden': true,
136
135
  'data-tone': tone,
@@ -142,27 +141,28 @@ export function Icon({ disableStyle, children, className, ...props }) {
142
141
  strokeWidth: props.strokeWidth ?? icon.props.strokeWidth ?? 1.8,
143
142
  });
144
143
  }
145
- export const Title = forwardRef(function Title({ disableStyle, className, ...props }, ref) {
144
+ export const Title = /* @__PURE__ */ forwardRef(function Title({ disableStyle, className, ...props }, ref) {
146
145
  return (_jsx(BaseToast.Title, { ...props, ref: ref, "data-component": "toast-title", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
147
146
  });
148
- export const Description = forwardRef(function Description({ disableStyle, className, ...props }, ref) {
147
+ export const Description = /* @__PURE__ */ forwardRef(function Description({ disableStyle, className, ...props }, ref) {
149
148
  return (_jsx(BaseToast.Description, { ...props, ref: ref, "data-component": "toast-description", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
150
149
  });
151
- /** Behavior only: give your child control this action. Style the child itself; this wrapper has no preset appearance or disableStyle prop. */
152
- export const CloseHandler = forwardRef(function CloseHandler({ children, ...props }, ref) {
153
- return (_jsx(BaseToast.Close, { ...props, ref: ref, render: children, className: props.className }));
150
+ /** Icon-only: put just a CloseButtonIcon inside, never text like "Close". It is already named "Dismiss notification" for screen readers. Pass asChild to give dismissing behavior to your own button instead, like a "Dismiss" Button, which then names itself. */
151
+ export const CloseButton = /* @__PURE__ */ forwardRef(function CloseButton({ asChild, disableStyle, children, ...props }, ref) {
152
+ // Naming the icon-only button for screen readers, while the consumer's own button names itself
153
+ const ariaLabel = asChild ? undefined : 'Dismiss notification';
154
+ const rendering = asChildRendering({ asChild, children, component: 'toast-closebutton', disableStyle });
155
+ return _jsx(BaseToast.Close, { "aria-label": ariaLabel, ...props, ref: ref, ...rendering });
154
156
  });
155
- export const CloseButton = forwardRef(function CloseButton({ disableStyle, className, ...props }, ref) {
156
- return (_jsx(BaseToast.Close, { "aria-label": "Dismiss notification", ...props, ref: ref, "data-component": "toast-closebutton", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
157
- });
158
- export const ActionButton = forwardRef(function ActionButton({ disableStyle, className, ...props }, ref) {
159
- return (_jsx(BaseToast.Action, { ...props, ref: ref, "data-component": "toast-actionbutton", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
157
+ /** Runs the toast's action. Pass asChild to give this behavior to your own button instead; it keeps the state data attributes but none of this part's styling. */
158
+ export const ActionButton = /* @__PURE__ */ forwardRef(function ActionButton({ asChild, disableStyle, children, ...props }, ref) {
159
+ const rendering = asChildRendering({ asChild, children, component: 'toast-actionbutton', disableStyle });
160
+ return _jsx(BaseToast.Action, { ...props, ref: ref, ...rendering });
160
161
  });
161
162
  /** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
162
163
  export function CloseButtonIcon({ disableStyle, children = _jsx(X, {}), className, ...props }) {
163
164
  const tone = useContext(ToneContext);
164
165
  return cloneElement(children, {
165
- ...children.props,
166
166
  ...props,
167
167
  'aria-hidden': true,
168
168
  'data-tone': tone,
@@ -176,8 +176,10 @@ export function CloseButtonIcon({ disableStyle, children = _jsx(X, {}), classNam
176
176
  }
177
177
  // Private: every callback-rendered composition receives the native object required by Toast.Root.
178
178
  function Notifications({ className, style, }) {
179
- const { toasts } = BaseToast.useToastManager();
180
- const visible = toasts.filter((notification) => !notification.limited && notification.transitionStatus !== 'ending');
179
+ const toastManager = BaseToast.useToastManager();
180
+ const visible = toastManager.toasts.filter((notification) => !notification.limited && notification.transitionStatus !== 'ending');
181
+ // The stack's 16px gaps between the visible toasts
182
+ const gaps = Math.max(0, visible.length - 1) * 16;
181
183
  return (_jsx(BaseToast.Portal, { children: _jsx(BaseToast.Viewport, { className: className, style: (state) => ({
182
184
  position: 'fixed',
183
185
  bottom: 24,
@@ -185,21 +187,19 @@ function Notifications({ className, style, }) {
185
187
  transform: 'translateX(-50%)',
186
188
  width: 'min(400px, calc(100vw - 48px))',
187
189
  zIndex: 1000,
188
- height: state.expanded
189
- ? visible.reduce((total, notification) => total + (notification.height ?? 0), 0) +
190
- Math.max(0, visible.length - 1) * 16
191
- : (visible[0]?.height ?? 0) + Math.max(0, visible.length - 1) * 16,
190
+ // Expanded, the viewport fits every visible toast, otherwise only the front one
191
+ height: (state.expanded ? visible.reduce((total, notification) => total + (notification.height ?? 0), 0) : (visible[0]?.height ?? 0)) + gaps,
192
192
  pointerEvents: visible.length ? 'auto' : 'none',
193
193
  ...(typeof style === 'function' ? style(state) : style),
194
- }), children: toasts.map((notification) => (_jsx(NotificationContext.Provider, { value: notification, children: notification.data.render() }, notification.id))) }) }));
194
+ }), children: toastManager.toasts.map((notification) => (_jsx(NotificationContext.Provider, { value: notification, children: notification.data.render() }, notification.id))) }) }));
195
195
  }
196
196
  let activeManager;
197
- const NotificationContext = createContext(null);
198
- const ToneContext = createContext('neutral');
197
+ const NotificationContext =
198
+ /* @__PURE__ */ createContext(null);
199
+ const ToneContext = /* @__PURE__ */ createContext('neutral');
199
200
  function useNotificationContext() {
200
201
  const notification = useContext(NotificationContext);
201
202
  if (!notification)
202
203
  throw new Error('Toast.Toast must be rendered by Toast.Show');
203
204
  return notification;
204
205
  }
205
- //# sourceMappingURL=index.js.map
@@ -2,7 +2,7 @@ import type { StyleProps } from '../../types/Style.ts';
2
2
  import { Toggle as BaseToggle } from '@base-ui/react/toggle';
3
3
  import type { ReactElement } from 'react';
4
4
  import type { ButtonProps } from '../button/index.tsx';
5
- import type { LucideProps } from 'lucide-react';
5
+ import type { SVGIconProps } from '../../types/Icon.ts';
6
6
  /**
7
7
  * Root is the interactive toggle button. ActiveIcon and InactiveIcon switch automatically with pressed state; do not conditionally render them yourself.
8
8
  *
@@ -29,13 +29,12 @@ export declare const Root: import("react").ForwardRefExoticComponent<Omit<Omit<B
29
29
  size?: ButtonProps["size"];
30
30
  } & StyleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
31
31
  /** Render beside InactiveIcon inside Root. It automatically appears only while pressed; supply the decorative icon without another visibility condition. */
32
- export declare const ActiveIcon: import("react").ForwardRefExoticComponent<Omit<LucideProps & {
32
+ export declare const ActiveIcon: import("react").ForwardRefExoticComponent<Omit<SVGIconProps & {
33
33
  /** Supply the decorative icon; the wrapper forwards the relevant state and preserves its classes. */
34
- children: ReactElement<LucideProps>;
34
+ children: ReactElement<SVGIconProps>;
35
35
  } & StyleProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
36
36
  /** Render beside ActiveIcon inside Root. It automatically appears only while unpressed; supply the decorative icon without another visibility condition. */
37
- export declare const InactiveIcon: import("react").ForwardRefExoticComponent<Omit<LucideProps & {
37
+ export declare const InactiveIcon: import("react").ForwardRefExoticComponent<Omit<SVGIconProps & {
38
38
  /** Supply the decorative icon; the wrapper forwards the relevant state and preserves its classes. */
39
- children: ReactElement<LucideProps>;
39
+ children: ReactElement<SVGIconProps>;
40
40
  } & StyleProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
41
- //# sourceMappingURL=index.d.ts.map
@@ -22,7 +22,7 @@ import { twMerge } from 'tailwind-merge';
22
22
  * )
23
23
  * }
24
24
  */
25
- export const Root = forwardRef(function Root({ children, className, disableStyle, size = 'medium', pressed, defaultPressed = false, onPressedChange, disabled = false, ...props }, ref) {
25
+ export const Root = /* @__PURE__ */ forwardRef(function Root({ children, className, disableStyle, size = 'medium', pressed, defaultPressed = false, onPressedChange, disabled = false, ...props }, ref) {
26
26
  const [pressedInternalState, setPressedInternalState] = useState(defaultPressed);
27
27
  return (_jsx(BaseToggle, { ...props, ref: ref, pressed: pressed, defaultPressed: defaultPressed, disabled: disabled, "data-size": size, "data-component": "toggle-root", "data-style-disabled": disableStyle ? '' : undefined, onPressedChange: (next, details) => {
28
28
  onPressedChange?.(next, details);
@@ -31,48 +31,41 @@ export const Root = forwardRef(function Root({ children, className, disableStyle
31
31
  }, className: className, children: _jsx(ToggleContext.Provider, { value: { pressed: pressed ?? pressedInternalState, disabled, size }, children: children }) }));
32
32
  });
33
33
  /** Render beside InactiveIcon inside Root. It automatically appears only while pressed; supply the decorative icon without another visibility condition. */
34
- export const ActiveIcon = forwardRef(function ActiveIcon({ disableStyle, children, className, ...props }, ref) {
35
- const { pressed, disabled, size } = useToggleContext();
36
- if (!pressed)
34
+ export const ActiveIcon = /* @__PURE__ */ forwardRef(function ActiveIcon(props, ref) {
35
+ const context = useToggleContext();
36
+ if (!context.pressed)
37
37
  return null;
38
- return cloneElement(children, {
39
- ...props,
40
- ref,
41
- 'aria-hidden': true,
42
- 'data-size': size,
43
- 'data-pressed': pressed ? '' : undefined,
44
- 'data-disabled': disabled ? '' : undefined,
45
- ...{
46
- 'data-component': 'toggle-activeicon',
47
- 'data-style-disabled': disableStyle ? '' : undefined,
48
- },
49
- className: twMerge(children.props.className, className),
50
- });
38
+ return _jsx(StateIcon, { ...props, ref: ref, component: "toggle-activeicon" });
51
39
  });
52
40
  /** Render beside ActiveIcon inside Root. It automatically appears only while unpressed; supply the decorative icon without another visibility condition. */
53
- export const InactiveIcon = forwardRef(function InactiveIcon({ disableStyle, children, className, ...props }, ref) {
54
- const { pressed, disabled, size } = useToggleContext();
55
- if (pressed)
41
+ export const InactiveIcon = /* @__PURE__ */ forwardRef(function InactiveIcon(props, ref) {
42
+ const context = useToggleContext();
43
+ if (context.pressed)
56
44
  return null;
45
+ return _jsx(StateIcon, { ...props, ref: ref, component: "toggle-inactiveicon" });
46
+ });
47
+ // The shared body of ActiveIcon and InactiveIcon: decorates the supplied icon with the toggle's state
48
+ const StateIcon = /* @__PURE__ */ forwardRef(function StateIcon({ disableStyle, children, className, component, ...props }, ref) {
49
+ const context = useToggleContext();
57
50
  return cloneElement(children, {
58
51
  ...props,
59
52
  ref,
60
53
  'aria-hidden': true,
61
- 'data-size': size,
62
- 'data-pressed': pressed ? '' : undefined,
63
- 'data-disabled': disabled ? '' : undefined,
54
+ 'data-size': context.size,
55
+ 'data-pressed': context.pressed ? '' : undefined,
56
+ 'data-disabled': context.disabled ? '' : undefined,
57
+ // Spread from an object so the data-* keys pass the element props' excess property check
64
58
  ...{
65
- 'data-component': 'toggle-inactiveicon',
59
+ 'data-component': component,
66
60
  'data-style-disabled': disableStyle ? '' : undefined,
67
61
  },
68
62
  className: twMerge(children.props.className, className),
69
63
  });
70
64
  });
71
- const ToggleContext = createContext(null);
65
+ const ToggleContext = /* @__PURE__ */ createContext(null);
72
66
  function useToggleContext() {
73
67
  const context = useContext(ToggleContext);
74
68
  if (!context)
75
69
  throw new Error('Toggle icons must be inside Toggle.Root');
76
70
  return context;
77
71
  }
78
- //# sourceMappingURL=index.js.map