@central-ui/react 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. package/LICENSE +49 -0
  2. package/dist/components/accordion/index.d.ts +4 -3
  3. package/dist/components/accordion/index.js +7 -4
  4. package/dist/components/autocomplete/index.d.ts +14 -25
  5. package/dist/components/autocomplete/index.js +70 -54
  6. package/dist/components/avatar/index.d.ts +1 -2
  7. package/dist/components/avatar/index.js +0 -1
  8. package/dist/components/badge/index.d.ts +0 -1
  9. package/dist/components/badge/index.js +2 -2
  10. package/dist/components/banner/index.d.ts +1 -1
  11. package/dist/components/banner/index.js +23 -25
  12. package/dist/components/barchart/index.d.ts +106 -0
  13. package/dist/components/barchart/index.js +122 -0
  14. package/dist/components/breadcrumb/index.d.ts +0 -1
  15. package/dist/components/breadcrumb/index.js +6 -7
  16. package/dist/components/button/index.d.ts +2 -3
  17. package/dist/components/button/index.js +11 -12
  18. package/dist/components/card/index.d.ts +0 -1
  19. package/dist/components/card/index.js +0 -1
  20. package/dist/components/checkbox/index.d.ts +13 -11
  21. package/dist/components/checkbox/index.js +51 -31
  22. package/dist/components/chip/index.d.ts +1 -1
  23. package/dist/components/chip/index.js +2 -3
  24. package/dist/components/combobox/index.d.ts +18 -30
  25. package/dist/components/combobox/index.js +90 -67
  26. package/dist/components/datepicker/index.d.ts +18 -31
  27. package/dist/components/datepicker/index.js +81 -99
  28. package/dist/components/dialog/index.d.ts +14 -27
  29. package/dist/components/dialog/index.js +17 -18
  30. package/dist/components/divider/index.d.ts +0 -1
  31. package/dist/components/divider/index.js +0 -1
  32. package/dist/components/donutchart/index.d.ts +100 -0
  33. package/dist/components/donutchart/index.js +178 -0
  34. package/dist/components/drawer/index.d.ts +12 -21
  35. package/dist/components/drawer/index.js +34 -36
  36. package/dist/components/empty/index.d.ts +1 -2
  37. package/dist/components/empty/index.js +2 -4
  38. package/dist/components/fileupload/index.d.ts +4 -9
  39. package/dist/components/fileupload/index.js +26 -38
  40. package/dist/components/form/index.d.ts +0 -1
  41. package/dist/components/form/index.js +0 -1
  42. package/dist/components/horizontalbarchart/index.d.ts +120 -0
  43. package/dist/components/horizontalbarchart/index.js +193 -0
  44. package/dist/components/input/index.d.ts +22 -22
  45. package/dist/components/input/index.js +76 -105
  46. package/dist/components/linechart/index.d.ts +114 -0
  47. package/dist/components/linechart/index.js +139 -0
  48. package/dist/components/menu/index.d.ts +9 -11
  49. package/dist/components/menu/index.js +42 -39
  50. package/dist/components/metric/index.d.ts +0 -1
  51. package/dist/components/metric/index.js +0 -1
  52. package/dist/components/numberinput/index.d.ts +14 -21
  53. package/dist/components/numberinput/index.js +40 -53
  54. package/dist/components/otpinput/index.d.ts +14 -9
  55. package/dist/components/otpinput/index.js +25 -18
  56. package/dist/components/page/index.d.ts +0 -1
  57. package/dist/components/page/index.js +1 -3
  58. package/dist/components/passwordinput/index.d.ts +14 -11
  59. package/dist/components/passwordinput/index.js +36 -45
  60. package/dist/components/popover/index.d.ts +21 -19
  61. package/dist/components/popover/index.js +34 -15
  62. package/dist/components/radio/index.d.ts +13 -9
  63. package/dist/components/radio/index.js +69 -60
  64. package/dist/components/ratinginput/index.d.ts +13 -8
  65. package/dist/components/ratinginput/index.js +37 -17
  66. package/dist/components/select/index.d.ts +25 -28
  67. package/dist/components/select/index.js +67 -38
  68. package/dist/components/skeleton/index.d.ts +0 -1
  69. package/dist/components/skeleton/index.js +0 -1
  70. package/dist/components/slider/index.d.ts +14 -9
  71. package/dist/components/slider/index.js +64 -63
  72. package/dist/components/spinner/index.d.ts +1 -2
  73. package/dist/components/spinner/index.js +2 -3
  74. package/dist/components/splitter/index.d.ts +1 -2
  75. package/dist/components/splitter/index.js +5 -6
  76. package/dist/components/stepper/index.d.ts +8 -20
  77. package/dist/components/stepper/index.js +15 -16
  78. package/dist/components/switch/index.d.ts +12 -10
  79. package/dist/components/switch/index.js +46 -30
  80. package/dist/components/table/index.d.ts +3 -3
  81. package/dist/components/table/index.js +14 -13
  82. package/dist/components/tabs/index.d.ts +0 -1
  83. package/dist/components/tabs/index.js +1 -2
  84. package/dist/components/textarea/index.d.ts +14 -11
  85. package/dist/components/textarea/index.js +37 -46
  86. package/dist/components/textlink/index.d.ts +3 -1
  87. package/dist/components/textlink/index.js +4 -1
  88. package/dist/components/toast/index.d.ts +8 -14
  89. package/dist/components/toast/index.js +48 -48
  90. package/dist/components/toggle/index.d.ts +0 -1
  91. package/dist/components/toggle/index.js +17 -24
  92. package/dist/components/tooltip/index.d.ts +11 -13
  93. package/dist/components/tooltip/index.js +12 -9
  94. package/dist/components/tour/index.d.ts +154 -0
  95. package/dist/components/tour/index.js +280 -0
  96. package/dist/index.d.ts +5 -2
  97. package/dist/index.js +5 -1
  98. package/dist/types/Icon.d.ts +0 -1
  99. package/dist/types/Icon.js +0 -1
  100. package/dist/types/Style.d.ts +0 -1
  101. package/dist/types/Style.js +0 -1
  102. package/dist/types/Tone.d.ts +0 -1
  103. package/dist/types/Tone.js +0 -1
  104. package/dist/types/Validation.d.ts +12 -0
  105. package/dist/types/Validation.js +1 -0
  106. package/dist/utils/ArkStateToDataAttributes.d.ts +0 -1
  107. package/dist/utils/ArkStateToDataAttributes.js +0 -1
  108. package/dist/utils/Tone.d.ts +0 -1
  109. package/dist/utils/Tone.js +0 -1
  110. package/dist/utils/Validation.d.ts +14 -0
  111. package/dist/utils/Validation.js +23 -0
  112. package/dist/utils/asChild.d.ts +41 -0
  113. package/dist/utils/asChild.js +15 -0
  114. package/dist/utils/icons.d.ts +24 -0
  115. package/dist/utils/icons.js +160 -0
  116. package/dist/utils/useForwardClickToInput.d.ts +0 -1
  117. package/dist/utils/useForwardClickToInput.js +0 -1
  118. package/dist/utils/virtualization/useVirtualizedAutocomplete.d.ts +0 -1
  119. package/dist/utils/virtualization/useVirtualizedAutocomplete.js +0 -1
  120. package/dist/utils/virtualization/useVirtualizedCombobox.d.ts +0 -1
  121. package/dist/utils/virtualization/useVirtualizedCombobox.js +0 -1
  122. package/dist/utils/virtualization/useVirtualizedTable.d.ts +0 -1
  123. package/dist/utils/virtualization/useVirtualizedTable.js +0 -1
  124. package/package.json +12 -11
  125. package/src/presets/shopify-polaris/shopify-polaris-autocomplete.css +2 -2
  126. package/src/presets/shopify-polaris/shopify-polaris-barchart.css +64 -0
  127. package/src/presets/shopify-polaris/shopify-polaris-checkbox.css +2 -2
  128. package/src/presets/shopify-polaris/shopify-polaris-combobox.css +2 -2
  129. package/src/presets/shopify-polaris/shopify-polaris-datepicker.css +4 -4
  130. package/src/presets/shopify-polaris/shopify-polaris-dialog.css +16 -0
  131. package/src/presets/shopify-polaris/shopify-polaris-donutchart.css +172 -0
  132. package/src/presets/shopify-polaris/shopify-polaris-drawer.css +16 -0
  133. package/src/presets/shopify-polaris/shopify-polaris-fileupload.css +1 -1
  134. package/src/presets/shopify-polaris/shopify-polaris-horizontalbarchart.css +60 -0
  135. package/src/presets/shopify-polaris/shopify-polaris-input.css +2 -2
  136. package/src/presets/shopify-polaris/shopify-polaris-linechart.css +68 -0
  137. package/src/presets/shopify-polaris/shopify-polaris-menu.css +16 -0
  138. package/src/presets/shopify-polaris/shopify-polaris-numberinput.css +2 -2
  139. package/src/presets/shopify-polaris/shopify-polaris-otpinput.css +2 -2
  140. package/src/presets/shopify-polaris/shopify-polaris-passwordinput.css +2 -2
  141. package/src/presets/shopify-polaris/shopify-polaris-popover.css +29 -0
  142. package/src/presets/shopify-polaris/shopify-polaris-radio.css +2 -2
  143. package/src/presets/shopify-polaris/shopify-polaris-ratinginput.css +2 -2
  144. package/src/presets/shopify-polaris/shopify-polaris-select.css +2 -2
  145. package/src/presets/shopify-polaris/shopify-polaris-slider.css +2 -2
  146. package/src/presets/shopify-polaris/shopify-polaris-stepper.css +16 -0
  147. package/src/presets/shopify-polaris/shopify-polaris-switch.css +2 -2
  148. package/src/presets/shopify-polaris/shopify-polaris-textarea.css +2 -2
  149. package/src/presets/shopify-polaris/shopify-polaris-tooltip.css +16 -0
  150. package/src/presets/shopify-polaris/shopify-polaris.css +4 -0
  151. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-autocomplete.css +2 -2
  152. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-barchart.css +64 -0
  153. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-checkbox.css +2 -2
  154. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-combobox.css +2 -2
  155. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-datepicker.css +2 -2
  156. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-dialog.css +9 -0
  157. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-donutchart.css +172 -0
  158. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-drawer.css +9 -0
  159. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-fileupload.css +1 -1
  160. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-horizontalbarchart.css +60 -0
  161. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-input.css +2 -2
  162. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-linechart.css +68 -0
  163. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-menu.css +9 -0
  164. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-numberinput.css +2 -2
  165. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-otpinput.css +2 -2
  166. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-passwordinput.css +2 -2
  167. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-popover.css +22 -0
  168. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-radio.css +2 -2
  169. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-ratinginput.css +2 -2
  170. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-slider.css +2 -2
  171. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-stepper.css +9 -0
  172. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-switch.css +2 -2
  173. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-textarea.css +2 -2
  174. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy-tooltip.css +9 -0
  175. package/src/presets/shopify-polaris-legacy/shopify-polaris-legacy.css +4 -0
  176. package/dist/components/accordion/index.d.ts.map +0 -1
  177. package/dist/components/accordion/index.js.map +0 -1
  178. package/dist/components/autocomplete/index.d.ts.map +0 -1
  179. package/dist/components/autocomplete/index.js.map +0 -1
  180. package/dist/components/avatar/index.d.ts.map +0 -1
  181. package/dist/components/avatar/index.js.map +0 -1
  182. package/dist/components/badge/index.d.ts.map +0 -1
  183. package/dist/components/badge/index.js.map +0 -1
  184. package/dist/components/banner/index.d.ts.map +0 -1
  185. package/dist/components/banner/index.js.map +0 -1
  186. package/dist/components/breadcrumb/index.d.ts.map +0 -1
  187. package/dist/components/breadcrumb/index.js.map +0 -1
  188. package/dist/components/button/index.d.ts.map +0 -1
  189. package/dist/components/button/index.js.map +0 -1
  190. package/dist/components/card/index.d.ts.map +0 -1
  191. package/dist/components/card/index.js.map +0 -1
  192. package/dist/components/checkbox/index.d.ts.map +0 -1
  193. package/dist/components/checkbox/index.js.map +0 -1
  194. package/dist/components/chip/index.d.ts.map +0 -1
  195. package/dist/components/chip/index.js.map +0 -1
  196. package/dist/components/combobox/index.d.ts.map +0 -1
  197. package/dist/components/combobox/index.js.map +0 -1
  198. package/dist/components/datepicker/index.d.ts.map +0 -1
  199. package/dist/components/datepicker/index.js.map +0 -1
  200. package/dist/components/dialog/index.d.ts.map +0 -1
  201. package/dist/components/dialog/index.js.map +0 -1
  202. package/dist/components/divider/index.d.ts.map +0 -1
  203. package/dist/components/divider/index.js.map +0 -1
  204. package/dist/components/drawer/index.d.ts.map +0 -1
  205. package/dist/components/drawer/index.js.map +0 -1
  206. package/dist/components/empty/index.d.ts.map +0 -1
  207. package/dist/components/empty/index.js.map +0 -1
  208. package/dist/components/fileupload/index.d.ts.map +0 -1
  209. package/dist/components/fileupload/index.js.map +0 -1
  210. package/dist/components/form/index.d.ts.map +0 -1
  211. package/dist/components/form/index.js.map +0 -1
  212. package/dist/components/input/index.d.ts.map +0 -1
  213. package/dist/components/input/index.js.map +0 -1
  214. package/dist/components/menu/index.d.ts.map +0 -1
  215. package/dist/components/menu/index.js.map +0 -1
  216. package/dist/components/metric/index.d.ts.map +0 -1
  217. package/dist/components/metric/index.js.map +0 -1
  218. package/dist/components/numberinput/index.d.ts.map +0 -1
  219. package/dist/components/numberinput/index.js.map +0 -1
  220. package/dist/components/otpinput/index.d.ts.map +0 -1
  221. package/dist/components/otpinput/index.js.map +0 -1
  222. package/dist/components/page/index.d.ts.map +0 -1
  223. package/dist/components/page/index.js.map +0 -1
  224. package/dist/components/passwordinput/index.d.ts.map +0 -1
  225. package/dist/components/passwordinput/index.js.map +0 -1
  226. package/dist/components/popover/index.d.ts.map +0 -1
  227. package/dist/components/popover/index.js.map +0 -1
  228. package/dist/components/radio/index.d.ts.map +0 -1
  229. package/dist/components/radio/index.js.map +0 -1
  230. package/dist/components/ratinginput/index.d.ts.map +0 -1
  231. package/dist/components/ratinginput/index.js.map +0 -1
  232. package/dist/components/select/index.d.ts.map +0 -1
  233. package/dist/components/select/index.js.map +0 -1
  234. package/dist/components/skeleton/index.d.ts.map +0 -1
  235. package/dist/components/skeleton/index.js.map +0 -1
  236. package/dist/components/slider/index.d.ts.map +0 -1
  237. package/dist/components/slider/index.js.map +0 -1
  238. package/dist/components/spinner/index.d.ts.map +0 -1
  239. package/dist/components/spinner/index.js.map +0 -1
  240. package/dist/components/splitter/index.d.ts.map +0 -1
  241. package/dist/components/splitter/index.js.map +0 -1
  242. package/dist/components/stepper/index.d.ts.map +0 -1
  243. package/dist/components/stepper/index.js.map +0 -1
  244. package/dist/components/switch/index.d.ts.map +0 -1
  245. package/dist/components/switch/index.js.map +0 -1
  246. package/dist/components/table/index.d.ts.map +0 -1
  247. package/dist/components/table/index.js.map +0 -1
  248. package/dist/components/tabs/index.d.ts.map +0 -1
  249. package/dist/components/tabs/index.js.map +0 -1
  250. package/dist/components/textarea/index.d.ts.map +0 -1
  251. package/dist/components/textarea/index.js.map +0 -1
  252. package/dist/components/textlink/index.d.ts.map +0 -1
  253. package/dist/components/textlink/index.js.map +0 -1
  254. package/dist/components/toast/index.d.ts.map +0 -1
  255. package/dist/components/toast/index.js.map +0 -1
  256. package/dist/components/toggle/index.d.ts.map +0 -1
  257. package/dist/components/toggle/index.js.map +0 -1
  258. package/dist/components/tooltip/index.d.ts.map +0 -1
  259. package/dist/components/tooltip/index.js.map +0 -1
  260. package/dist/index.d.ts.map +0 -1
  261. package/dist/index.js.map +0 -1
  262. package/dist/types/Icon.d.ts.map +0 -1
  263. package/dist/types/Icon.js.map +0 -1
  264. package/dist/types/Style.d.ts.map +0 -1
  265. package/dist/types/Style.js.map +0 -1
  266. package/dist/types/Tone.d.ts.map +0 -1
  267. package/dist/types/Tone.js.map +0 -1
  268. package/dist/utils/ArkStateToDataAttributes.d.ts.map +0 -1
  269. package/dist/utils/ArkStateToDataAttributes.js.map +0 -1
  270. package/dist/utils/Tone.d.ts.map +0 -1
  271. package/dist/utils/Tone.js.map +0 -1
  272. package/dist/utils/useForwardClickToInput.d.ts.map +0 -1
  273. package/dist/utils/useForwardClickToInput.js.map +0 -1
  274. package/dist/utils/virtualization/useVirtualizedAutocomplete.d.ts.map +0 -1
  275. package/dist/utils/virtualization/useVirtualizedAutocomplete.js.map +0 -1
  276. package/dist/utils/virtualization/useVirtualizedCombobox.d.ts.map +0 -1
  277. package/dist/utils/virtualization/useVirtualizedCombobox.js.map +0 -1
  278. package/dist/utils/virtualization/useVirtualizedTable.d.ts.map +0 -1
  279. package/dist/utils/virtualization/useVirtualizedTable.js.map +0 -1
@@ -0,0 +1,106 @@
1
+ import type { ComponentProps, ReactNode } from 'react';
2
+ import { BarChart as RechartsBarChart } from 'recharts';
3
+ import type { BarProps as RechartsBarProps, TooltipProps as RechartsTooltipProps, XAxisProps as RechartsXAxisProps, YAxisProps as RechartsYAxisProps } from 'recharts';
4
+ import type { StyleProps } from '../../types/Style.ts';
5
+ /** Every record needs a unique `label` (the category) and a numeric `value` (the bar height). Extra fields are kept for the tooltip. */
6
+ type Datum = {
7
+ label: string;
8
+ value: number;
9
+ };
10
+ export type RootProps<Data extends Datum = Datum> = Pick<ComponentProps<typeof RechartsBarChart>, 'accessibilityLayer' | 'desc'> & {
11
+ /** Unique labels are equally spaced categories, including when they contain dates. */
12
+ data: readonly Data[];
13
+ 'aria-label': string;
14
+ children: ReactNode;
15
+ /**
16
+ * Converts a record's `label` into display text.
17
+ * Used by the X axis ticks and the tooltip label, so both always read the same.
18
+ * Use it for dates (e.g. `'2026-10-12'` → `'October 12, 2026'`) or to shorten long categories.
19
+ * @default (label) => label
20
+ */
21
+ labelToString?: (label: string) => string;
22
+ /**
23
+ * Converts a record's `value` into display text.
24
+ * Used by the Y axis ticks and the tooltip value, so both always read the same.
25
+ * Use it for currency, percentages, or units (e.g. `1240` → `'$1,240'`).
26
+ * @default (value) => value.toLocaleString()
27
+ */
28
+ valueToString?: (value: number) => string;
29
+ /**
30
+ * Whether the Y axis may place ticks at fractional values.
31
+ * Keep it `false` for counts (orders, visitors) so the axis never shows `0.5 orders`.
32
+ * Set it to `true` for continuous measures where fractions are meaningful, such as small currency amounts or ratings.
33
+ * @default false
34
+ */
35
+ allowDecimals?: boolean;
36
+ };
37
+ /** Provides the chart data, formatting, and accessibility settings to its parts. Renders no element. */
38
+ export declare function Root<Data extends Datum>({ children, labelToString, valueToString, allowDecimals, ...chart }: RootProps<Data>): import("react").JSX.Element;
39
+ export type ContainerProps = Pick<ComponentProps<typeof RechartsBarChart>, 'children' | 'height' | 'className' | 'style' | 'id' | 'margin' | 'ref' | 'tabIndex'> & {
40
+ /**
41
+ * The vertical line that follows the pointer across the chart.
42
+ * Shown by default, with or without a Tooltip, so readers can line a point up with its axis label.
43
+ * Pass `false` for static charts where hover feedback adds noise. Style it through `data-component="barchart-hoverguide"`.
44
+ * @default true
45
+ */
46
+ hoverGuide?: LineSwitch;
47
+ };
48
+ /** Recharts supplies its own responsive container, so no extra wrapper is needed. */
49
+ export declare function Container({ height, className, style, children, hoverGuide, ...props }: ContainerProps): import("react").JSX.Element;
50
+ /** On/off only: style it through its data-component in a preset, so each export keeps one className. */
51
+ type LineSwitch = boolean;
52
+ export type XAxisProps = Pick<RechartsXAxisProps, 'hide' | 'tickSize'> & {
53
+ /** Classes for the tick labels, e.g. `fill-neutral-500`. Keep the font size at 12px: Recharts measures labels at that size to skip overlapping ones. */
54
+ className?: string;
55
+ /** Space between the labels and the plot area, in pixels. */
56
+ labelGap?: number;
57
+ /** The line along the axis. Hidden by default. */
58
+ axisLine?: LineSwitch;
59
+ /** The small marks at each tick. Hidden by default. */
60
+ tickLine?: LineSwitch;
61
+ };
62
+ export declare function XAxis({ className, labelGap, axisLine, tickLine, ...props }: XAxisProps): import("react").JSX.Element;
63
+ export type YAxisProps = Pick<RechartsYAxisProps, 'hide' | 'tickSize' | 'width'> & {
64
+ /** Classes for the tick labels, e.g. `fill-neutral-500`. Keep the font size at 12px: Recharts measures labels at that size to skip overlapping ones. */
65
+ className?: string;
66
+ /** Space between the labels and the plot area, in pixels. */
67
+ labelGap?: number;
68
+ /** The line along the axis. Hidden by default. */
69
+ axisLine?: LineSwitch;
70
+ /** The small marks at each tick. Hidden by default. */
71
+ tickLine?: LineSwitch;
72
+ };
73
+ export declare function YAxis({ className, labelGap, axisLine, tickLine, ...props }: YAxisProps): import("react").JSX.Element;
74
+ export type GridProps = {
75
+ /** Classes for every grid line, e.g. `stroke-neutral-200 [stroke-dasharray:4_4]`. */
76
+ className?: string;
77
+ };
78
+ /** Horizontal lines only, one per Y value tick. */
79
+ export declare function Grid({ className }: GridProps): import("react").JSX.Element;
80
+ export type BarsProps = Pick<RechartsBarProps, 'radius' | 'hide' | 'name'> & {
81
+ /**
82
+ * Classes for every bar. Colors come only from here or from a preset; there is no built-in color.
83
+ * Target hover with `data-active:` (e.g. `fill-sky-500 data-active:opacity-80`).
84
+ */
85
+ className?: string;
86
+ /**
87
+ * Whether the bar under the pointer gets `data-active`. Pass false to turn the hover state off.
88
+ * @default true
89
+ */
90
+ activeBar?: boolean;
91
+ };
92
+ export declare function Bars({ className, activeBar, ...props }: BarsProps): import("react").JSX.Element;
93
+ export type TooltipProps<Data extends Datum = Datum> = Pick<RechartsTooltipProps<number, string>, 'offset' | 'allowEscapeViewBox' | 'portal'> & {
94
+ /** Receives the hovered record and returns the popup. */
95
+ children: (datum: Data) => ReactNode;
96
+ };
97
+ /** Renders no element: hands its popup to the Container. For extra fields, specify the record type: Tooltip<(typeof data)[number]>. */
98
+ export declare function Tooltip<Data extends Datum = Datum>({ children, offset, allowEscapeViewBox, portal, }: TooltipProps<Data>): null;
99
+ export declare function TooltipPopup({ disableStyle, className, ...props }: ComponentProps<'div'> & StyleProps): import("react").JSX.Element;
100
+ export declare function TooltipTitle({ disableStyle, className, ...props }: ComponentProps<'p'> & StyleProps): import("react").JSX.Element;
101
+ /** Shows the hovered record's label, formatted by `labelToString` on Root. */
102
+ export declare function TooltipLabel({ disableStyle, className, ...props }: Omit<ComponentProps<'p'>, 'children'> & StyleProps): import("react").JSX.Element;
103
+ /** Shows the hovered record's value, formatted by `valueToString` on Root. */
104
+ export declare function TooltipValue({ disableStyle, className, ...props }: Omit<ComponentProps<'p'>, 'children'> & StyleProps): import("react").JSX.Element;
105
+ export declare function TooltipColorIndicator({ disableStyle, className, ...props }: ComponentProps<'span'> & StyleProps): import("react").JSX.Element;
106
+ export {};
@@ -0,0 +1,122 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { createContext, useContext, useLayoutEffect, useState } from 'react';
3
+ import { twMerge } from 'tailwind-merge';
4
+ import { Bar as RechartsBar, BarChart as RechartsBarChart, CartesianGrid as RechartsGrid, Rectangle as RechartsRectangle, Tooltip as RechartsTooltip, XAxis as RechartsXAxis, YAxis as RechartsYAxis, } from 'recharts';
5
+ const ChartContext = /* @__PURE__ */ createContext(null);
6
+ /** Provides the chart data, formatting, and accessibility settings to its parts. Renders no element. */
7
+ export function Root({ children, labelToString = (label) => label, valueToString = (value) => value.toLocaleString(), allowDecimals = false, ...chart }) {
8
+ return (_jsx(ChartContext.Provider, { value: { ...chart, labelToString, valueToString, allowDecimals }, children: children }));
9
+ }
10
+ function useChart(part) {
11
+ const chart = useContext(ChartContext);
12
+ if (!chart)
13
+ throw new Error(`BarChart.${part} must be inside BarChart.Root`);
14
+ return chart;
15
+ }
16
+ /** Lets a Tooltip part hand its content to the Container, which owns the single Recharts tooltip. */
17
+ const TooltipSlotContext = /* @__PURE__ */ createContext(null);
18
+ /** Recharts supplies its own responsive container, so no extra wrapper is needed. */
19
+ export function Container({ height = 300, className, style, children, hoverGuide = true, ...props }) {
20
+ const chart = useChart('Container');
21
+ const [tooltip, setTooltip] = useState(null);
22
+ return (_jsxs(RechartsBarChart, { margin: { top: 12, right: 12, bottom: 0, left: 0 }, ...props, data: chart.data, accessibilityLayer: chart.accessibilityLayer, desc: chart.desc, title: chart['aria-label'], className: twMerge('min-w-0 w-full', className), style: { ...style, background: 'transparent' }, height: height, width: "100%", responsive: true, layout: "horizontal",
23
+ // Bars nearly touch: each fills 90% of its slot.
24
+ barCategoryGap: "15%", children: [_jsx(TooltipSlotContext.Provider, { value: setTooltip, children: children }), _jsx(RechartsTooltip, { offset: 12, ...tooltip?.props,
25
+ // Native popup slide, timed to match the hover guide's transition.
26
+ animationDuration: 200, animationEasing: "ease-out", shared: true, cursor: hoverGuide && _jsx(HoverGuide, {}), content: (state) => {
27
+ if (!tooltip || !state.active || !state.payload.length)
28
+ return null;
29
+ // Recharts types the payload as unknown; payload[0] is always the hovered record.
30
+ const datum = state.payload[0].payload;
31
+ return (_jsx(TooltipContext.Provider, { value: datum, children: tooltip.render(datum) }));
32
+ } })] }));
33
+ }
34
+ const lineProps = (line, part) =>
35
+ // Recharts forwards data attributes at runtime; its types omit them.
36
+ (line && { 'data-component': part });
37
+ export function XAxis({ className, labelGap = 8, axisLine = false, tickLine = false, ...props }) {
38
+ const chart = useChart('XAxis');
39
+ return (_jsx(RechartsXAxis, { height: "auto", ...props, axisLine: lineProps(axisLine, 'barchart-xaxis-line'), tickLine: lineProps(tickLine, 'barchart-xaxis-tickline'), tick: {
40
+ className,
41
+ 'data-component': 'barchart-xaxis-ticklabel',
42
+ }, tickMargin: labelGap, tickFormatter: chart.labelToString,
43
+ // Recharts measures labels at this size when it hides overlapping ones.
44
+ fontSize: 12, dataKey: "label", type: "category", label: false, angle: 0,
45
+ // Drops labels at a steady step when they would overlap, so the remaining ones stay evenly spaced.
46
+ interval: "equidistantPreserveStart", minTickGap: 8 }));
47
+ }
48
+ export function YAxis({ className, labelGap = 8, axisLine = false, tickLine = false, ...props }) {
49
+ const chart = useChart('YAxis');
50
+ return (_jsx(RechartsYAxis, { width: "auto", ...props, axisLine: lineProps(axisLine, 'barchart-yaxis-line'), tickLine: lineProps(tickLine, 'barchart-yaxis-tickline'), tick: {
51
+ className,
52
+ 'data-component': 'barchart-yaxis-ticklabel',
53
+ }, tickMargin: labelGap, tickFormatter: chart.valueToString, allowDecimals: chart.allowDecimals, fontSize: 12, type: "number", label: false, angle: 0,
54
+ // Always include zero so bars have a baseline, and never collapse the range when every value is 0.
55
+ domain: ([minimum, maximum]) => [
56
+ Math.min(0, minimum),
57
+ Math.max(Math.min(0, minimum) + 1, maximum, 0),
58
+ ], interval: "preserveStartEnd", minTickGap: 8 }));
59
+ }
60
+ /** Horizontal lines only, one per Y value tick. */
61
+ export function Grid({ className }) {
62
+ return (_jsx(RechartsGrid
63
+ // Recharts' native line slot: each line gets the class and a data-component hook.
64
+ , {
65
+ // Recharts' native line slot: each line gets the class and a data-component hook.
66
+ horizontal: { className, 'data-component': 'barchart-gridline' }, vertical: false, fill: "none" }));
67
+ }
68
+ export function Bars({ className, activeBar = true, ...props }) {
69
+ return (_jsx(RechartsBar, { ...props, activeBar: activeBar,
70
+ // Recharts' native shape slot renders each bar ourselves, so className and data attributes land on the drawn element.
71
+ shape: (bar) => (_jsx(RechartsRectangle, { ...bar, className: className, "data-component": "barchart-bar", "data-index": bar.index, "data-active": bar.isActive ? '' : undefined })), dataKey: "value",
72
+ // Zero days still get a thin, hoverable sliver on the baseline.
73
+ minPointSize: 2, isAnimationActive: false }));
74
+ }
75
+ const TooltipContext = /* @__PURE__ */ createContext(null);
76
+ /** Renders no element: hands its popup to the Container. For extra fields, specify the record type: Tooltip<(typeof data)[number]>. */
77
+ export function Tooltip({ children, offset, allowEscapeViewBox, portal, }) {
78
+ const setTooltip = useContext(TooltipSlotContext);
79
+ if (!setTooltip)
80
+ throw new Error('BarChart.Tooltip must be inside BarChart.Container');
81
+ useLayoutEffect(() => {
82
+ setTooltip({
83
+ render: children,
84
+ props: { offset, allowEscapeViewBox, portal },
85
+ });
86
+ return () => setTooltip(null);
87
+ }, [setTooltip, children, offset, allowEscapeViewBox, portal]);
88
+ return null;
89
+ }
90
+ /** Recharts gives the cursor the bar's whole rectangle; only its center line is drawn. */
91
+ function HoverGuide({ x = 0, y = 0, width = 0, height = 0, }) {
92
+ return (_jsx("line", { "data-component": "barchart-hoverguide",
93
+ // Draw at x=0 and move with a transform, so CSS can slide it between points (Recharts' cursor has no animation of its own).
94
+ x1: 0, x2: 0, y1: y, y2: y + height,
95
+ // The slide between points is built in.
96
+ className: "transition-transform duration-200 ease-out motion-reduce:transition-none", style: { transform: `translateX(${x + width / 2}px)` }, pointerEvents: "none" }));
97
+ }
98
+ export function TooltipPopup({ disableStyle, className, ...props }) {
99
+ return (_jsx("div", { ...props, "data-component": "barchart-tooltip", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
100
+ }
101
+ export function TooltipTitle({ disableStyle, className, ...props }) {
102
+ return (_jsx("p", { ...props, "data-component": "barchart-tooltiptitle", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
103
+ }
104
+ /** Shows the hovered record's label, formatted by `labelToString` on Root. */
105
+ export function TooltipLabel({ disableStyle, className, ...props }) {
106
+ const chart = useChart('TooltipLabel');
107
+ const datum = useContext(TooltipContext);
108
+ if (!datum)
109
+ throw new Error('BarChart.TooltipLabel must be inside BarChart.Tooltip');
110
+ return (_jsx("p", { ...props, "data-component": "barchart-tooltiplabel", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: chart.labelToString(datum.label) }));
111
+ }
112
+ /** Shows the hovered record's value, formatted by `valueToString` on Root. */
113
+ export function TooltipValue({ disableStyle, className, ...props }) {
114
+ const chart = useChart('TooltipValue');
115
+ const datum = useContext(TooltipContext);
116
+ if (!datum)
117
+ throw new Error('BarChart.TooltipValue must be inside BarChart.Tooltip');
118
+ return (_jsx("p", { ...props, "data-component": "barchart-tooltipvalue", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: chart.valueToString(datum.value) }));
119
+ }
120
+ export function TooltipColorIndicator({ disableStyle, className, ...props }) {
121
+ return (_jsx("span", { "aria-hidden": "true", ...props, "data-component": "barchart-tooltipcolorindicator", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
122
+ }
@@ -28,4 +28,3 @@ export declare function Item({ disableStyle, value, type, className, ...props }:
28
28
  export declare function Separator({ disableStyle, children, className, ...props }: (Omit<ComponentProps<'svg'>, 'children'> & {
29
29
  children?: ReactElement<ComponentProps<'svg'>>;
30
30
  }) & StyleProps): ReactElement<import("react").SVGProps<SVGSVGElement>, string | import("react").JSXElementConstructor<any>>;
31
- //# sourceMappingURL=index.d.ts.map
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { ChevronRight } from 'lucide-react';
2
+ import { ChevronRight } from "../../utils/icons.js";
3
3
  import { cloneElement, createContext, useContext } from 'react';
4
4
  import { twMerge } from 'tailwind-merge';
5
- const context = /* @__PURE__ */ createContext('');
5
+ // Sharing the current location's value, so each Item knows whether it's the active one
6
+ const ActiveValueContext = /* @__PURE__ */ createContext('');
6
7
  /**
7
8
  * Set active_value on the default export to match the current Item value. Use Item for each location and Separator between locations; supply actual navigation behavior where needed.
8
9
  *
@@ -20,16 +21,15 @@ const context = /* @__PURE__ */ createContext('');
20
21
  * }
21
22
  */
22
23
  export default function BreadCrumb({ disableStyle, active_value, className, children, ...props }) {
23
- return (_jsx("div", { ...props, "data-component": "breadcrumb-breadcrumb", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: _jsx(context.Provider, { value: active_value, children: children }) }));
24
+ return (_jsx("div", { ...props, "data-component": "breadcrumb-breadcrumb", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: _jsx(ActiveValueContext.Provider, { value: active_value, children: children }) }));
24
25
  }
25
26
  export function Item({ disableStyle, value, type = 'button', className, ...props }) {
26
- const active_value = useContext(context);
27
- return (_jsx("button", { ...props, type: type, "data-active": active_value === value || undefined, "data-component": "breadcrumb-item", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
27
+ const activeValue = useContext(ActiveValueContext);
28
+ return (_jsx("button", { ...props, type: type, "data-active": activeValue === value || undefined, "data-component": "breadcrumb-item", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
28
29
  }
29
30
  /** Omit children to use the supplied separator icon. Override only when another separator is needed. */
30
31
  export function Separator({ disableStyle, children = _jsx(ChevronRight, {}), className, ...props }) {
31
32
  return cloneElement(children, {
32
- ...children.props,
33
33
  ...props,
34
34
  ...{
35
35
  'data-component': 'breadcrumb-separator',
@@ -39,4 +39,3 @@ export function Separator({ disableStyle, children = _jsx(ChevronRight, {}), cla
39
39
  strokeWidth: props.strokeWidth ?? children.props.strokeWidth ?? 2.5,
40
40
  });
41
41
  }
42
- //# sourceMappingURL=index.js.map
@@ -32,7 +32,7 @@ export type ButtonProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'variant
32
32
  * Saving
33
33
  * </Button.default>
34
34
  */
35
- export default function Button({ disableStyle, variant, tone, size, className, children, ...props }: ButtonProps & StyleProps): import("react").JSX.Element;
35
+ export default function Button({ disableStyle, variant, tone, size, className, children, ...props }: ButtonProps): import("react").JSX.Element;
36
36
  /** Supply the decorative icon as a child. Its classes are preserved; interaction belongs to the surrounding control. */
37
37
  export declare function Icon({ disableStyle, children, className, ...props }: (Omit<ComponentProps<'svg'>, 'children'> & {
38
38
  /** Supply the decorative icon; the wrapper forwards the relevant state and preserves its classes. */
@@ -43,6 +43,5 @@ export declare function Icon({ disableStyle, children, className, ...props }: (O
43
43
  'data-tone'?: string;
44
44
  }, string | import("react").JSXElementConstructor<any>>;
45
45
  /** Built-in icon; no children needed. Use it inside its matching control. */
46
- export declare function LoadingIcon({ disableStyle, className, ...props }: SVGIconProps & StyleProps): import("react").JSX.Element;
46
+ export declare function LoadingIcon({ disableStyle, className, strokeWidth, ...props }: SVGIconProps & StyleProps): import("react").JSX.Element;
47
47
  export declare function List({ disableStyle, className, ...props }: ComponentProps<'div'> & StyleProps): import("react").JSX.Element;
48
- //# sourceMappingURL=index.d.ts.map
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { LoaderCircle } from 'lucide-react';
2
+ import { LoaderCircle } from "../../utils/icons.js";
3
3
  import { cloneElement, createContext, useContext } from 'react';
4
4
  import { twMerge } from 'tailwind-merge';
5
- const context = /* @__PURE__ */ createContext({
5
+ // Sharing the button's look with its icons, so they match its size, variant and tone
6
+ const ButtonContext = /* @__PURE__ */ createContext({
6
7
  size: 'medium',
7
8
  variant: 'primary',
8
9
  tone: 'neutral',
@@ -31,17 +32,16 @@ const context = /* @__PURE__ */ createContext({
31
32
  * </Button.default>
32
33
  */
33
34
  export default function Button({ disableStyle, variant, tone = 'neutral', size = 'medium', className, children, ...props }) {
34
- return (_jsx("button", { ...props, "data-variant": variant, "data-tone": tone, "data-size": size, "data-component": "button-button", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: _jsx(context.Provider, { value: { size, variant, tone }, children: children }) }));
35
+ return (_jsx("button", { ...props, "data-variant": variant, "data-tone": tone, "data-size": size, "data-component": "button-button", "data-style-disabled": disableStyle ? '' : undefined, className: className, children: _jsx(ButtonContext.Provider, { value: { size, variant, tone }, children: children }) }));
35
36
  }
36
37
  /** Supply the decorative icon as a child. Its classes are preserved; interaction belongs to the surrounding control. */
37
38
  export function Icon({ disableStyle, children, className, ...props }) {
38
- const { size, variant, tone } = useContext(context);
39
+ const context = useContext(ButtonContext);
39
40
  return cloneElement(children, {
40
- ...children.props,
41
41
  ...props,
42
- 'data-size': size,
43
- 'data-variant': variant,
44
- 'data-tone': tone,
42
+ 'data-size': context.size,
43
+ 'data-variant': context.variant,
44
+ 'data-tone': context.tone,
45
45
  ...{
46
46
  'data-component': 'button-icon',
47
47
  'data-style-disabled': disableStyle ? '' : undefined,
@@ -50,11 +50,10 @@ export function Icon({ disableStyle, children, className, ...props }) {
50
50
  });
51
51
  }
52
52
  /** Built-in icon; no children needed. Use it inside its matching control. */
53
- export function LoadingIcon({ disableStyle, className, ...props }) {
54
- const { size, variant, tone } = useContext(context);
55
- return (_jsx(LoaderCircle, { "data-component": "button-loadingicon", "data-style-disabled": disableStyle ? '' : undefined, className: className, strokeWidth: undefined, ...props, "data-size": size, "data-variant": variant, "data-tone": tone }));
53
+ export function LoadingIcon({ disableStyle, className, strokeWidth = 2, ...props }) {
54
+ const context = useContext(ButtonContext);
55
+ return (_jsx(LoaderCircle, { "data-component": "button-loadingicon", "data-style-disabled": disableStyle ? '' : undefined, className: className, strokeWidth: strokeWidth, ...props, "data-size": context.size, "data-variant": context.variant, "data-tone": context.tone }));
56
56
  }
57
57
  export function List({ disableStyle, className, ...props }) {
58
58
  return (_jsx("div", { ...props, "data-component": "button-list", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
59
59
  }
60
- //# sourceMappingURL=index.js.map
@@ -31,4 +31,3 @@ export declare function Title({ disableStyle, className, ...props }: HTMLAttribu
31
31
  export declare function Description({ disableStyle, className, ...props }: HTMLAttributes<HTMLParagraphElement> & StyleProps): import("react").JSX.Element;
32
32
  export declare function Body({ disableStyle, className, ...props }: HTMLAttributes<HTMLDivElement> & StyleProps): import("react").JSX.Element;
33
33
  export declare function Footer({ disableStyle, className, ...props }: HTMLAttributes<HTMLDivElement> & StyleProps): import("react").JSX.Element;
34
- //# sourceMappingURL=index.d.ts.map
@@ -42,4 +42,3 @@ export function Body({ disableStyle, className, ...props }) {
42
42
  export function Footer({ disableStyle, className, ...props }) {
43
43
  return (_jsx("div", { "data-component": "card-footer", "data-style-disabled": disableStyle ? '' : undefined, className: className, ...props }));
44
44
  }
45
- //# sourceMappingURL=index.js.map
@@ -1,11 +1,11 @@
1
1
  import type { StyleProps } from '../../types/Style.ts';
2
2
  import { Checkbox as BaseCheckbox } from '@base-ui/react/checkbox';
3
- import type { ReactNode } from 'react';
3
+ import type { ComponentProps, ReactNode } from 'react';
4
+ import type { ValidationProps } from '../../types/Validation.ts';
5
+ import type { ValidationMessageChildren } from '../../utils/Validation.ts';
4
6
  type CoreKeys = 'checked' | 'defaultChecked' | 'onCheckedChange' | 'indeterminate' | 'disabled' | 'readOnly' | 'required' | 'name' | 'form' | 'value' | 'uncheckedValue' | 'id' | 'inputRef' | 'parent';
5
- export type RootProps = Pick<BaseCheckbox.Root.Props, CoreKeys> & {
7
+ export type RootProps = Pick<BaseCheckbox.Root.Props, CoreKeys> & ValidationProps & {
6
8
  children: ReactNode;
7
- /** Choose the visual tone. This does not validate data or show/hide feedback messages. */
8
- tone?: 'neutral' | 'valid' | 'invalid';
9
9
  };
10
10
  /**
11
11
  * Keep Button and Indicator inside the same Root as Label. Indicator tracks checked and indeterminate state automatically; no conditional checkmark needed. Use CheckboxGroup only when coordinating several checkbox roots.
@@ -42,7 +42,7 @@ export type RootProps = Pick<BaseCheckbox.Root.Props, CoreKeys> & {
42
42
  * )
43
43
  * }
44
44
  */
45
- export declare function Root({ children, id, tone, ...coreProps }: RootProps): import("react").JSX.Element;
45
+ export declare function Root({ children, id, validation, ...coreProps }: RootProps): import("react").JSX.Element;
46
46
  /** Optional: controls multiple checkboxes as a native array of checked values. Put individual Roots inside and give each child a value. For a select-all checkbox, use parent on its Root and provide allValues on this controlled group; Base UI derives checked and indeterminate automatically. */
47
47
  export declare const CheckboxGroup: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").CheckboxGroupProps, "className"> & {
48
48
  className?: string;
@@ -52,15 +52,17 @@ export declare const Button: import("react").ForwardRefExoticComponent<Omit<Omit
52
52
  className?: string;
53
53
  } & StyleProps, "ref"> & import("react").RefAttributes<HTMLElement>>;
54
54
  /** Tracks the surrounding item state automatically. Keep it mounted; do not add your own visibility condition. Use the supplied default visual unless customization is needed. */
55
- export declare const Indicator: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").CheckboxIndicatorProps, "children" | "className" | "render"> & {
55
+ export declare const Indicator: import("react").ForwardRefExoticComponent<Omit<Omit<import("@base-ui/react").CheckboxIndicatorProps, "className" | "children" | "render"> & {
56
56
  className?: string;
57
57
  } & StyleProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
58
58
  /** Labels the associated control automatically. Supply the visible text; do not wire a second label association. */
59
59
  export declare const Label: import("react").ForwardRefExoticComponent<Omit<Omit<import("react").DetailedHTMLProps<import("react").LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, "htmlFor"> & StyleProps, "ref"> & import("react").RefAttributes<HTMLLabelElement>>;
60
60
  export declare const Description: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLSpanElement> & import("react").HTMLAttributes<HTMLSpanElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
61
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
62
- export declare const Error: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLSpanElement> & import("react").HTMLAttributes<HTMLSpanElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
63
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
64
- export declare const Success: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLSpanElement> & import("react").HTMLAttributes<HTMLSpanElement> & StyleProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
61
+ type MessageProps = Omit<ComponentProps<'span'>, 'children'> & StyleProps & {
62
+ children?: ValidationMessageChildren;
63
+ };
64
+ /** 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. */
65
+ export declare const Error: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
66
+ /** 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. */
67
+ export declare const Success: import("react").ForwardRefExoticComponent<Omit<MessageProps, "ref"> & import("react").RefAttributes<HTMLSpanElement>>;
65
68
  export {};
66
- //# sourceMappingURL=index.d.ts.map
@@ -2,8 +2,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Checkbox as BaseCheckbox } from '@base-ui/react/checkbox';
3
3
  import { CheckboxGroup as BaseCheckboxGroup } from '@base-ui/react/checkbox-group';
4
4
  import { createContext, forwardRef, useContext, useEffect, useId, useState, } from 'react';
5
- import { Check, Minus } from 'lucide-react';
6
- import { ToneProvider, useToneContext } from "../../utils/Tone.js";
5
+ import { Check, Minus } from "../../utils/icons.js";
6
+ import { readValidation, validationAttributes, validationMessageContent } from "../../utils/Validation.js";
7
7
  /**
8
8
  * Keep Button and Indicator inside the same Root as Label. Indicator tracks checked and indeterminate state automatically; no conditional checkmark needed. Use CheckboxGroup only when coordinating several checkbox roots.
9
9
  *
@@ -39,9 +39,10 @@ import { ToneProvider, useToneContext } from "../../utils/Tone.js";
39
39
  * )
40
40
  * }
41
41
  */
42
- export function Root({ children, id, tone = 'neutral', ...coreProps }) {
43
- const generatedId = useId();
42
+ export function Root({ children, id, validation, ...coreProps }) {
43
+ //1. Holding the ids of Description, Error and Success, so Button announces them to screen readers through aria-describedby
44
44
  const [messageIds, setMessageIds] = useState([]);
45
+ //2. Mirroring Base UI's live state, so parts outside Button (Label, Description…) can carry its data attributes
45
46
  const [state, setState] = useState({
46
47
  checked: coreProps.checked ?? coreProps.defaultChecked ?? false,
47
48
  indeterminate: coreProps.indeterminate ?? false,
@@ -49,13 +50,16 @@ export function Root({ children, id, tone = 'neutral', ...coreProps }) {
49
50
  readOnly: coreProps.readOnly ?? false,
50
51
  required: coreProps.required ?? false,
51
52
  });
53
+ //3. Sharing everything with the parts
54
+ const generatedId = useId();
52
55
  return (_jsx(CheckboxContext.Provider, { value: {
53
56
  coreProps: { ...coreProps, id: id ?? generatedId },
54
57
  state,
55
58
  setState,
56
59
  messageIds,
57
60
  setMessageIds,
58
- }, children: _jsx(ToneProvider, { value: tone, children: children }) }));
61
+ validation: readValidation(validation),
62
+ }, children: children }));
59
63
  }
60
64
  /** Optional: controls multiple checkboxes as a native array of checked values. Put individual Roots inside and give each child a value. For a select-all checkbox, use parent on its Root and provide allValues on this controlled group; Base UI derives checked and indeterminate automatically. */
61
65
  export const CheckboxGroup = /* @__PURE__ */ forwardRef(function CheckboxGroup({ disableStyle, className, ...props }, ref) {
@@ -66,14 +70,19 @@ export const Container = /* @__PURE__ */ forwardRef(function Container({ disable
66
70
  });
67
71
  export const Button = /* @__PURE__ */ forwardRef(function Button({ disableStyle, className, ...props }, ref) {
68
72
  const context = useCheckboxContext();
69
- const tone = useToneContext();
70
- return (_jsx(BaseCheckbox.Root, { ...props, ...context.coreProps, ref: ref, "data-tone": tone, "aria-invalid": tone === 'invalid' || props['aria-invalid'] || undefined, "aria-describedby": [props['aria-describedby'], ...context.messageIds]
73
+ return (_jsx(BaseCheckbox.Root, { ...props, ...context.coreProps, ref: ref, ...validationAttributes(context.validation), "aria-invalid": context.validation.state === 'error' || props['aria-invalid'] || undefined, "aria-describedby": [props['aria-describedby'], ...context.messageIds]
71
74
  .filter(Boolean)
72
75
  .join(' ') || undefined, "data-component": "checkbox-button", "data-style-disabled": disableStyle ? '' : undefined, className: className, render: (buttonProps, state) => (_jsx(CheckboxButtonSurface, { ...buttonProps, state: state })) }));
73
76
  });
74
77
  /** Tracks the surrounding item state automatically. Keep it mounted; do not add your own visibility condition. Use the supplied default visual unless customization is needed. */
75
78
  export const Indicator = /* @__PURE__ */ forwardRef(function Indicator({ disableStyle, className, ...props }, ref) {
76
- return (_jsx(BaseCheckbox.Indicator, { ...props, ref: ref, "data-component": "checkbox-indicator", "data-style-disabled": disableStyle ? '' : undefined, className: className, render: (indicatorProps, state) => (_jsx("span", { ...indicatorProps, children: state.indeterminate ? (_jsx(Minus, { "aria-hidden": true, strokeWidth: 3.5, "data-component": "checkbox-indicator-1" })) : state.checked ? (_jsx(Check, { "aria-hidden": true, strokeWidth: 3.5, "data-component": "checkbox-indicator-2" })) : null })) }));
79
+ return (_jsx(BaseCheckbox.Indicator, { ...props, ref: ref, "data-component": "checkbox-indicator", "data-style-disabled": disableStyle ? '' : undefined, className: className, render: (indicatorProps, state) => (_jsx("span", { ...indicatorProps, children: (() => {
80
+ if (state.indeterminate)
81
+ return _jsx(Minus, { "aria-hidden": true, strokeWidth: 3.5, "data-component": "checkbox-indicator-1" });
82
+ if (state.checked)
83
+ return _jsx(Check, { "aria-hidden": true, strokeWidth: 3.5, "data-component": "checkbox-indicator-2" });
84
+ return null;
85
+ })() })) }));
77
86
  });
78
87
  /** Labels the associated control automatically. Supply the visible text; do not wire a second label association. */
79
88
  export const Label = /* @__PURE__ */ forwardRef(function Label({ disableStyle, className, ...props }, ref) {
@@ -84,15 +93,26 @@ export const Description = /* @__PURE__ */ forwardRef(function Description({ dis
84
93
  const messageId = useMessageId(id);
85
94
  return (_jsx("span", { ...usePartAttributes(), ...props, ref: ref, id: messageId, "data-component": "checkbox-description", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
86
95
  });
87
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
88
- export const Error = /* @__PURE__ */ forwardRef(function Error({ disableStyle, className, id, ...props }, ref) {
89
- const messageId = useMessageId(id);
90
- return (_jsx("span", { role: "alert", "aria-atomic": "true", ...usePartAttributes(), ...props, ref: ref, id: messageId, "data-component": "checkbox-error", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
96
+ /** Shows itself only while Root's validation is `'error'`: with no children it shows the message from `['error', message]`, a function children formats that message, and other children replace it. */
97
+ export const Error = /* @__PURE__ */ forwardRef(function Error({ children, ...props }, ref) {
98
+ const context = useCheckboxContext();
99
+ const content = validationMessageContent(context.validation, 'error', children);
100
+ if (content === undefined)
101
+ return null;
102
+ return _jsx(Message, { ...props, ref: ref, role: "alert", component: "checkbox-error", children: content });
91
103
  });
92
- /** You decide when to show this feedback. Changing tone does not validate data or render the message for you. */
93
- export const Success = /* @__PURE__ */ forwardRef(function Success({ disableStyle, className, id, ...props }, ref) {
104
+ /** Shows itself only while Root's validation is `'success'`: with no children it shows the message from `['success', message]`, a function children formats that message, and other children replace it. */
105
+ export const Success = /* @__PURE__ */ forwardRef(function Success({ children, ...props }, ref) {
106
+ const context = useCheckboxContext();
107
+ const content = validationMessageContent(context.validation, 'success', children);
108
+ if (content === undefined)
109
+ return null;
110
+ return _jsx(Message, { ...props, ref: ref, role: "status", component: "checkbox-success", children: content });
111
+ });
112
+ // The shared body of Error and Success, mounted only while they show, so only visible messages describe the checkbox
113
+ const Message = /* @__PURE__ */ forwardRef(function Message({ disableStyle, className, id, component, ...props }, ref) {
94
114
  const messageId = useMessageId(id);
95
- return (_jsx("span", { role: "status", "aria-atomic": "true", ...usePartAttributes(), ...props, ref: ref, id: messageId, "data-component": "checkbox-success", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
115
+ return _jsx("span", { "aria-atomic": "true", ...usePartAttributes(), ...props, ref: ref, id: messageId, "data-component": component, "data-style-disabled": disableStyle ? '' : undefined, className: className });
96
116
  });
97
117
  const CheckboxContext = /* @__PURE__ */ createContext(null);
98
118
  function useCheckboxContext() {
@@ -102,21 +122,21 @@ function useCheckboxContext() {
102
122
  return context;
103
123
  }
104
124
  function usePartAttributes() {
105
- const { state } = useCheckboxContext();
106
- const tone = useToneContext();
125
+ const context = useCheckboxContext();
107
126
  return {
108
- 'data-checked': state.checked ? '' : undefined,
109
- 'data-indeterminate': state.indeterminate ? '' : undefined,
110
- 'data-disabled': state.disabled ? '' : undefined,
111
- 'data-readonly': state.readOnly ? '' : undefined,
112
- 'data-required': state.required ? '' : undefined,
113
- 'data-tone': tone,
127
+ 'data-checked': context.state.checked ? '' : undefined,
128
+ 'data-indeterminate': context.state.indeterminate ? '' : undefined,
129
+ 'data-disabled': context.state.disabled ? '' : undefined,
130
+ 'data-readonly': context.state.readOnly ? '' : undefined,
131
+ 'data-required': context.state.required ? '' : undefined,
132
+ ...validationAttributes(context.validation),
114
133
  };
115
134
  }
135
+ // Rendered by Base UI as the checkbox element, it reports Base UI's live state back to Root's mirror
116
136
  const CheckboxButtonSurface = /* @__PURE__ */ forwardRef(function CheckboxButtonSurface({ state, ...props }, ref) {
117
- const { setState } = useCheckboxContext();
137
+ const context = useCheckboxContext();
118
138
  useEffect(() => {
119
- setState({
139
+ context.setState({
120
140
  checked: state.checked,
121
141
  indeterminate: state.indeterminate,
122
142
  disabled: state.disabled,
@@ -129,18 +149,18 @@ const CheckboxButtonSurface = /* @__PURE__ */ forwardRef(function CheckboxButton
129
149
  state.disabled,
130
150
  state.readOnly,
131
151
  state.required,
132
- setState,
152
+ context.setState,
133
153
  ]);
134
154
  return _jsx("span", { ...props, ref: ref });
135
155
  });
156
+ // Registering a message part's id in Button's aria-describedby while the part is mounted
136
157
  function useMessageId(id) {
137
158
  const generatedId = useId();
138
159
  const messageId = id ?? generatedId;
139
- const { setMessageIds } = useCheckboxContext();
160
+ const context = useCheckboxContext();
140
161
  useEffect(() => {
141
- setMessageIds((current) => [...current, messageId]);
142
- return () => setMessageIds((current) => current.filter((value) => value !== messageId));
143
- }, [messageId, setMessageIds]);
162
+ context.setMessageIds((current) => [...current, messageId]);
163
+ return () => context.setMessageIds((current) => current.filter((value) => value !== messageId));
164
+ }, [messageId, context.setMessageIds]);
144
165
  return messageId;
145
166
  }
146
- //# sourceMappingURL=index.js.map
@@ -17,10 +17,10 @@ import type { ComponentProps, ReactElement } from 'react';
17
17
  * }
18
18
  */
19
19
  export declare function Chip({ disableStyle, className, ...props }: ComponentProps<'div'> & StyleProps): import("react").JSX.Element;
20
+ /** Icon-only: put just a CloseButtonIcon inside, never text like "Remove". Name it for screen readers with aria-label instead, e.g. aria-label="Remove tag". */
20
21
  export declare function CloseButton({ disableStyle, type, className, ...props }: ComponentProps<'button'> & StyleProps): import("react").JSX.Element;
21
22
  /** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
22
23
  export declare function CloseButtonIcon({ disableStyle, children, className, ...props }: (Omit<ComponentProps<'svg'>, 'children'> & {
23
24
  /** Omit for the supplied default icon; pass a child only to replace it. */
24
25
  children?: ReactElement<ComponentProps<'svg'>>;
25
26
  }) & StyleProps): ReactElement<import("react").SVGProps<SVGSVGElement>, string | import("react").JSXElementConstructor<any>>;
26
- //# sourceMappingURL=index.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { X } from 'lucide-react';
2
+ import { X } from "../../utils/icons.js";
3
3
  import { cloneElement } from 'react';
4
4
  import { twMerge } from 'tailwind-merge';
5
5
  /**
@@ -21,13 +21,13 @@ import { twMerge } from 'tailwind-merge';
21
21
  export function Chip({ disableStyle, className, ...props }) {
22
22
  return (_jsx("div", { ...props, "data-component": "chip-chip", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
23
23
  }
24
+ /** Icon-only: put just a CloseButtonIcon inside, never text like "Remove". Name it for screen readers with aria-label instead, e.g. aria-label="Remove tag". */
24
25
  export function CloseButton({ disableStyle, type = 'button', className, ...props }) {
25
26
  return (_jsx("button", { ...props, type: type, "data-component": "chip-closebutton", "data-style-disabled": disableStyle ? '' : undefined, className: className }));
26
27
  }
27
28
  /** A default icon is supplied. Omit children for the usual case; pass an icon only to replace that visual. */
28
29
  export function CloseButtonIcon({ disableStyle, children = _jsx(X, {}), className, ...props }) {
29
30
  return cloneElement(children, {
30
- ...children.props,
31
31
  ...props,
32
32
  ...{
33
33
  'data-component': 'chip-closebuttonicon',
@@ -37,4 +37,3 @@ export function CloseButtonIcon({ disableStyle, children = _jsx(X, {}), classNam
37
37
  strokeWidth: props.strokeWidth ?? children.props.strokeWidth ?? 1.5,
38
38
  });
39
39
  }
40
- //# sourceMappingURL=index.js.map