@cdx-ui/components 0.3.4 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (287) hide show
  1. package/README.md +1 -1
  2. package/coverage.svg +1 -1
  3. package/docs/components/bar-chart/content.md +703 -0
  4. package/docs/components/content.md +9 -1
  5. package/docs/components/line-chart/content.md +567 -0
  6. package/docs/components/pie-chart/content.md +493 -0
  7. package/docs/components/progress-segmented/content.md +1 -1
  8. package/docs/components/select/content.md +144 -2
  9. package/docs/components/stepper/content.md +599 -0
  10. package/docs/components/system-alert/content.md +533 -0
  11. package/docs/foundations/expressions/icons/content.md +1 -1
  12. package/docs/foundations/styles/tokens/all-tokens/content.md +2 -1
  13. package/docs/llms.txt +10 -0
  14. package/docs/patterns/content.md +1 -0
  15. package/docs/patterns/dashboard/content.md +423 -19
  16. package/docs/patterns/insights/content.md +590 -0
  17. package/docs/resources/release-notes/0.3.4/content.md +27 -0
  18. package/docs/resources/release-notes/0.3.5/content.md +7 -0
  19. package/docs/resources/release-notes/content.md +2 -0
  20. package/lib/commonjs/components/BarChart/geometry.js +1130 -0
  21. package/lib/commonjs/components/BarChart/geometry.js.map +1 -0
  22. package/lib/commonjs/components/BarChart/index.js +942 -0
  23. package/lib/commonjs/components/BarChart/index.js.map +1 -0
  24. package/lib/commonjs/components/BarChart/styles.js +26 -0
  25. package/lib/commonjs/components/BarChart/styles.js.map +1 -0
  26. package/lib/commonjs/components/Button/index.js +2 -2
  27. package/lib/commonjs/components/Button/index.js.map +1 -1
  28. package/lib/commonjs/components/Chip/styles.js +3 -1
  29. package/lib/commonjs/components/Chip/styles.js.map +1 -1
  30. package/lib/commonjs/components/LineChart/geometry.js +698 -0
  31. package/lib/commonjs/components/LineChart/geometry.js.map +1 -0
  32. package/lib/commonjs/components/LineChart/index.js +747 -0
  33. package/lib/commonjs/components/LineChart/index.js.map +1 -0
  34. package/lib/commonjs/components/LineChart/styles.js +25 -0
  35. package/lib/commonjs/components/LineChart/styles.js.map +1 -0
  36. package/lib/commonjs/components/PieChart/geometry.js +216 -0
  37. package/lib/commonjs/components/PieChart/geometry.js.map +1 -0
  38. package/lib/commonjs/components/PieChart/index.js +476 -0
  39. package/lib/commonjs/components/PieChart/index.js.map +1 -0
  40. package/lib/commonjs/components/PieChart/styles.js +88 -0
  41. package/lib/commonjs/components/PieChart/styles.js.map +1 -0
  42. package/lib/commonjs/components/ProgressCircle/ProgressCircleRing.js +9 -31
  43. package/lib/commonjs/components/ProgressCircle/ProgressCircleRing.js.map +1 -1
  44. package/lib/commonjs/components/ProgressCircle/ProgressRing.js +52 -0
  45. package/lib/commonjs/components/ProgressCircle/ProgressRing.js.map +1 -0
  46. package/lib/commonjs/components/ScrollShadow/useScrollShadow.js +8 -7
  47. package/lib/commonjs/components/ScrollShadow/useScrollShadow.js.map +1 -1
  48. package/lib/commonjs/components/Stepper/index.js +369 -0
  49. package/lib/commonjs/components/Stepper/index.js.map +1 -0
  50. package/lib/commonjs/components/Stepper/styles.js +211 -0
  51. package/lib/commonjs/components/Stepper/styles.js.map +1 -0
  52. package/lib/commonjs/components/Stepper/useStepperLabelFit.js +22 -0
  53. package/lib/commonjs/components/Stepper/useStepperLabelFit.js.map +1 -0
  54. package/lib/commonjs/components/Stepper/useStepperLabelFit.web.js +52 -0
  55. package/lib/commonjs/components/Stepper/useStepperLabelFit.web.js.map +1 -0
  56. package/lib/commonjs/components/Stepper/useStepperRingColors.js +31 -0
  57. package/lib/commonjs/components/Stepper/useStepperRingColors.js.map +1 -0
  58. package/lib/commonjs/components/SystemAlert/animation.js +218 -0
  59. package/lib/commonjs/components/SystemAlert/animation.js.map +1 -0
  60. package/lib/commonjs/components/SystemAlert/index.js +525 -0
  61. package/lib/commonjs/components/SystemAlert/index.js.map +1 -0
  62. package/lib/commonjs/components/SystemAlert/styles.js +178 -0
  63. package/lib/commonjs/components/SystemAlert/styles.js.map +1 -0
  64. package/lib/commonjs/components/SystemAlert/useSystemAlertStatusBarStyle.js +53 -0
  65. package/lib/commonjs/components/SystemAlert/useSystemAlertStatusBarStyle.js.map +1 -0
  66. package/lib/commonjs/components/Tabs/index.js +4 -0
  67. package/lib/commonjs/components/Tabs/index.js.map +1 -1
  68. package/lib/commonjs/components/Tabs/styles.js +1 -1
  69. package/lib/commonjs/components/Tabs/styles.js.map +1 -1
  70. package/lib/commonjs/components/chart/ChartInspector.js +610 -0
  71. package/lib/commonjs/components/chart/ChartInspector.js.map +1 -0
  72. package/lib/commonjs/components/chart/format.js +93 -0
  73. package/lib/commonjs/components/chart/format.js.map +1 -0
  74. package/lib/commonjs/components/chart/index.js +2 -0
  75. package/lib/commonjs/components/chart/index.js.map +1 -0
  76. package/lib/commonjs/components/chart/motion.js +97 -0
  77. package/lib/commonjs/components/chart/motion.js.map +1 -0
  78. package/lib/commonjs/components/chart/palette.js +178 -0
  79. package/lib/commonjs/components/chart/palette.js.map +1 -0
  80. package/lib/commonjs/components/chart/size.js +34 -0
  81. package/lib/commonjs/components/chart/size.js.map +1 -0
  82. package/lib/commonjs/components/chart/ticks.js +59 -0
  83. package/lib/commonjs/components/chart/ticks.js.map +1 -0
  84. package/lib/commonjs/components/chart/types.js +6 -0
  85. package/lib/commonjs/components/chart/types.js.map +1 -0
  86. package/lib/commonjs/components/chart/useChartHostWidth.js +27 -0
  87. package/lib/commonjs/components/chart/useChartHostWidth.js.map +1 -0
  88. package/lib/commonjs/components/index.js +60 -0
  89. package/lib/commonjs/components/index.js.map +1 -1
  90. package/lib/commonjs/figma/SystemAlert.Button.figma.js +28 -0
  91. package/lib/commonjs/figma/SystemAlert.Button.figma.js.map +1 -0
  92. package/lib/commonjs/figma/SystemAlert.Close.figma.js +22 -0
  93. package/lib/commonjs/figma/SystemAlert.Close.figma.js.map +1 -0
  94. package/lib/commonjs/figma/SystemAlert.Description.figma.js +20 -0
  95. package/lib/commonjs/figma/SystemAlert.Description.figma.js.map +1 -0
  96. package/lib/commonjs/figma/SystemAlert.IconButton.figma.js +31 -0
  97. package/lib/commonjs/figma/SystemAlert.IconButton.figma.js.map +1 -0
  98. package/lib/commonjs/figma/SystemAlert.figma.js +48 -0
  99. package/lib/commonjs/figma/SystemAlert.figma.js.map +1 -0
  100. package/lib/module/components/BarChart/geometry.js +1110 -0
  101. package/lib/module/components/BarChart/geometry.js.map +1 -0
  102. package/lib/module/components/BarChart/index.js +936 -0
  103. package/lib/module/components/BarChart/index.js.map +1 -0
  104. package/lib/module/components/BarChart/styles.js +22 -0
  105. package/lib/module/components/BarChart/styles.js.map +1 -0
  106. package/lib/module/components/Button/index.js +2 -2
  107. package/lib/module/components/Button/index.js.map +1 -1
  108. package/lib/module/components/Chip/styles.js +3 -1
  109. package/lib/module/components/Chip/styles.js.map +1 -1
  110. package/lib/module/components/LineChart/geometry.js +685 -0
  111. package/lib/module/components/LineChart/geometry.js.map +1 -0
  112. package/lib/module/components/LineChart/index.js +741 -0
  113. package/lib/module/components/LineChart/index.js.map +1 -0
  114. package/lib/module/components/LineChart/styles.js +21 -0
  115. package/lib/module/components/LineChart/styles.js.map +1 -0
  116. package/lib/module/components/PieChart/geometry.js +209 -0
  117. package/lib/module/components/PieChart/geometry.js.map +1 -0
  118. package/lib/module/components/PieChart/index.js +471 -0
  119. package/lib/module/components/PieChart/index.js.map +1 -0
  120. package/lib/module/components/PieChart/styles.js +84 -0
  121. package/lib/module/components/PieChart/styles.js.map +1 -0
  122. package/lib/module/components/ProgressCircle/ProgressCircleRing.js +10 -32
  123. package/lib/module/components/ProgressCircle/ProgressCircleRing.js.map +1 -1
  124. package/lib/module/components/ProgressCircle/ProgressRing.js +48 -0
  125. package/lib/module/components/ProgressCircle/ProgressRing.js.map +1 -0
  126. package/lib/module/components/ScrollShadow/useScrollShadow.js +8 -7
  127. package/lib/module/components/ScrollShadow/useScrollShadow.js.map +1 -1
  128. package/lib/module/components/Stepper/index.js +360 -0
  129. package/lib/module/components/Stepper/index.js.map +1 -0
  130. package/lib/module/components/Stepper/styles.js +206 -0
  131. package/lib/module/components/Stepper/styles.js.map +1 -0
  132. package/lib/module/components/Stepper/useStepperLabelFit.js +18 -0
  133. package/lib/module/components/Stepper/useStepperLabelFit.js.map +1 -0
  134. package/lib/module/components/Stepper/useStepperLabelFit.web.js +48 -0
  135. package/lib/module/components/Stepper/useStepperLabelFit.web.js.map +1 -0
  136. package/lib/module/components/Stepper/useStepperRingColors.js +28 -0
  137. package/lib/module/components/Stepper/useStepperRingColors.js.map +1 -0
  138. package/lib/module/components/SystemAlert/animation.js +213 -0
  139. package/lib/module/components/SystemAlert/animation.js.map +1 -0
  140. package/lib/module/components/SystemAlert/index.js +515 -0
  141. package/lib/module/components/SystemAlert/index.js.map +1 -0
  142. package/lib/module/components/SystemAlert/styles.js +174 -0
  143. package/lib/module/components/SystemAlert/styles.js.map +1 -0
  144. package/lib/module/components/SystemAlert/useSystemAlertStatusBarStyle.js +49 -0
  145. package/lib/module/components/SystemAlert/useSystemAlertStatusBarStyle.js.map +1 -0
  146. package/lib/module/components/Tabs/index.js +4 -0
  147. package/lib/module/components/Tabs/index.js.map +1 -1
  148. package/lib/module/components/Tabs/styles.js +1 -1
  149. package/lib/module/components/Tabs/styles.js.map +1 -1
  150. package/lib/module/components/chart/ChartInspector.js +600 -0
  151. package/lib/module/components/chart/ChartInspector.js.map +1 -0
  152. package/lib/module/components/chart/format.js +84 -0
  153. package/lib/module/components/chart/format.js.map +1 -0
  154. package/lib/module/components/chart/index.js +2 -0
  155. package/lib/module/components/chart/index.js.map +1 -0
  156. package/lib/module/components/chart/motion.js +89 -0
  157. package/lib/module/components/chart/motion.js.map +1 -0
  158. package/lib/module/components/chart/palette.js +168 -0
  159. package/lib/module/components/chart/palette.js.map +1 -0
  160. package/lib/module/components/chart/size.js +29 -0
  161. package/lib/module/components/chart/size.js.map +1 -0
  162. package/lib/module/components/chart/ticks.js +55 -0
  163. package/lib/module/components/chart/ticks.js.map +1 -0
  164. package/lib/module/components/chart/types.js +4 -0
  165. package/lib/module/components/chart/types.js.map +1 -0
  166. package/lib/module/components/chart/useChartHostWidth.js +23 -0
  167. package/lib/module/components/chart/useChartHostWidth.js.map +1 -0
  168. package/lib/module/components/index.js +5 -0
  169. package/lib/module/components/index.js.map +1 -1
  170. package/lib/module/figma/SystemAlert.Button.figma.js +22 -0
  171. package/lib/module/figma/SystemAlert.Button.figma.js.map +1 -0
  172. package/lib/module/figma/SystemAlert.Close.figma.js +18 -0
  173. package/lib/module/figma/SystemAlert.Close.figma.js.map +1 -0
  174. package/lib/module/figma/SystemAlert.Description.figma.js +14 -0
  175. package/lib/module/figma/SystemAlert.Description.figma.js.map +1 -0
  176. package/lib/module/figma/SystemAlert.IconButton.figma.js +25 -0
  177. package/lib/module/figma/SystemAlert.IconButton.figma.js.map +1 -0
  178. package/lib/module/figma/SystemAlert.figma.js +42 -0
  179. package/lib/module/figma/SystemAlert.figma.js.map +1 -0
  180. package/lib/typescript/components/BarChart/geometry.d.ts +236 -0
  181. package/lib/typescript/components/BarChart/geometry.d.ts.map +1 -0
  182. package/lib/typescript/components/BarChart/index.d.ts +193 -0
  183. package/lib/typescript/components/BarChart/index.d.ts.map +1 -0
  184. package/lib/typescript/components/BarChart/styles.d.ts +32 -0
  185. package/lib/typescript/components/BarChart/styles.d.ts.map +1 -0
  186. package/lib/typescript/components/Chip/styles.d.ts.map +1 -1
  187. package/lib/typescript/components/LineChart/geometry.d.ts +248 -0
  188. package/lib/typescript/components/LineChart/geometry.d.ts.map +1 -0
  189. package/lib/typescript/components/LineChart/index.d.ts +105 -0
  190. package/lib/typescript/components/LineChart/index.d.ts.map +1 -0
  191. package/lib/typescript/components/LineChart/styles.d.ts +12 -0
  192. package/lib/typescript/components/LineChart/styles.d.ts.map +1 -0
  193. package/lib/typescript/components/PieChart/geometry.d.ts +43 -0
  194. package/lib/typescript/components/PieChart/geometry.d.ts.map +1 -0
  195. package/lib/typescript/components/PieChart/index.d.ts +147 -0
  196. package/lib/typescript/components/PieChart/index.d.ts.map +1 -0
  197. package/lib/typescript/components/PieChart/styles.d.ts +27 -0
  198. package/lib/typescript/components/PieChart/styles.d.ts.map +1 -0
  199. package/lib/typescript/components/ProgressCircle/ProgressCircleRing.d.ts.map +1 -1
  200. package/lib/typescript/components/ProgressCircle/ProgressRing.d.ts +17 -0
  201. package/lib/typescript/components/ProgressCircle/ProgressRing.d.ts.map +1 -0
  202. package/lib/typescript/components/ScrollShadow/useScrollShadow.d.ts.map +1 -1
  203. package/lib/typescript/components/Stepper/index.d.ts +68 -0
  204. package/lib/typescript/components/Stepper/index.d.ts.map +1 -0
  205. package/lib/typescript/components/Stepper/styles.d.ts +46 -0
  206. package/lib/typescript/components/Stepper/styles.d.ts.map +1 -0
  207. package/lib/typescript/components/Stepper/useStepperLabelFit.d.ts +15 -0
  208. package/lib/typescript/components/Stepper/useStepperLabelFit.d.ts.map +1 -0
  209. package/lib/typescript/components/Stepper/useStepperLabelFit.web.d.ts +10 -0
  210. package/lib/typescript/components/Stepper/useStepperLabelFit.web.d.ts.map +1 -0
  211. package/lib/typescript/components/Stepper/useStepperRingColors.d.ts +6 -0
  212. package/lib/typescript/components/Stepper/useStepperRingColors.d.ts.map +1 -0
  213. package/lib/typescript/components/SystemAlert/animation.d.ts +56 -0
  214. package/lib/typescript/components/SystemAlert/animation.d.ts.map +1 -0
  215. package/lib/typescript/components/SystemAlert/index.d.ts +110 -0
  216. package/lib/typescript/components/SystemAlert/index.d.ts.map +1 -0
  217. package/lib/typescript/components/SystemAlert/styles.d.ts +38 -0
  218. package/lib/typescript/components/SystemAlert/styles.d.ts.map +1 -0
  219. package/lib/typescript/components/SystemAlert/useSystemAlertStatusBarStyle.d.ts +14 -0
  220. package/lib/typescript/components/SystemAlert/useSystemAlertStatusBarStyle.d.ts.map +1 -0
  221. package/lib/typescript/components/Tabs/index.d.ts.map +1 -1
  222. package/lib/typescript/components/chart/ChartInspector.d.ts +101 -0
  223. package/lib/typescript/components/chart/ChartInspector.d.ts.map +1 -0
  224. package/lib/typescript/components/chart/format.d.ts +16 -0
  225. package/lib/typescript/components/chart/format.d.ts.map +1 -0
  226. package/lib/typescript/components/chart/index.d.ts +3 -0
  227. package/lib/typescript/components/chart/index.d.ts.map +1 -0
  228. package/lib/typescript/components/chart/motion.d.ts +27 -0
  229. package/lib/typescript/components/chart/motion.d.ts.map +1 -0
  230. package/lib/typescript/components/chart/palette.d.ts +44 -0
  231. package/lib/typescript/components/chart/palette.d.ts.map +1 -0
  232. package/lib/typescript/components/chart/size.d.ts +25 -0
  233. package/lib/typescript/components/chart/size.d.ts.map +1 -0
  234. package/lib/typescript/components/chart/ticks.d.ts +3 -0
  235. package/lib/typescript/components/chart/ticks.d.ts.map +1 -0
  236. package/lib/typescript/components/chart/types.d.ts +163 -0
  237. package/lib/typescript/components/chart/types.d.ts.map +1 -0
  238. package/lib/typescript/components/chart/useChartHostWidth.d.ts +9 -0
  239. package/lib/typescript/components/chart/useChartHostWidth.d.ts.map +1 -0
  240. package/lib/typescript/components/index.d.ts +5 -0
  241. package/lib/typescript/components/index.d.ts.map +1 -1
  242. package/lib/typescript/figma/SystemAlert.Button.figma.d.ts +11 -0
  243. package/lib/typescript/figma/SystemAlert.Button.figma.d.ts.map +1 -0
  244. package/lib/typescript/figma/SystemAlert.Close.figma.d.ts +11 -0
  245. package/lib/typescript/figma/SystemAlert.Close.figma.d.ts.map +1 -0
  246. package/lib/typescript/figma/SystemAlert.Description.figma.d.ts +8 -0
  247. package/lib/typescript/figma/SystemAlert.Description.figma.d.ts.map +1 -0
  248. package/lib/typescript/figma/SystemAlert.IconButton.figma.d.ts +11 -0
  249. package/lib/typescript/figma/SystemAlert.IconButton.figma.d.ts.map +1 -0
  250. package/lib/typescript/figma/SystemAlert.figma.d.ts +8 -0
  251. package/lib/typescript/figma/SystemAlert.figma.d.ts.map +1 -0
  252. package/package.json +5 -5
  253. package/src/components/BarChart/geometry.ts +1469 -0
  254. package/src/components/BarChart/index.tsx +1424 -0
  255. package/src/components/BarChart/styles.ts +31 -0
  256. package/src/components/Button/index.tsx +1 -1
  257. package/src/components/Chip/styles.ts +3 -1
  258. package/src/components/LineChart/geometry.ts +957 -0
  259. package/src/components/LineChart/index.tsx +1109 -0
  260. package/src/components/LineChart/styles.ts +26 -0
  261. package/src/components/PieChart/geometry.ts +295 -0
  262. package/src/components/PieChart/index.tsx +715 -0
  263. package/src/components/PieChart/styles.ts +101 -0
  264. package/src/components/ProgressCircle/ProgressCircleRing.tsx +10 -39
  265. package/src/components/ProgressCircle/ProgressRing.tsx +60 -0
  266. package/src/components/ScrollShadow/useScrollShadow.ts +12 -11
  267. package/src/components/Stepper/index.tsx +452 -0
  268. package/src/components/Stepper/styles.ts +234 -0
  269. package/src/components/Stepper/useStepperLabelFit.ts +21 -0
  270. package/src/components/Stepper/useStepperLabelFit.web.ts +53 -0
  271. package/src/components/Stepper/useStepperRingColors.ts +29 -0
  272. package/src/components/SystemAlert/animation.ts +252 -0
  273. package/src/components/SystemAlert/index.tsx +684 -0
  274. package/src/components/SystemAlert/styles.ts +212 -0
  275. package/src/components/SystemAlert/useSystemAlertStatusBarStyle.ts +57 -0
  276. package/src/components/Tabs/index.tsx +4 -0
  277. package/src/components/Tabs/styles.ts +1 -1
  278. package/src/components/chart/ChartInspector.tsx +726 -0
  279. package/src/components/chart/format.ts +95 -0
  280. package/src/components/chart/index.ts +24 -0
  281. package/src/components/chart/motion.ts +98 -0
  282. package/src/components/chart/palette.tsx +247 -0
  283. package/src/components/chart/size.ts +21 -0
  284. package/src/components/chart/ticks.ts +53 -0
  285. package/src/components/chart/types.ts +183 -0
  286. package/src/components/chart/useChartHostWidth.ts +26 -0
  287. package/src/components/index.ts +5 -0
@@ -0,0 +1,703 @@
1
+ # Bar Chart (https://design.candescent.com/docs/components/bar-chart)
2
+
3
+ Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/charts-barchart--default)
4
+
5
+ `BarChart` follows the MUI X Charts shape. Pass your own rows as `dataset`, name the category column on the band axis, and give each series a `dataKey`. No row key is reserved, so a server payload can go in as is. The [Insights Overview](https://design.candescent.com/docs/patterns/dashboard/content.md#insights-overview) pattern shows compact bar charts inside dashboard cards.
6
+
7
+ ```tsx
8
+ import { BarChart } from '@cdx-ui/components';
9
+ ```
10
+
11
+ ## Basic
12
+
13
+ One series over a band axis. `xAxis[0].dataKey` names the category column; `series[].dataKey` names the value column. The plot uses Forge `--color-chart-simple-primary`.
14
+
15
+ ```tsx
16
+ import { BarChart } from '@cdx-ui/components';
17
+ import { MONTH_AXIS, SIGNUPS } from './_data';
18
+
19
+ export default function BarChartBasicDemo() {
20
+ return (
21
+ <BarChart
22
+ dataset={SIGNUPS}
23
+ xAxis={MONTH_AXIS}
24
+ series={[{ id: 'signups', dataKey: 'value', label: 'Signups' }]}
25
+ hideLegend
26
+ scrollable={false}
27
+ accessibilityLabel="Monthly signups"
28
+ />
29
+ );
30
+ }
31
+ ```
32
+
33
+ ## Sizes
34
+
35
+ `size` picks a preset plot box: `sm`, `md`, `lg` (the default), or `xl`. `width` and `height` override one side.
36
+
37
+ ```tsx
38
+ import { useState } from 'react';
39
+ import { BarChart, Box, Slider, VStack } from '@cdx-ui/components';
40
+ import { GROUPED, GROUPED_AXIS, SERIES } from './_data';
41
+
42
+ const SIZES = ['sm', 'md', 'lg', 'xl'] as const;
43
+
44
+ export default function BarChartSizesDemo() {
45
+ const [index, setIndex] = useState(2);
46
+ const size = SIZES[index] ?? 'lg';
47
+
48
+ return (
49
+ <VStack space="2xl" className="w-full items-center">
50
+ <Box className="w-full max-w-xs">
51
+ <Slider
52
+ value={index}
53
+ onChange={setIndex}
54
+ min={0}
55
+ max={SIZES.length - 1}
56
+ step={1}
57
+ accessibilityLabel="Chart size"
58
+ >
59
+ <Slider.Rail>
60
+ <Slider.Track />
61
+ </Slider.Rail>
62
+ <Slider.Thumb>
63
+ <Slider.Popup>{size}</Slider.Popup>
64
+ </Slider.Thumb>
65
+ <Slider.MarkerGroup>
66
+ <Slider.Marker />
67
+ </Slider.MarkerGroup>
68
+ </Slider>
69
+ </Box>
70
+ <BarChart
71
+ key={size}
72
+ dataset={GROUPED}
73
+ xAxis={GROUPED_AXIS}
74
+ series={SERIES}
75
+ size={size}
76
+ scrollable={false}
77
+ accessibilityLabel="Signups by channel"
78
+ />
79
+ </VStack>
80
+ );
81
+ }
82
+ ```
83
+
84
+ ## Horizontal
85
+
86
+ `layout="horizontal"` swaps the axes, as in MUI X: the category axis moves to `yAxis` and the value axis to `xAxis`. Use it when labels are longer than a month abbreviation. Grouped and stacked series work the same way; the second chart puts a loans stack and a cards stack in each quarter.
87
+
88
+ ```tsx
89
+ import { BarChart, VStack } from '@cdx-ui/components';
90
+ import { CHANNELS, PIPELINE } from './_data';
91
+
92
+ export default function BarChartHorizontalDemo() {
93
+ return (
94
+ <VStack space="2xl" className="w-full">
95
+ <BarChart
96
+ dataset={CHANNELS}
97
+ layout="horizontal"
98
+ yAxis={[{ id: 'channel', dataKey: 'channel', scaleType: 'band' }]}
99
+ series={[{ id: 'contacts', dataKey: 'contacts' }]}
100
+ barLabel
101
+ hideLegend
102
+ scrollable={false}
103
+ height={280}
104
+ accessibilityLabel="Contacts by channel"
105
+ />
106
+ <BarChart
107
+ dataset={PIPELINE}
108
+ layout="horizontal"
109
+ yAxis={[{ id: 'quarter', dataKey: 'quarter', scaleType: 'band' }]}
110
+ series={[
111
+ { id: 'newLoans', dataKey: 'newLoans', label: 'New loans', stack: 'loans' },
112
+ { id: 'renewals', dataKey: 'renewals', label: 'Renewals', stack: 'loans' },
113
+ { id: 'newCards', dataKey: 'newCards', label: 'New cards', stack: 'cards' },
114
+ { id: 'upgrades', dataKey: 'upgrades', label: 'Upgrades', stack: 'cards' },
115
+ ]}
116
+ barLabel
117
+ scrollable={false}
118
+ height={360}
119
+ accessibilityLabel="Loans and cards by quarter"
120
+ />
121
+ </VStack>
122
+ );
123
+ }
124
+ ```
125
+
126
+ ## Axis config
127
+
128
+ The value axis takes `min`, `max`, and `tickNumber` to set the domain and the number of ticks, and `valueFormatter` for tick text. A series `valueFormatter` wins over the axis one everywhere except ticks, so ticks can read `$1k` while the tooltip reads `$860`. `position: 'none'` on the value axis hides its ticks. On the category axis, `position` moves the names (`'top'` / `'bottom'` when vertical, `'left'` / `'right'` when horizontal, `'none'` to hide them) and a `tickLabelInterval` function picks which names draw.
129
+
130
+ ```tsx
131
+ import { BarChart } from '@cdx-ui/components';
132
+ import { formatWholeUsd, MONTH_AXIS, SIGNUPS } from './_data';
133
+
134
+ export default function BarChartAxisDemo() {
135
+ return (
136
+ <BarChart
137
+ dataset={SIGNUPS}
138
+ xAxis={MONTH_AXIS}
139
+ yAxis={[
140
+ {
141
+ id: 'revenue',
142
+ min: 0,
143
+ max: 1000,
144
+ tickNumber: 6,
145
+ valueFormatter: (value) => {
146
+ if (value === null) {
147
+ return '';
148
+ }
149
+ return value >= 1000 ? `$${String(value / 1000)}k` : `$${String(value)}`;
150
+ },
151
+ },
152
+ ]}
153
+ series={[
154
+ { id: 'revenue', dataKey: 'value', label: 'Revenue', valueFormatter: formatWholeUsd },
155
+ ]}
156
+ hideLegend
157
+ scrollable={false}
158
+ accessibilityLabel="Monthly revenue"
159
+ />
160
+ );
161
+ }
162
+ ```
163
+
164
+ ## Series colors
165
+
166
+ Each series draws its own bar in the category. Up to three series use `simple-primary`, `simple-secondary`, and `simple-tertiary` (the FI brand family). Four or more switch the whole chart to `categorical-1`…`6`; pass `palette="categorical"` to use them at any count. A series `color` (a chart token name) wins over both, as in this demo. The legend shows by default; `hideLegend` turns it off.
167
+
168
+ ```tsx
169
+ import { BarChart } from '@cdx-ui/components';
170
+ import { GROUPED, GROUPED_AXIS } from './_data';
171
+
172
+ export default function BarChartGroupedDemo() {
173
+ return (
174
+ <BarChart
175
+ dataset={GROUPED}
176
+ xAxis={GROUPED_AXIS}
177
+ series={[
178
+ { id: 'online', dataKey: 'online', label: 'Online', color: 'categorical-3' },
179
+ { id: 'retail', dataKey: 'retail', label: 'Retail', color: 'categorical-5' },
180
+ { id: 'direct', dataKey: 'direct', label: 'Direct', color: 'simple-secondary' },
181
+ ]}
182
+ scrollable={false}
183
+ accessibilityLabel="Signups by channel"
184
+ />
185
+ );
186
+ }
187
+ ```
188
+
189
+ ## Colors
190
+
191
+ A series `color` can also be a severity token: `danger`, `warning`, `success`, or `info`. Use one, on the series that carries the message. Pair it with `emphasizedIndex` to mute the other bars to neutral, so the severity color is the only hue on the plot. Here February's electric bill is flagged `warning`.
192
+
193
+ ```tsx
194
+ import { useState } from 'react';
195
+ import { BarChart, Box, Tabs, type ChartColor, type ChartValueFormatter } from '@cdx-ui/components';
196
+
197
+ const COLORS: readonly ChartColor[] = [
198
+ 'danger',
199
+ 'warning',
200
+ 'success',
201
+ 'info',
202
+ 'simple-primary',
203
+ 'simple-secondary',
204
+ 'simple-tertiary',
205
+ 'categorical-1',
206
+ 'categorical-2',
207
+ 'categorical-3',
208
+ 'categorical-4',
209
+ 'categorical-5',
210
+ 'categorical-6',
211
+ ];
212
+
213
+ const ELECTRIC = [
214
+ { month: 'Jan', bill: 128 },
215
+ { month: 'Feb', bill: 212 },
216
+ { month: 'Mar', bill: 121 },
217
+ { month: 'Apr', bill: 109 },
218
+ { month: 'May', bill: 102 },
219
+ { month: 'Jun', bill: 118 },
220
+ ];
221
+
222
+ const SPIKE_INDEX = 1;
223
+
224
+ const formatDollars: ChartValueFormatter = (value) => (value === null ? '' : `$${value}`);
225
+
226
+ export default function BarChartColorsDemo() {
227
+ const [color, setColor] = useState<string>('warning');
228
+
229
+ return (
230
+ <Tabs value={color} onValueChange={setColor} className="w-full">
231
+ <Box className="w-90 max-w-full self-center">
232
+ <Tabs.List accessibilityLabel="Bar color">
233
+ {COLORS.map((item) => (
234
+ <Tabs.Tab key={item} value={item}>
235
+ <Tabs.TabLabel>{item}</Tabs.TabLabel>
236
+ </Tabs.Tab>
237
+ ))}
238
+ </Tabs.List>
239
+ </Box>
240
+ {COLORS.map((item) => (
241
+ <Tabs.Panel key={item} value={item} className="mt-4">
242
+ <BarChart
243
+ dataset={ELECTRIC}
244
+ xAxis={[{ id: 'month', dataKey: 'month', scaleType: 'band' }]}
245
+ yAxis={[{ id: 'bill', position: 'none', max: 240 }]}
246
+ series={[
247
+ {
248
+ id: 'bill',
249
+ dataKey: 'bill',
250
+ label: 'Electric bill',
251
+ color: item,
252
+ valueFormatter: formatDollars,
253
+ },
254
+ ]}
255
+ grid={{ horizontal: false }}
256
+ emphasizedIndex={SPIKE_INDEX}
257
+ barLabel
258
+ hideLegend
259
+ scrollable={false}
260
+ accessibilityLabel="Electric bill by month. February is $212, about $95 above the usual bill."
261
+ />
262
+ </Tabs.Panel>
263
+ ))}
264
+ </Tabs>
265
+ );
266
+ }
267
+ ```
268
+
269
+ ## Stacking groups
270
+
271
+ Series with the same `stack` id pile into one bar. Different ids draw side by side, so one category can hold two stacks. `barLabel` labels each stack with its total. `stackGap` sets the gap between segments, and with a gap every segment is rounded. The second chart passes `stackGap={0}` to join the segments and `borderRadius={0}` to square the corners.
272
+
273
+ ```tsx
274
+ import { BarChart, VStack, type BarChartSeries, type ChartAxis } from '@cdx-ui/components';
275
+ import { PIPELINE, type QuarterPipeline } from './_data';
276
+
277
+ const PIPELINE_SERIES: BarChartSeries<QuarterPipeline>[] = [
278
+ { id: 'newLoans', dataKey: 'newLoans', label: 'New loans', stack: 'loans' },
279
+ { id: 'renewals', dataKey: 'renewals', label: 'Renewals', stack: 'loans' },
280
+ { id: 'newCards', dataKey: 'newCards', label: 'New cards', stack: 'cards' },
281
+ { id: 'upgrades', dataKey: 'upgrades', label: 'Upgrades', stack: 'cards' },
282
+ ];
283
+
284
+ const QUARTER_AXIS: ChartAxis<QuarterPipeline>[] = [
285
+ { id: 'quarter', dataKey: 'quarter', scaleType: 'band' },
286
+ ];
287
+
288
+ export default function BarChartStackedDemo() {
289
+ return (
290
+ <VStack space="2xl" className="w-full">
291
+ <BarChart
292
+ dataset={PIPELINE}
293
+ xAxis={QUARTER_AXIS}
294
+ series={PIPELINE_SERIES}
295
+ barLabel
296
+ scrollable={false}
297
+ accessibilityLabel="Loans and cards by quarter"
298
+ />
299
+ <BarChart
300
+ dataset={PIPELINE}
301
+ xAxis={QUARTER_AXIS}
302
+ series={PIPELINE_SERIES}
303
+ stackGap={0}
304
+ borderRadius={0}
305
+ barLabel
306
+ scrollable={false}
307
+ accessibilityLabel="Loans and cards by quarter, flat stacks"
308
+ />
309
+ </VStack>
310
+ );
311
+ }
312
+ ```
313
+
314
+ ## Stack expand
315
+
316
+ `stackOffset: 'expand'` on any series in the group scales every category to the same length, so each segment shows its share. Ticks, tooltip, and labels read percentages, and an axis `valueFormatter` receives a 0–1 share.
317
+
318
+ ```tsx
319
+ import { BarChart } from '@cdx-ui/components';
320
+ import { PLATFORMS } from './_data';
321
+
322
+ export default function BarChartStacked100Demo() {
323
+ return (
324
+ <BarChart
325
+ dataset={PLATFORMS}
326
+ xAxis={[{ id: 'month', dataKey: 'month', scaleType: 'band' }]}
327
+ series={[
328
+ { id: 'ios', dataKey: 'ios', label: 'iOS', stack: 'share', stackOffset: 'expand' },
329
+ { id: 'android', dataKey: 'android', label: 'Android', stack: 'share' },
330
+ { id: 'web', dataKey: 'web', label: 'Web', stack: 'share' },
331
+ ]}
332
+ scrollable={false}
333
+ accessibilityLabel="Sessions by platform"
334
+ />
335
+ );
336
+ }
337
+ ```
338
+
339
+ ## Negative values
340
+
341
+ Values below zero grow down from a zero baseline. The axis includes zero unless `min` says otherwise, so gains and losses read against the same line.
342
+
343
+ ```tsx
344
+ import { BarChart } from '@cdx-ui/components';
345
+ import { MONTH_AXIS, PROFIT } from './_data';
346
+
347
+ export default function BarChartNegativeDemo() {
348
+ return (
349
+ <BarChart
350
+ dataset={PROFIT}
351
+ xAxis={MONTH_AXIS}
352
+ series={[{ id: 'profit', dataKey: 'value', label: 'Profit' }]}
353
+ barLabel
354
+ hideLegend
355
+ scrollable={false}
356
+ accessibilityLabel="Monthly profit"
357
+ />
358
+ );
359
+ }
360
+ ```
361
+
362
+ ## Overlay
363
+
364
+ `overlay: { seriesId }` draws a series as a thinner comparison bar beside the series it names — this month versus last month, or actual versus budget. Screen readers hear the change after the primary value, worded by `localeText.trend`.
365
+
366
+ ```tsx
367
+ import { BarChart } from '@cdx-ui/components';
368
+ import { formatUsd, SPENDING } from './_data';
369
+
370
+ export default function BarChartOverlayDemo() {
371
+ return (
372
+ <BarChart
373
+ dataset={SPENDING}
374
+ layout="horizontal"
375
+ yAxis={[{ id: 'category', dataKey: 'category', scaleType: 'band' }]}
376
+ series={[
377
+ { id: 'this', dataKey: 'thisMonth', label: 'This month', valueFormatter: formatUsd },
378
+ {
379
+ id: 'last',
380
+ dataKey: 'lastMonth',
381
+ label: 'Last month',
382
+ overlay: { seriesId: 'this' },
383
+ valueFormatter: formatUsd,
384
+ },
385
+ ]}
386
+ barLabel
387
+ grid={{ vertical: false }}
388
+ xAxis={[{ id: 'amount', position: 'none' }]}
389
+ scrollable={false}
390
+ height={280}
391
+ accessibilityLabel="Spending this month versus last month"
392
+ />
393
+ );
394
+ }
395
+ ```
396
+
397
+ ## Waterfall
398
+
399
+ `waterfall: { totalKey }` turns a series into a running total. Each row is a change, except rows where your `totalKey` column is `true`: those draw from zero to the total so far. Pick any boolean column — a column named `sum` is ordinary data. Step names come from `localeText.waterfallIncrease` and `localeText.waterfallDecrease`.
400
+
401
+ ```tsx
402
+ import { BarChart } from '@cdx-ui/components';
403
+ import { formatUsd, WATERFALL } from './_data';
404
+
405
+ export default function BarChartWaterfallDemo() {
406
+ return (
407
+ <BarChart
408
+ dataset={WATERFALL}
409
+ layout="horizontal"
410
+ yAxis={[{ id: 'step', dataKey: 'step', scaleType: 'band' }]}
411
+ series={[
412
+ {
413
+ id: 'balance',
414
+ dataKey: 'amount',
415
+ waterfall: { totalKey: 'isTotal' },
416
+ valueFormatter: formatUsd,
417
+ },
418
+ ]}
419
+ barLabel
420
+ grid={{ vertical: false }}
421
+ xAxis={[{ id: 'amount', position: 'none' }]}
422
+ scrollable={false}
423
+ height={280}
424
+ accessibilityLabel="Checking starting balance, income, expenses, and ending balance"
425
+ />
426
+ );
427
+ }
428
+ ```
429
+
430
+ ## Reference line
431
+
432
+ `referenceLines` draws a dashed line at a value. `emphasizedIndex` keeps one bar in full color and mutes the rest — this week against a typical week. An empty category name hides that label.
433
+
434
+ ```tsx
435
+ import { BarChart } from '@cdx-ui/components';
436
+ import { DINING_WEEKS, formatWholeUsd } from './_data';
437
+
438
+ export default function BarChartReferenceDemo() {
439
+ return (
440
+ <BarChart
441
+ dataset={DINING_WEEKS}
442
+ xAxis={[{ id: 'week', dataKey: 'week', scaleType: 'band' }]}
443
+ series={[{ id: 'dining', dataKey: 'spend', valueFormatter: formatWholeUsd }]}
444
+ grid={{ horizontal: false }}
445
+ yAxis={[{ id: 'spend', position: 'none' }]}
446
+ hideLegend
447
+ barLabel
448
+ emphasizedIndex={DINING_WEEKS.length - 1}
449
+ referenceLines={[{ value: 340, label: 'Typical week $340' }]}
450
+ scrollable={false}
451
+ accessibilityLabel="Dining versus a typical week"
452
+ />
453
+ );
454
+ }
455
+ ```
456
+
457
+ ## Scrollable
458
+
459
+ When there are more categories than fit, the plot scrolls while the value axis stays put. `visiblePoints` sets how many categories are on screen at once.
460
+
461
+ ```tsx
462
+ import { BarChart, Box } from '@cdx-ui/components';
463
+ import { WEEKS } from './_data';
464
+
465
+ export default function BarChartScrollableDemo() {
466
+ return (
467
+ <Box className="w-64">
468
+ <BarChart
469
+ dataset={WEEKS}
470
+ xAxis={[{ id: 'week', dataKey: 'week', scaleType: 'band' }]}
471
+ series={[{ id: 'spend', dataKey: 'spend' }]}
472
+ hideLegend
473
+ visiblePoints={6}
474
+ accessibilityLabel="Weekly spend"
475
+ />
476
+ </Box>
477
+ );
478
+ }
479
+ ```
480
+
481
+ ## Selectable
482
+
483
+ Pass `selectedItem` and `onSelectedItemChange` to dim unselected bars. The item is `{ seriesId, dataIndex }`, where `dataIndex` is the `dataset` row. Pressing the selected bar again reports `null`. Use `defaultSelectedItem` for an uncontrolled chart.
484
+
485
+ ```tsx
486
+ import { useState } from 'react';
487
+ import { BarChart, Text, VStack, type ChartSelectedItem } from '@cdx-ui/components';
488
+ import { GROUPED, GROUPED_AXIS, SERIES } from './_data';
489
+
490
+ export default function BarChartSelectableDemo() {
491
+ const [selectedItem, setSelectedItem] = useState<ChartSelectedItem>({
492
+ seriesId: 'retail',
493
+ dataIndex: 1,
494
+ });
495
+ const row = selectedItem === null ? undefined : GROUPED[selectedItem.dataIndex];
496
+ const series = SERIES.find((item) => item.id === selectedItem?.seriesId);
497
+
498
+ return (
499
+ <VStack space="md" className="w-full">
500
+ <Text size="sm" color="secondary">
501
+ {row !== undefined && series !== undefined
502
+ ? `${row.month} ${series.label ?? ''} ${String(row[series.dataKey])}`
503
+ : 'Select a bar'}
504
+ </Text>
505
+ <BarChart
506
+ dataset={GROUPED}
507
+ xAxis={GROUPED_AXIS}
508
+ series={SERIES}
509
+ scrollable={false}
510
+ selectedItem={selectedItem}
511
+ onSelectedItemChange={setSelectedItem}
512
+ />
513
+ </VStack>
514
+ );
515
+ }
516
+ ```
517
+
518
+ ## Data change
519
+
520
+ Bars tween to their new values when `dataset` changes. Pass `animation="disable-all"` to draw the final state; Reduce Motion and `GlobalAnimationSettingsProvider` `disable-all` also turn it off.
521
+
522
+ ```tsx
523
+ import { useState } from 'react';
524
+ import { BarChart, Button, VStack } from '@cdx-ui/components';
525
+ import { GROUPED, GROUPED_AXIS, SERIES } from './_data';
526
+
527
+ export default function BarChartDataChangeDemo() {
528
+ const [step, setStep] = useState(0);
529
+ const dataset = GROUPED.map((row, index) => {
530
+ const shifted = GROUPED[(index + step) % GROUPED.length] ?? row;
531
+ return { ...shifted, month: row.month };
532
+ });
533
+
534
+ return (
535
+ <VStack space="lg" className="w-full items-center">
536
+ <BarChart
537
+ dataset={dataset}
538
+ xAxis={GROUPED_AXIS}
539
+ series={SERIES}
540
+ barLabel
541
+ scrollable={false}
542
+ accessibilityLabel="Signups by channel"
543
+ />
544
+ <Button
545
+ variant="outline"
546
+ onPress={() => {
547
+ setStep((prev) => prev + 1);
548
+ }}
549
+ >
550
+ <Button.Label>Shift data</Button.Label>
551
+ </Button>
552
+ </VStack>
553
+ );
554
+ }
555
+ ```
556
+
557
+ ## API
558
+
559
+ ### BarChart
560
+
561
+ Generic over your row type, shown here as `TRow`: `series[].dataKey` and axis `dataKey` must be keys of a `dataset` row.
562
+
563
+ | Prop | Type | Default | Description |
564
+ | --- | --- | --- | --- |
565
+ | `className?` | `string` | — | Additional Uniwind/Tailwind classes, merged after the root's own styles. |
566
+ | `accessibilityLabel?` | `string` | — | Accessible summary. Defaults to `localeText.barChartSummary` over every category. |
567
+ | `dataset` | `readonly TRow[]` | — | One object per category. Series and axes read it through `dataKey`. |
568
+ | `series` | `readonly BarChartSeries<TRow>[]` | — | Bars to draw. Each reads one numeric column through `dataKey`. |
569
+ | `xAxis?` | `readonly ChartAxis<TRow>[]` | — | Horizontal axis. In `vertical` layout it is the category (band) axis: `dataKey` names the category column, `position` (`'bottom'`, `'top'`, `'none'`) places its labels, and `tickLabelInterval` picks which labels draw. In `horizontal` layout it is the value axis. Only the first axis is used. |
570
+ | `yAxis?` | `readonly ChartAxis<TRow>[]` | — | Vertical axis. In `vertical` layout it is the value axis (`min`, `max`, `tickNumber`, `valueFormatter`; `position: 'none'` hides its ticks). In `horizontal` layout it is the category axis (`position` `'left'`, `'right'`, or `'none'`). Only the first axis is used. |
571
+ | `layout?` | `'vertical' \| 'horizontal'` | `'vertical'` | `vertical` grows bars up from the baseline. `horizontal` grows them to the right. |
572
+ | `hideLegend?` | `boolean` | `false` | Hides the series legend under the chart. Waterfall charts never show one. |
573
+ | `grid?` | `ChartGrid` | `{ horizontal: true } (vertical layout), { vertical: true } (horizontal layout)` | Grid lines along the value axis: `horizontal` in `vertical` layout, `vertical` in `horizontal` layout. The other direction is not drawn. Omit to draw the value-axis lines; pass an object without that key set to `true` to hide them and keep only the baseline. |
574
+ | `palette?` | `'auto' \| 'categorical'` | `'auto'` | Default series colors. `auto` uses the FI brand family (`simple-primary`, `-secondary`, `-tertiary`) for up to three series and switches the whole chart to `categorical-1`…`6` past that. `categorical` always uses the categorical slots. A series `color` wins. |
575
+ | `referenceLines?` | `readonly ChartReferenceLine[]` | — | Dashed guides at a value: horizontal on a vertical chart, vertical on a horizontal chart. |
576
+ | `emphasizedIndex?` | `number` | — | Keeps this `dataset` row full color and mutes the rest. Use with `barLabel` to label only that bar, like "this week" in a spending insight. |
577
+ | `barLabel?` | `boolean` | `false` | Draws formatted values at the end of each bar (each stack's total when stacked). |
578
+ | `borderRadius?` | `number` | `6` | Corner radius in pixels. `0` draws square bars. |
579
+ | `stackGap?` | `number` | `3` | Pixel gap between stacked segments. With a gap every segment is rounded; `0` joins them and rounds only the outer cap. |
580
+ | `categoryGapRatio?` | `number` | `0.36` | Share of each category slot left empty around its bars, from `0` to `0.95`. Higher is thinner bars with more space between categories. |
581
+ | `barGapRatio?` | `number` | `0.5` | Gap between side-by-side bars in one category, as a share of one bar's thickness. |
582
+ | `scrollable?` | `boolean` | `true` | When the categories need more room than the visible box, scroll instead of squeezing bars. Vertical charts scroll sideways; horizontal charts scroll vertically. The value axis stays pinned. Turn off to pack every category into `width` / `height`. |
583
+ | `visiblePoints?` | `number` | — | How many categories fit in the viewport when `scrollable` is on. Omit to use a readable minimum band (~48px). |
584
+ | `selectedItem?` | `ChartSelectedItem` | — | Controlled selected bar: `seriesId` and the `dataset` row. `null` clears the selection while staying controlled. |
585
+ | `defaultSelectedItem?` | `ChartSelectedItem` | — | Initial selected bar when `selectedItem` is omitted. |
586
+ | `onSelectedItemChange?` | `((item: ChartSelectedItem) => void)` | — | Called when a bar is pressed, with that bar, or with `null` when the selected bar is pressed again. Providing this, `selectedItem`, or `defaultSelectedItem` makes the chart selectable. |
587
+ | `tooltip?` | `ChartTooltipProps` | `{ trigger: 'axis' }` | Tooltip on hover, keyboard focus, or tap. `axis` lists every series in the category, `item` only the bar under the pointer, `none` hides it. On web the plot is one tab stop. Tab / Shift+Tab move between categories and leave the chart after the last (or before the first) group. Arrow keys move along the category axis (and between series). Home and End jump to the first or last category. Enter or Space selects. Escape hides the tooltip. Each bar is announced to screen readers. |
588
+ | `locale?` | `string` | — | BCP 47 locale for default number and percent formatting. |
589
+ | `localeText?` | `Partial<ChartLocaleText>` | — | Overrides for generated strings: summary, trend, waterfall step names, legend fallback, and no-value text. Keys you omit keep the English defaults. |
590
+ | `animation?` | `'disable-all'` | — | Bars grow from the baseline on mount and tween to new values when `dataset` changes. Pass `'disable-all'` to draw the final state. Reduce Motion and `GlobalAnimationSettingsProvider` `disable-all` also turn it off. |
591
+ | `size?` | `'sm' \| 'md' \| 'lg' \| 'xl'` | `'lg'` | Plot box. Named sizes set both width and height; `width` / `height` override one side. |
592
+ | `width?` | `number` | — | Pixel width. Overrides the `size` width. |
593
+ | `height?` | `number` | — | Pixel height. Overrides the `size` height. |
594
+
595
+ Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
596
+
597
+ | Attribute | Values | Description |
598
+ | --------------- | ----------------- | --------------------------------------------------------------- |
599
+ | `data-selected` | `true` \| `false` | On each `bar-chart-point`: whether that bar is the selected one |
600
+
601
+ ### BarChartSeries
602
+
603
+ One entry in `series`. The first series with `waterfall`, or the first `overlay` pair, draws alone.
604
+
605
+ | Prop | Type | Default | Description |
606
+ | --- | --- | --- | --- |
607
+ | `type?` | `'bar'` | — | Series type. Reserved for mixed charts; bar is the only type today. |
608
+ | `stack?` | `string` | — | Stack group id. Series with the same `stack` draw as one bar per category; different ids draw side by side. Omit to draw the series on its own. |
609
+ | `stackOffset?` | `'diverging' \| 'none' \| 'expand'` | `'diverging'` | How the stack group piles its values. Set it on any one series in the group. `expand` scales each category to 100%. |
610
+ | `waterfall?` | `BarChartWaterfall<TRow>` | — | Draws the series as a waterfall (running total). A waterfall series draws alone: other series are not plotted. |
611
+ | `overlay?` | `BarChartOverlay` | — | Draws the series as a thin comparison bar beside the series it names (this month versus last month). The pair draws alone, and the named series is announced with the change. |
612
+ | `dataKey` | `string` | — | Numeric column in `dataset`. A key that is not on the row type is a compile error. |
613
+ | `id` | `string` | — | Stable id. `selectedItem.seriesId` and tooltip items refer to it. |
614
+ | `label?` | `string` | — | Series name. Bar and line charts show it in the legend, tooltip, and screen reader text. A pie chart only prefixes tooltip values with it; slice labels name the legend and slices. |
615
+ | `color?` | `'danger' \| 'warning' \| 'success' \| 'info' \| 'simple-primary' \| 'simple-secondary' \| 'simple-tertiary' \| 'categorical-1' \| 'categorical-2' \| 'categorical-3' \| 'categorical-4' \| 'categorical-5' \| 'categorical-6'` | — | Chart token name, not a CSS color. Omit to take the next color from the chart's `palette`. |
616
+ | `valueFormatter?` | `ChartValueFormatter` | — | Formats this series' values for tooltips and screen reader text, plus bar value labels, line marker values, and a pie's legend value column. `context.location` says where. On charts with axes it wins over the value axis `valueFormatter`. |
617
+
618
+ ### ChartAxis
619
+
620
+ One entry in `xAxis` or `yAxis`. Only the first entry in each direction is read.
621
+
622
+ | Prop | Type | Default | Description |
623
+ | --- | --- | --- | --- |
624
+ | `id` | `string` | — | Axis id, as in MUI X. |
625
+ | `dataKey?` | `string` | — | Column in `dataset` that holds this axis's values (category names on a band axis). |
626
+ | `scaleType?` | `'band' \| 'linear'` | — | Scale kind, as in MUI X. Accepted for parity; charts do not read it yet. |
627
+ | `min?` | `number` | — | Lowest value on a value axis. Omit to fit the data. |
628
+ | `max?` | `number` | — | Highest value on a value axis. Omit to fit the data. |
629
+ | `tickNumber?` | `number` | — | Approximate tick count. The chart rounds to readable steps. |
630
+ | `label?` | `string` | — | Axis title, as in MUI X. Accepted for parity; not drawn yet. |
631
+ | `valueFormatter?` | `ChartValueFormatter` | — | Formats tick text on this axis (`location: 'tick'`). On a value axis it also formats series values when the series has no `valueFormatter`. On a line chart's x-axis it formats numeric categories, both the tick (`location: 'tick'`) and the tooltip title (`location: 'tooltip'`). |
632
+ | `position?` | `'top' \| 'bottom' \| 'left' \| 'right' \| 'none'` | — | Side the axis labels draw on. `'none'` hides them. Each chart accepts the sides it can draw and falls back to its default side for the others. |
633
+ | `tickLabelInterval?` | `"auto" \| ((value: unknown, index: number) => boolean)` | `'auto'` | Which category labels to draw. A function keeps the label at `index` when it returns `true`. `'auto'` currently draws every label; it does not thin them yet. |
634
+
635
+ Formatters resolve per value: the series `valueFormatter`, then the value axis `valueFormatter`, then a `locale` number. Ticks use the axis formatter with `location: 'tick'`.
636
+
637
+ On the value axis, `position: 'none'` hides the ticks; any other side falls back to the default (left in `vertical` layout, bottom in `horizontal`). On the category axis, `position` picks the side for the names. `tickLabelInterval: 'auto'` pins the first and last names inside the plot.
638
+
639
+ ### ChartLocaleText
640
+
641
+ Every string the chart generates. Pass any subset as `localeText`.
642
+
643
+ | Prop | Type | Default | Description |
644
+ | --- | --- | --- | --- |
645
+ | `noData` | `string` | — | Shown when there is nothing to plot. |
646
+ | `noValue` | `string` | — | Tooltip and screen reader text for a category with no value. |
647
+ | `defaultSeriesLabel` | `string` | — | Legend name for a series without a `label`. |
648
+ | `waterfallIncrease` | `string` | — | Waterfall step that raises the running total. |
649
+ | `waterfallDecrease` | `string` | — | Waterfall step that lowers the running total. |
650
+ | `trend` | `(trend: ChartTrend) => string` | — | Change against the comparison series, read after the value. |
651
+ | `barChartSummary` | `(categories: readonly ChartSummaryCategory[]) => string` | — | Bar chart summary. Called with an empty list when there is no data. |
652
+ | `lineChartSummary` | `(latest: ChartSummaryCategory \| null) => string` | — | Line chart summary of the latest category. `null` when there is no data. |
653
+ | `pieChartSummary` | `(slices: readonly ChartSummaryValue[]) => string` | — | Pie chart summary. `formattedValue` is the share. Empty list when there is no data. |
654
+
655
+ ### Coming from MUI X
656
+
657
+ Forge renders with `react-native-svg` on iOS, Android, and web, and does not depend on MUI. The props follow MUI X Charts names so a migration is mostly a copy.
658
+
659
+ | MUI X | Forge | Notes |
660
+ | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
661
+ | `dataset` | `dataset` | Same. |
662
+ | `series[].dataKey`, `id`, `label`, `color`, `valueFormatter` | same names | `color` is a chart token name, not a CSS color, so FI themes and dark mode recolor it. |
663
+ | `series[].data` | — | Read values from `dataset` through `dataKey`. |
664
+ | `series[].stack`, `stackOffset` | same names | `'diverging'`, `'none'`, and `'expand'`. `stackOrder` is not supported yet. |
665
+ | `xAxis` / `yAxis` (`id`, `dataKey`, `scaleType`, `min`, `max`, `tickNumber`, `valueFormatter`) | same names | Only the first axis in each direction is read, and only `band` category axes render today. |
666
+ | `layout` | `layout` | Same. The category axis moves to `yAxis` in `horizontal`, as in MUI X. |
667
+ | `borderRadius` | `borderRadius` | Same. |
668
+ | `barLabel` | `barLabel` | A chart-level boolean. MUI X takes `'value'` or a function, per series in recent versions. Format label text with the series `valueFormatter` (`location: 'label'`). |
669
+ | `xAxis[].categoryGapRatio`, `barGapRatio` | `categoryGapRatio`, `barGapRatio` | Same meaning, but chart-level props: Forge has one band axis, and the shared `ChartAxis` type is the same for every chart. |
670
+ | `hideLegend` | `hideLegend` | Same default (`false`). |
671
+ | `colors` | `palette` + series `color` | MUI takes CSS colors or a function. Forge takes chart token names, so FI themes and dark mode recolor every chart: `palette` picks the default ramp, and a series `color` names one token. |
672
+ | `slotProps.tooltip.trigger` | `tooltip.trigger` | `'axis'` by default, as in MUI X. Custom tooltip content is not supported yet. |
673
+ | `grid={{ horizontal, vertical }}` | `grid` | Same shape, but only the lines along the value axis draw, and they are on by default. MUI draws no grid unless you pass `grid`. |
674
+ | axis `position` | axis `position` | `'none'` hides an axis. The value axis draws only on its default side. |
675
+ | axis `tickLabelInterval` | axis `tickLabelInterval` | The function form works on the category axis. `'auto'` draws every label for now. |
676
+ | `<ChartsReferenceLine>` | `referenceLines` | Forge has no composition API yet, so reference lines are a prop. |
677
+ | `highlightedItem` / `onItemClick` | `selectedItem` / `onSelectedItemChange` | Selection is shared by every Forge chart. Pressing the selected bar reports `null`. `defaultSelectedItem` is a Forge addition for uncontrolled use. |
678
+ | `skipAnimation` | `animation="disable-all"` | Matches the `animation` prop on other Forge components. |
679
+ | `localeText` | `localeText` | Keys are Forge's: `barChartSummary`, `trend`, `waterfallIncrease`, `waterfallDecrease`, `defaultSeriesLabel`, `noValue`. |
680
+ | — | `waterfall: { totalKey }` | MUI X has no waterfall series. |
681
+ | — | `overlay: { seriesId }` | MUI X has no comparison overlay. The option names the series it compares against, the way `selectedItem` does. |
682
+ | — | `emphasizedIndex`, `scrollable`, `visiblePoints`, `stackGap` | Forge additions for insight cards and long category lists. |
683
+
684
+ ## Anatomy
685
+
686
+ | `data-slot` | Element |
687
+ | ----------------------- | --------------------------------------------------------------- |
688
+ | `bar-chart` | Root |
689
+ | `bar-chart-plot` | Plot area: axes, bars, and the inspector overlay |
690
+ | `bar-chart-inspector` | Overlay of bar hit targets, when the tooltip or selection is on |
691
+ | `bar-chart-point` | Hit target for one bar |
692
+ | `bar-chart-focus` | Keyboard focus ring |
693
+ | `bar-chart-tooltip` | Tooltip |
694
+ | `bar-chart-legend` | Legend |
695
+ | `bar-chart-legend-item` | One legend entry |
696
+
697
+ ## Accessibility
698
+
699
+ By default the plot is a group with the chart summary as its label, and every drawn bar inside it is a button. When the chart has no tooltip (`tooltip={{ trigger: 'none' }}`), no selection props, and `hideLegend`, the root becomes a single `accessibilityRole="image"` with the summary as its label instead. With a legend but no tooltip or selection, only the legend text is read and no summary is announced. The summary comes from `localeText.barChartSummary`, which receives each category's values formatted with `location: 'a11y'`. Pass `accessibilityLabel` to replace it, or `localeText` to reword or translate it.
700
+
701
+ Axes, grid, bars, and value labels are SVG hidden from assistive technology, as are the tooltip and the focus ring. Legend names stay readable. Each bar is named by its category, series label, and formatted value, such as "Feb, Paid, 34". Waterfall steps take `localeText.waterfallIncrease` or `localeText.waterfallDecrease` as their series name. In an overlay pair, the primary bar's name ends with the change worded by `localeText.trend`, and the comparison bar is announced on its own.
702
+
703
+ On web the plot is one tab stop. Arrow keys move between bars, Home and End jump to the first or last category, Tab and Shift+Tab step through categories before leaving the chart, and Escape hides the tooltip. On native every bar is focusable and the escape gesture hides the tooltip. In a selectable chart, pressing a bar or pressing Enter or Space toggles its selection, exposed as `aria-pressed` on web and `accessibilityState.selected` on native.