@cdx-ui/components 0.2.3 → 0.2.5

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 (296) hide show
  1. package/AGENTS.md +24 -0
  2. package/README.md +2 -0
  3. package/coverage.svg +1 -1
  4. package/docs/components/accordion/content.md +538 -0
  5. package/docs/components/alert/content.md +203 -0
  6. package/docs/components/alert-dialog/content.md +319 -0
  7. package/docs/components/avatar/content.md +368 -0
  8. package/docs/components/avatar/design.md +202 -0
  9. package/docs/components/badge/content.md +225 -0
  10. package/docs/components/bottom-sheet/content.md +353 -0
  11. package/docs/components/bottom-sheet/design.md +249 -0
  12. package/docs/components/box/content.md +141 -0
  13. package/docs/components/breadcrumbs/content.md +169 -0
  14. package/docs/components/button/content.md +398 -0
  15. package/docs/components/button/design.md +258 -0
  16. package/docs/components/calendar/content.md +137 -0
  17. package/docs/components/card/content.md +283 -0
  18. package/docs/components/carousel/content.md +417 -0
  19. package/docs/components/checkbox/content.md +236 -0
  20. package/docs/components/checkbox/design.md +214 -0
  21. package/docs/components/chip/content.md +439 -0
  22. package/docs/components/chip/design.md +418 -0
  23. package/docs/components/color-area/content.md +84 -0
  24. package/docs/components/color-field/content.md +132 -0
  25. package/docs/components/color-picker/content.md +209 -0
  26. package/docs/components/color-slider/content.md +118 -0
  27. package/docs/components/color-swatch/content.md +62 -0
  28. package/docs/components/color-swatch-picker/content.md +124 -0
  29. package/docs/components/content.md +98 -0
  30. package/docs/components/currency-input/content.md +205 -0
  31. package/docs/components/data-grid/content.md +521 -0
  32. package/docs/components/date-field/content.md +147 -0
  33. package/docs/components/date-picker/content.md +360 -0
  34. package/docs/components/date-range-picker/content.md +301 -0
  35. package/docs/components/date-time-field/content.md +157 -0
  36. package/docs/components/date-time-list/content.md +105 -0
  37. package/docs/components/date-time-picker/content.md +272 -0
  38. package/docs/components/dialog/content.md +436 -0
  39. package/docs/components/dialog/design.md +192 -0
  40. package/docs/components/divider/content.md +112 -0
  41. package/docs/components/drawer/content.md +428 -0
  42. package/docs/components/field/content.md +277 -0
  43. package/docs/components/form/content.md +62 -0
  44. package/docs/components/full-screen-dialog/content.md +881 -0
  45. package/docs/components/heading/content.md +55 -0
  46. package/docs/components/icon/content.md +190 -0
  47. package/docs/components/icon-button/content.md +200 -0
  48. package/docs/components/icon-button/design.md +165 -0
  49. package/docs/components/image/content.md +104 -0
  50. package/docs/components/input/content.md +346 -0
  51. package/docs/components/input/design.md +389 -0
  52. package/docs/components/insurance-disclosure/content.md +103 -0
  53. package/docs/components/link/content.md +180 -0
  54. package/docs/components/link/design.md +160 -0
  55. package/docs/components/list-item/content.md +695 -0
  56. package/docs/components/menu/content.md +1254 -0
  57. package/docs/components/month-calendar/content.md +84 -0
  58. package/docs/components/month-picker/content.md +273 -0
  59. package/docs/components/otp-input/content.md +327 -0
  60. package/docs/components/progress-bar/content.md +87 -0
  61. package/docs/components/progress-circle/content.md +176 -0
  62. package/docs/components/progress-segmented/content.md +119 -0
  63. package/docs/components/quick-action-button/content.md +154 -0
  64. package/docs/components/quick-action-button/design.md +170 -0
  65. package/docs/components/radio/content.md +224 -0
  66. package/docs/components/range-calendar/content.md +123 -0
  67. package/docs/components/reorderable-list/content.md +311 -0
  68. package/docs/components/scoped-theme/content.md +47 -0
  69. package/docs/components/scroll-shadow/content.md +693 -0
  70. package/docs/components/select/content.md +473 -0
  71. package/docs/components/select/design.md +301 -0
  72. package/docs/components/skeleton/content.md +104 -0
  73. package/docs/components/slider/content.md +423 -0
  74. package/docs/components/stack/content.md +161 -0
  75. package/docs/components/switch/content.md +150 -0
  76. package/docs/components/switch/design.md +208 -0
  77. package/docs/components/table/content.md +548 -0
  78. package/docs/components/table-pagination/content.md +177 -0
  79. package/docs/components/tabs/content.md +297 -0
  80. package/docs/components/text/content.md +142 -0
  81. package/docs/components/textarea/content.md +222 -0
  82. package/docs/components/tile/content.md +702 -0
  83. package/docs/components/toast/content.md +456 -0
  84. package/docs/components/toggle-button/content.md +505 -0
  85. package/docs/components/tooltip/content.md +350 -0
  86. package/docs/components/virtualized-list/content.md +250 -0
  87. package/docs/foundations/content.md +9 -0
  88. package/docs/foundations/expressions/icons/content.md +19 -0
  89. package/docs/foundations/styles/tokens/all-tokens/content.md +192 -0
  90. package/docs/foundations/styles/tokens/what-are-tokens/content.md +33 -0
  91. package/docs/foundations/styles/tokens/what-are-tokens/design.md +33 -0
  92. package/docs/getting-started/content.md +4 -0
  93. package/docs/getting-started/designers/content.md +13 -0
  94. package/docs/getting-started/designers/design.md +13 -0
  95. package/docs/getting-started/developers/accessibility/content.md +31 -0
  96. package/docs/getting-started/developers/content.md +612 -0
  97. package/docs/getting-started/developers/styling/content.md +195 -0
  98. package/docs/llms.txt +195 -0
  99. package/docs/patterns/account-management/content.md +75 -0
  100. package/docs/patterns/authentication/content.md +50 -0
  101. package/docs/patterns/content.md +10 -0
  102. package/docs/patterns/dashboard/content.md +34 -0
  103. package/docs/patterns/empty-states/content.md +32 -0
  104. package/docs/patterns/forms/content.md +108 -0
  105. package/docs/patterns/onboarding/content.md +69 -0
  106. package/docs/patterns/payments/content.md +35 -0
  107. package/docs/patterns/settings/content.md +72 -0
  108. package/docs/resources/content.md +9 -0
  109. package/docs/resources/figma-libraries/content.md +42 -0
  110. package/docs/resources/release-notes/0.0.1-beta.118/content.md +27 -0
  111. package/docs/resources/release-notes/0.0.1-beta.122/content.md +21 -0
  112. package/docs/resources/release-notes/0.0.1-beta.124/content.md +16 -0
  113. package/docs/resources/release-notes/0.0.1-beta.126/content.md +10 -0
  114. package/docs/resources/release-notes/0.0.1-beta.127/content.md +14 -0
  115. package/docs/resources/release-notes/0.0.1-beta.128/content.md +9 -0
  116. package/docs/resources/release-notes/0.0.1-beta.129/content.md +18 -0
  117. package/docs/resources/release-notes/0.0.1-beta.130/content.md +18 -0
  118. package/docs/resources/release-notes/0.0.1-beta.133/content.md +7 -0
  119. package/docs/resources/release-notes/0.0.1-beta.134/content.md +17 -0
  120. package/docs/resources/release-notes/0.0.1-beta.136/content.md +7 -0
  121. package/docs/resources/release-notes/0.0.1-beta.137/content.md +10 -0
  122. package/docs/resources/release-notes/0.0.1-beta.138/content.md +7 -0
  123. package/docs/resources/release-notes/0.0.1-beta.139/content.md +13 -0
  124. package/docs/resources/release-notes/0.0.1-beta.140/content.md +26 -0
  125. package/docs/resources/release-notes/0.0.1-beta.141/content.md +63 -0
  126. package/docs/resources/release-notes/0.0.1-beta.142/content.md +7 -0
  127. package/docs/resources/release-notes/0.0.1-beta.143/content.md +12 -0
  128. package/docs/resources/release-notes/0.0.1-beta.144/content.md +7 -0
  129. package/docs/resources/release-notes/0.0.1-beta.145/content.md +7 -0
  130. package/docs/resources/release-notes/0.0.1-beta.147/content.md +10 -0
  131. package/docs/resources/release-notes/0.0.1-beta.149/content.md +10 -0
  132. package/docs/resources/release-notes/0.0.1-beta.150/content.md +13 -0
  133. package/docs/resources/release-notes/0.0.1-beta.152/content.md +7 -0
  134. package/docs/resources/release-notes/0.0.1-beta.154/content.md +15 -0
  135. package/docs/resources/release-notes/0.0.1-beta.156/content.md +7 -0
  136. package/docs/resources/release-notes/0.0.1-beta.158/content.md +9 -0
  137. package/docs/resources/release-notes/0.0.1-beta.159/content.md +11 -0
  138. package/docs/resources/release-notes/0.0.1-beta.160/content.md +7 -0
  139. package/docs/resources/release-notes/0.0.1-beta.161/content.md +7 -0
  140. package/docs/resources/release-notes/0.0.1-beta.163/content.md +7 -0
  141. package/docs/resources/release-notes/0.0.1-beta.164/content.md +9 -0
  142. package/docs/resources/release-notes/0.0.1-beta.166/content.md +17 -0
  143. package/docs/resources/release-notes/0.0.1-beta.167/content.md +7 -0
  144. package/docs/resources/release-notes/0.0.1-beta.168/content.md +7 -0
  145. package/docs/resources/release-notes/0.0.1-beta.169/content.md +7 -0
  146. package/docs/resources/release-notes/0.0.1-beta.171/content.md +16 -0
  147. package/docs/resources/release-notes/0.0.1-beta.172/content.md +24 -0
  148. package/docs/resources/release-notes/0.0.1-beta.173/content.md +15 -0
  149. package/docs/resources/release-notes/0.0.1-beta.174/content.md +7 -0
  150. package/docs/resources/release-notes/0.0.1-beta.176/content.md +32 -0
  151. package/docs/resources/release-notes/0.0.1-beta.179/content.md +11 -0
  152. package/docs/resources/release-notes/0.0.1-beta.182/content.md +13 -0
  153. package/docs/resources/release-notes/0.0.1-beta.185/content.md +7 -0
  154. package/docs/resources/release-notes/0.0.1-beta.187/content.md +27 -0
  155. package/docs/resources/release-notes/0.1.1/content.md +23 -0
  156. package/docs/resources/release-notes/0.1.2/content.md +7 -0
  157. package/docs/resources/release-notes/0.1.4/content.md +19 -0
  158. package/docs/resources/release-notes/0.1.5/content.md +7 -0
  159. package/docs/resources/release-notes/0.1.6/content.md +7 -0
  160. package/docs/resources/release-notes/0.2.0/content.md +31 -0
  161. package/docs/resources/release-notes/0.2.1/content.md +17 -0
  162. package/docs/resources/release-notes/0.2.2/content.md +11 -0
  163. package/docs/resources/release-notes/0.2.3/content.md +15 -0
  164. package/docs/resources/release-notes/0.2.4/content.md +17 -0
  165. package/docs/resources/release-notes/content.md +65 -0
  166. package/lib/commonjs/components/Box/Box.js +9 -1
  167. package/lib/commonjs/components/Box/Box.js.map +1 -1
  168. package/lib/commonjs/components/Breadcrumbs/index.js +28 -3
  169. package/lib/commonjs/components/Breadcrumbs/index.js.map +1 -1
  170. package/lib/commonjs/components/Breadcrumbs/styles.js +27 -0
  171. package/lib/commonjs/components/Breadcrumbs/styles.js.map +1 -1
  172. package/lib/commonjs/components/DateTimeList/index.js +11 -26
  173. package/lib/commonjs/components/DateTimeList/index.js.map +1 -1
  174. package/lib/commonjs/components/DateTimeList/styles.js +2 -12
  175. package/lib/commonjs/components/DateTimeList/styles.js.map +1 -1
  176. package/lib/commonjs/components/ListItem/index.js.map +1 -1
  177. package/lib/commonjs/components/ListItem/styles.js +2 -1
  178. package/lib/commonjs/components/ListItem/styles.js.map +1 -1
  179. package/lib/commonjs/components/Menu/index.js +11 -5
  180. package/lib/commonjs/components/Menu/index.js.map +1 -1
  181. package/lib/commonjs/components/ScrollShadow/gradient.js +29 -0
  182. package/lib/commonjs/components/ScrollShadow/gradient.js.map +1 -0
  183. package/lib/commonjs/components/ScrollShadow/index.js +171 -44
  184. package/lib/commonjs/components/ScrollShadow/index.js.map +1 -1
  185. package/lib/commonjs/components/ScrollShadow/styles.js +58 -14
  186. package/lib/commonjs/components/ScrollShadow/styles.js.map +1 -1
  187. package/lib/commonjs/components/ScrollShadow/useComposedScrollHandler.js +63 -0
  188. package/lib/commonjs/components/ScrollShadow/useComposedScrollHandler.js.map +1 -0
  189. package/lib/commonjs/components/ScrollShadow/useScrollShadow.js +48 -8
  190. package/lib/commonjs/components/ScrollShadow/useScrollShadow.js.map +1 -1
  191. package/lib/commonjs/components/Stack/HStack.js +6 -2
  192. package/lib/commonjs/components/Stack/HStack.js.map +1 -1
  193. package/lib/commonjs/components/Stack/VStack.js +6 -2
  194. package/lib/commonjs/components/Stack/VStack.js.map +1 -1
  195. package/lib/commonjs/components/Tabs/index.js +16 -23
  196. package/lib/commonjs/components/Tabs/index.js.map +1 -1
  197. package/lib/commonjs/components/Tabs/styles.js +1 -10
  198. package/lib/commonjs/components/Tabs/styles.js.map +1 -1
  199. package/lib/commonjs/figma/ListItem.SectionHeader.figma.js +20 -5
  200. package/lib/commonjs/figma/ListItem.SectionHeader.figma.js.map +1 -1
  201. package/lib/commonjs/index.js +10 -10
  202. package/lib/commonjs/index.js.map +1 -1
  203. package/lib/module/components/Box/Box.js +9 -1
  204. package/lib/module/components/Box/Box.js.map +1 -1
  205. package/lib/module/components/Breadcrumbs/index.js +29 -4
  206. package/lib/module/components/Breadcrumbs/index.js.map +1 -1
  207. package/lib/module/components/Breadcrumbs/styles.js +26 -0
  208. package/lib/module/components/Breadcrumbs/styles.js.map +1 -1
  209. package/lib/module/components/DateTimeList/index.js +12 -27
  210. package/lib/module/components/DateTimeList/index.js.map +1 -1
  211. package/lib/module/components/DateTimeList/styles.js +1 -11
  212. package/lib/module/components/DateTimeList/styles.js.map +1 -1
  213. package/lib/module/components/ListItem/index.js.map +1 -1
  214. package/lib/module/components/ListItem/styles.js +2 -1
  215. package/lib/module/components/ListItem/styles.js.map +1 -1
  216. package/lib/module/components/Menu/index.js +11 -5
  217. package/lib/module/components/Menu/index.js.map +1 -1
  218. package/lib/module/components/ScrollShadow/gradient.js +24 -0
  219. package/lib/module/components/ScrollShadow/gradient.js.map +1 -0
  220. package/lib/module/components/ScrollShadow/index.js +170 -48
  221. package/lib/module/components/ScrollShadow/index.js.map +1 -1
  222. package/lib/module/components/ScrollShadow/styles.js +57 -13
  223. package/lib/module/components/ScrollShadow/styles.js.map +1 -1
  224. package/lib/module/components/ScrollShadow/useComposedScrollHandler.js +57 -0
  225. package/lib/module/components/ScrollShadow/useComposedScrollHandler.js.map +1 -0
  226. package/lib/module/components/ScrollShadow/useScrollShadow.js +46 -8
  227. package/lib/module/components/ScrollShadow/useScrollShadow.js.map +1 -1
  228. package/lib/module/components/Stack/HStack.js +6 -2
  229. package/lib/module/components/Stack/HStack.js.map +1 -1
  230. package/lib/module/components/Stack/VStack.js +6 -2
  231. package/lib/module/components/Stack/VStack.js.map +1 -1
  232. package/lib/module/components/Tabs/index.js +17 -24
  233. package/lib/module/components/Tabs/index.js.map +1 -1
  234. package/lib/module/components/Tabs/styles.js +0 -9
  235. package/lib/module/components/Tabs/styles.js.map +1 -1
  236. package/lib/module/figma/ListItem.SectionHeader.figma.js +20 -5
  237. package/lib/module/figma/ListItem.SectionHeader.figma.js.map +1 -1
  238. package/lib/module/index.js +6 -1
  239. package/lib/module/index.js.map +1 -1
  240. package/lib/typescript/animation/hooks/usePopupDialogContentAnimation.d.ts +2 -2
  241. package/lib/typescript/animation/hooks/usePopupOverlayAnimation.d.ts +2 -2
  242. package/lib/typescript/components/Box/Box.d.ts +4 -0
  243. package/lib/typescript/components/Box/Box.d.ts.map +1 -1
  244. package/lib/typescript/components/Breadcrumbs/index.d.ts +3 -1
  245. package/lib/typescript/components/Breadcrumbs/index.d.ts.map +1 -1
  246. package/lib/typescript/components/Breadcrumbs/styles.d.ts +2 -0
  247. package/lib/typescript/components/Breadcrumbs/styles.d.ts.map +1 -1
  248. package/lib/typescript/components/DateTimeList/index.d.ts.map +1 -1
  249. package/lib/typescript/components/DateTimeList/styles.d.ts +1 -4
  250. package/lib/typescript/components/DateTimeList/styles.d.ts.map +1 -1
  251. package/lib/typescript/components/ListItem/index.d.ts +5 -4
  252. package/lib/typescript/components/ListItem/index.d.ts.map +1 -1
  253. package/lib/typescript/components/ListItem/styles.d.ts +1 -1
  254. package/lib/typescript/components/ListItem/styles.d.ts.map +1 -1
  255. package/lib/typescript/components/Menu/index.d.ts.map +1 -1
  256. package/lib/typescript/components/ScrollShadow/gradient.d.ts +7 -0
  257. package/lib/typescript/components/ScrollShadow/gradient.d.ts.map +1 -0
  258. package/lib/typescript/components/ScrollShadow/index.d.ts +57 -15
  259. package/lib/typescript/components/ScrollShadow/index.d.ts.map +1 -1
  260. package/lib/typescript/components/ScrollShadow/styles.d.ts +8 -2
  261. package/lib/typescript/components/ScrollShadow/styles.d.ts.map +1 -1
  262. package/lib/typescript/components/ScrollShadow/useComposedScrollHandler.d.ts +13 -0
  263. package/lib/typescript/components/ScrollShadow/useComposedScrollHandler.d.ts.map +1 -0
  264. package/lib/typescript/components/ScrollShadow/useScrollShadow.d.ts +15 -2
  265. package/lib/typescript/components/ScrollShadow/useScrollShadow.d.ts.map +1 -1
  266. package/lib/typescript/components/Stack/HStack.d.ts +3 -2
  267. package/lib/typescript/components/Stack/HStack.d.ts.map +1 -1
  268. package/lib/typescript/components/Stack/VStack.d.ts +3 -2
  269. package/lib/typescript/components/Stack/VStack.d.ts.map +1 -1
  270. package/lib/typescript/components/Tabs/index.d.ts.map +1 -1
  271. package/lib/typescript/components/Tabs/styles.d.ts +0 -7
  272. package/lib/typescript/components/Tabs/styles.d.ts.map +1 -1
  273. package/lib/typescript/components/Toast/animation.d.ts +3 -3
  274. package/lib/typescript/components/Toast/animation.d.ts.map +1 -1
  275. package/lib/typescript/figma/ListItem.SectionHeader.figma.d.ts.map +1 -1
  276. package/lib/typescript/index.d.ts +6 -1
  277. package/lib/typescript/index.d.ts.map +1 -1
  278. package/package.json +11 -9
  279. package/src/components/Box/Box.tsx +18 -4
  280. package/src/components/Breadcrumbs/index.tsx +28 -4
  281. package/src/components/Breadcrumbs/styles.ts +30 -0
  282. package/src/components/DateTimeList/index.tsx +13 -26
  283. package/src/components/DateTimeList/styles.ts +1 -10
  284. package/src/components/ListItem/index.tsx +5 -4
  285. package/src/components/ListItem/styles.ts +1 -0
  286. package/src/components/Menu/index.tsx +11 -8
  287. package/src/components/ScrollShadow/gradient.ts +48 -0
  288. package/src/components/ScrollShadow/index.tsx +300 -69
  289. package/src/components/ScrollShadow/styles.ts +45 -28
  290. package/src/components/ScrollShadow/useComposedScrollHandler.ts +58 -0
  291. package/src/components/ScrollShadow/useScrollShadow.ts +72 -10
  292. package/src/components/Stack/HStack.tsx +8 -4
  293. package/src/components/Stack/VStack.tsx +8 -4
  294. package/src/components/Tabs/index.tsx +25 -35
  295. package/src/components/Tabs/styles.ts +0 -9
  296. package/src/index.ts +8 -1
@@ -0,0 +1,521 @@
1
+ # Data Grid (https://design.candescent.com/docs/components/data-grid)
2
+
3
+ Resources: [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/data-visualization-datagrid--default)
4
+
5
+ `DataGrid` is a **web-only** data-driven grid. Install `@cdx-ui/data-grid` in addition to `@cdx-ui/components`. For fully custom markup use `Table`. For a standalone pager use `TablePagination`.
6
+
7
+ ```tsx
8
+ import { Avatar, Chip, IconButton, Menu, ProgressBar, Text, VStack } from '@cdx-ui/components';
9
+ import { DataGrid } from '@cdx-ui/data-grid';
10
+ ```
11
+
12
+ ## Basic
13
+
14
+ Pass `rows` and `columns`. This account grid starts with the features most applications need: formatted values, status `Chip` cells, search, header filters, selection, sorting, and pagination.
15
+
16
+ Search is **not** always on. Set `showToolbar` to show the search field (same opt-in as MUI Community’s toolbar / quick filter). Set `headerFilters` to show per-column filter inputs in a second header row.
17
+
18
+ The grid is a fixed viewport like MUI Data Grid Community: **300px** tall by default. Column headers stay visible while rows scroll; pagination stays at the bottom. Override height with a `className` such as `h-full` or a spacing-scale height (`h-130`).
19
+
20
+ When `rows` is empty, a centered "No rows" message is shown and pagination is omitted. Pass `noRowsOverlay` to replace the default message.
21
+
22
+ ```tsx
23
+ import { Chip } from '@cdx-ui/components';
24
+ import { DataGrid, type GridColDef } from '@cdx-ui/data-grid';
25
+ import { accounts, type Account, type AccountStatus } from './_data';
26
+
27
+ const currencyFormatter = new Intl.NumberFormat('en-US', {
28
+ style: 'currency',
29
+ currency: 'USD',
30
+ });
31
+
32
+ const statusColors: Record<AccountStatus, 'success' | 'warning' | 'info' | 'neutral'> = {
33
+ Active: 'success',
34
+ Pending: 'warning',
35
+ Frozen: 'info',
36
+ Closed: 'neutral',
37
+ };
38
+
39
+ const columns: GridColDef<Account>[] = [
40
+ { field: 'id', headerName: 'Account', width: 120 },
41
+ { field: 'name', headerName: 'Name', flex: 1, minWidth: 160 },
42
+ { field: 'type', headerName: 'Type', width: 140 },
43
+ {
44
+ field: 'status',
45
+ headerName: 'Status',
46
+ width: 120,
47
+ renderCell: ({ row }) => (
48
+ <Chip color={statusColors[row.status]} size="small">
49
+ <Chip.Label>{row.status}</Chip.Label>
50
+ </Chip>
51
+ ),
52
+ },
53
+ {
54
+ field: 'balance',
55
+ headerName: 'Balance',
56
+ width: 140,
57
+ align: 'end',
58
+ valueFormatter: (_, row) => currencyFormatter.format(row.balance),
59
+ },
60
+ ];
61
+
62
+ export default function DataGridBasicDemo() {
63
+ return (
64
+ <DataGrid
65
+ rows={accounts}
66
+ columns={columns}
67
+ checkboxSelection
68
+ showToolbar
69
+ headerFilters
70
+ aria-label="Accounts"
71
+ defaultPaginationModel={{ page: 0, pageSize: 5 }}
72
+ pageSizeOptions={[5, 10, 25]}
73
+ className="h-105"
74
+ />
75
+ );
76
+ }
77
+ ```
78
+
79
+ ## Rich cells
80
+
81
+ Use `renderCell` to compose Forge UI components inside a cell. This operations view combines `Avatar`, `Chip`, `ProgressBar`, and an action `Menu`, while `valueFormatter` keeps sortable numeric data separate from its display value.
82
+
83
+ Rows are currently fixed at 48px, so use compact component variants and single-line content.
84
+
85
+ ```tsx
86
+ import { Avatar, Chip, HStack, IconButton, Menu, ProgressBar, Text } from '@cdx-ui/components';
87
+ import { DataGrid, type GridColDef } from '@cdx-ui/data-grid';
88
+ import { MoreHoriz } from '@cdx-ui/icons';
89
+ import { accounts, type Account, type AccountStatus } from './_data';
90
+
91
+ const currencyFormatter = new Intl.NumberFormat('en-US', {
92
+ style: 'currency',
93
+ currency: 'USD',
94
+ });
95
+
96
+ const statusColors: Record<AccountStatus, 'success' | 'warning' | 'info' | 'neutral'> = {
97
+ Active: 'success',
98
+ Pending: 'warning',
99
+ Frozen: 'info',
100
+ Closed: 'neutral',
101
+ };
102
+
103
+ const columns: GridColDef<Account>[] = [
104
+ { field: 'id', headerName: 'Account', width: 120 },
105
+ {
106
+ field: 'name',
107
+ headerName: 'Account name',
108
+ minWidth: 210,
109
+ flex: 1,
110
+ renderCell: ({ row }) => (
111
+ <HStack space="sm" className="items-center">
112
+ <Avatar size="sm">
113
+ <Avatar.Text>{row.name}</Avatar.Text>
114
+ </Avatar>
115
+ <Text numberOfLines={1} weight="medium">
116
+ {row.name}
117
+ </Text>
118
+ </HStack>
119
+ ),
120
+ },
121
+ {
122
+ field: 'status',
123
+ headerName: 'Status',
124
+ width: 120,
125
+ renderCell: ({ row }) => (
126
+ <Chip color={statusColors[row.status]} size="small">
127
+ <Chip.Label>{row.status}</Chip.Label>
128
+ </Chip>
129
+ ),
130
+ },
131
+ {
132
+ field: 'automation',
133
+ headerName: 'Automated',
134
+ width: 170,
135
+ renderCell: ({ row }) => (
136
+ <HStack space="sm" className="items-center">
137
+ <ProgressBar
138
+ value={row.automation}
139
+ max={100}
140
+ accessibilityLabel={`${row.name} is ${row.automation.toString()}% automated`}
141
+ className="w-full max-w-20"
142
+ >
143
+ <ProgressBar.Indicator />
144
+ </ProgressBar>
145
+ <Text color="secondary" size="sm">
146
+ {row.automation}%
147
+ </Text>
148
+ </HStack>
149
+ ),
150
+ },
151
+ {
152
+ field: 'balance',
153
+ headerName: 'Balance',
154
+ width: 140,
155
+ align: 'end',
156
+ valueFormatter: (_, row) => currencyFormatter.format(row.balance),
157
+ },
158
+ {
159
+ field: 'actions',
160
+ headerName: 'Actions',
161
+ width: 72,
162
+ align: 'center',
163
+ headerAlign: 'center',
164
+ sortable: false,
165
+ filterable: false,
166
+ renderCell: ({ row }) => (
167
+ <Menu placement="bottom-end">
168
+ <Menu.Trigger asChild>
169
+ <IconButton
170
+ as={MoreHoriz}
171
+ variant="ghost"
172
+ size="small"
173
+ accessibilityLabel={`Actions for ${row.name}`}
174
+ />
175
+ </Menu.Trigger>
176
+ <Menu.Popup>
177
+ <Menu.Content accessibilityLabel={`${row.name} actions`}>
178
+ <Menu.Item>
179
+ <Menu.ItemLabel>View account</Menu.ItemLabel>
180
+ </Menu.Item>
181
+ <Menu.Item>
182
+ <Menu.ItemLabel>Assign owner</Menu.ItemLabel>
183
+ </Menu.Item>
184
+ <Menu.Item color="danger">
185
+ <Menu.ItemLabel>Freeze account</Menu.ItemLabel>
186
+ </Menu.Item>
187
+ </Menu.Content>
188
+ </Menu.Popup>
189
+ </Menu>
190
+ ),
191
+ },
192
+ ];
193
+
194
+ export default function DataGridRichCellsDemo() {
195
+ return (
196
+ <DataGrid
197
+ rows={accounts.slice(0, 10)}
198
+ columns={columns}
199
+ hideFooter
200
+ aria-label="Account operations"
201
+ className="h-130"
202
+ />
203
+ );
204
+ }
205
+ ```
206
+
207
+ ## Toolbar actions
208
+
209
+ `toolbarActions` is an extension slot for your own toolbar controls beside search — export, density, view toggles, and so on. DataGrid does not ship toolbar buttons; you compose them and wire `onPress` to state that drives grid props.
210
+
211
+ A common pattern is a **Filters** button that toggles the `headerFilters` row on demand instead of leaving filter inputs always visible:
212
+
213
+ ```tsx
214
+ import { useState } from 'react';
215
+ import { Button, Chip } from '@cdx-ui/components';
216
+ import { DataGrid, type GridColDef, type GridFilterModel } from '@cdx-ui/data-grid';
217
+ import { FilterList } from '@cdx-ui/icons';
218
+ import { accounts, type Account } from './_data';
219
+
220
+ const currencyFormatter = new Intl.NumberFormat('en-US', {
221
+ style: 'currency',
222
+ currency: 'USD',
223
+ });
224
+
225
+ const columns: GridColDef<Account>[] = [
226
+ { field: 'id', headerName: 'Account', width: 120 },
227
+ { field: 'name', headerName: 'Name', flex: 1, minWidth: 160 },
228
+ { field: 'type', headerName: 'Type', width: 140 },
229
+ { field: 'status', headerName: 'Status', width: 120 },
230
+ {
231
+ field: 'balance',
232
+ headerName: 'Balance',
233
+ width: 140,
234
+ align: 'end',
235
+ valueFormatter: (_, row) => currencyFormatter.format(row.balance),
236
+ },
237
+ ];
238
+
239
+ export default function DataGridToolbarActionsDemo() {
240
+ const [headerFiltersOpen, setHeaderFiltersOpen] = useState(false);
241
+ const [filterModel, setFilterModel] = useState<GridFilterModel>([]);
242
+
243
+ const toggleHeaderFilters = () => {
244
+ setHeaderFiltersOpen((open) => {
245
+ if (open) {
246
+ setFilterModel([]);
247
+ }
248
+ return !open;
249
+ });
250
+ };
251
+
252
+ return (
253
+ <DataGrid
254
+ rows={accounts}
255
+ columns={columns}
256
+ showToolbar
257
+ headerFilters={headerFiltersOpen}
258
+ filterModel={filterModel}
259
+ onFilterModelChange={setFilterModel}
260
+ toolbarActions={
261
+ <>
262
+ <Chip color={filterModel.length > 0 ? 'action' : 'neutral'} size="small">
263
+ <Chip.Label>{filterModel.length} active</Chip.Label>
264
+ </Chip>
265
+ <Button variant="ghost" size="small" onPress={toggleHeaderFilters}>
266
+ <Button.Label>Filters</Button.Label>
267
+ <Button.Icon as={FilterList} position="trailing" />
268
+ </Button>
269
+ </>
270
+ }
271
+ aria-label="Accounts"
272
+ defaultPaginationModel={{ page: 0, pageSize: 5 }}
273
+ pageSizeOptions={[5, 10, 25]}
274
+ className="h-105"
275
+ />
276
+ );
277
+ }
278
+ ```
279
+
280
+ ## Selection
281
+
282
+ Set `checkboxSelection` for a leading checkbox column with select-all in the header. Control `rowSelectionModel` when bulk-action UI outside the rows needs the current selection.
283
+
284
+ ```tsx
285
+ import { useState } from 'react';
286
+ import { Button, Chip } from '@cdx-ui/components';
287
+ import { DataGrid, type GridColDef, type GridRowSelectionModel } from '@cdx-ui/data-grid';
288
+ import { accounts, type Account } from './_data';
289
+
290
+ const columns: GridColDef<Account>[] = [
291
+ { field: 'id', headerName: 'Account', width: 120 },
292
+ { field: 'name', headerName: 'Name', flex: 1, minWidth: 160 },
293
+ { field: 'owner', headerName: 'Owner', width: 170 },
294
+ { field: 'status', headerName: 'Status', width: 120 },
295
+ ];
296
+
297
+ export default function DataGridSelectionDemo() {
298
+ const [selectionModel, setSelectionModel] = useState<GridRowSelectionModel>({
299
+ type: 'include',
300
+ ids: new Set(['ACC-0002', 'ACC-0004']),
301
+ });
302
+ const selectedCount = selectionModel.ids.size;
303
+
304
+ return (
305
+ <DataGrid
306
+ rows={accounts.slice(0, 12)}
307
+ columns={columns}
308
+ checkboxSelection
309
+ rowSelectionModel={selectionModel}
310
+ onRowSelectionModelChange={setSelectionModel}
311
+ toolbarActions={
312
+ <>
313
+ <Chip color={selectedCount > 0 ? 'action' : 'neutral'} size="small">
314
+ <Chip.Label>{selectedCount} selected</Chip.Label>
315
+ </Chip>
316
+ <Button
317
+ variant="ghost"
318
+ size="small"
319
+ isDisabled={selectedCount === 0}
320
+ onPress={() => setSelectionModel({ type: 'include', ids: new Set() })}
321
+ >
322
+ <Button.Label>Clear selection</Button.Label>
323
+ </Button>
324
+ </>
325
+ }
326
+ aria-label="Accounts"
327
+ defaultPaginationModel={{ page: 0, pageSize: 5 }}
328
+ pageSizeOptions={[5, 10]}
329
+ className="h-105"
330
+ />
331
+ );
332
+ }
333
+ ```
334
+
335
+ ## Server data
336
+
337
+ Set `paginationMode="server"` and `sortingMode="server"` to let your data source own those operations. Keep the models controlled, pass the current page in `rows`, and provide the full `rowCount`.
338
+
339
+ Server-side filtering is not supported yet. Do not combine quick or header filters with server-paged rows; those filters only inspect the current `rows` array.
340
+
341
+ ```tsx
342
+ import { useState } from 'react';
343
+ import {
344
+ DataGrid,
345
+ type GridColDef,
346
+ type GridPaginationModel,
347
+ type GridSortModel,
348
+ } from '@cdx-ui/data-grid';
349
+ import { accounts, type Account } from './_data';
350
+
351
+ const currencyFormatter = new Intl.NumberFormat('en-US', {
352
+ style: 'currency',
353
+ currency: 'USD',
354
+ });
355
+
356
+ const columns: GridColDef<Account>[] = [
357
+ { field: 'id', headerName: 'Account', width: 120 },
358
+ { field: 'name', headerName: 'Name', flex: 1, minWidth: 160 },
359
+ { field: 'owner', headerName: 'Owner', width: 170 },
360
+ {
361
+ field: 'balance',
362
+ headerName: 'Balance',
363
+ width: 140,
364
+ align: 'end',
365
+ valueFormatter: (_, row) => currencyFormatter.format(row.balance),
366
+ },
367
+ ];
368
+
369
+ function queryAccounts(paginationModel: GridPaginationModel, sortModel: GridSortModel): Account[] {
370
+ const sortedRows = [...accounts];
371
+ const activeSort = sortModel.length > 0 ? sortModel[0] : undefined;
372
+
373
+ if (activeSort) {
374
+ sortedRows.sort((leftRow, rightRow) => {
375
+ const left = leftRow[activeSort.field as keyof Account];
376
+ const right = rightRow[activeSort.field as keyof Account];
377
+ const comparison =
378
+ typeof left === 'number' && typeof right === 'number'
379
+ ? left - right
380
+ : String(left).localeCompare(String(right));
381
+ return activeSort.sort === 'asc' ? comparison : -comparison;
382
+ });
383
+ }
384
+
385
+ const start = paginationModel.page * paginationModel.pageSize;
386
+ return sortedRows.slice(start, start + paginationModel.pageSize);
387
+ }
388
+
389
+ export default function DataGridServerDataDemo() {
390
+ const [paginationModel, setPaginationModel] = useState<GridPaginationModel>({
391
+ page: 0,
392
+ pageSize: 5,
393
+ });
394
+ const [sortModel, setSortModel] = useState<GridSortModel>([]);
395
+ const rows = queryAccounts(paginationModel, sortModel);
396
+
397
+ return (
398
+ <DataGrid
399
+ rows={rows}
400
+ columns={columns}
401
+ rowCount={accounts.length}
402
+ paginationMode="server"
403
+ sortingMode="server"
404
+ paginationModel={paginationModel}
405
+ onPaginationModelChange={setPaginationModel}
406
+ sortModel={sortModel}
407
+ onSortModelChange={setSortModel}
408
+ pageSizeOptions={[5, 10]}
409
+ aria-label="Server-managed accounts"
410
+ className="h-105"
411
+ />
412
+ );
413
+ }
414
+ ```
415
+
416
+ ## Loading
417
+
418
+ Set `loading` to mark the grid busy and show skeleton rows. Pagination is disabled and the empty state is suppressed while loading. Pass `loadingOverlay` to replace the default skeletons.
419
+
420
+ ```tsx
421
+ import { DataGrid, type GridColDef } from '@cdx-ui/data-grid';
422
+
423
+ // GridValidRowModel's index signature rejects otherwise equivalent interfaces.
424
+ // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
425
+ type Account = {
426
+ id: string;
427
+ name: string;
428
+ };
429
+
430
+ const columns: GridColDef<Account>[] = [
431
+ { field: 'id', headerName: 'Account' },
432
+ { field: 'name', headerName: 'Name' },
433
+ ];
434
+
435
+ export default function DataGridLoadingDemo() {
436
+ return (
437
+ <DataGrid
438
+ rows={[{ id: 'ACC-0001', name: 'Operating' }]}
439
+ columns={columns}
440
+ loading
441
+ hideFooter
442
+ aria-label="Accounts"
443
+ />
444
+ );
445
+ }
446
+ ```
447
+
448
+ ## Empty state
449
+
450
+ When no rows match, use `noRowsOverlay` to replace the default message with product-specific guidance. Pagination is omitted automatically.
451
+
452
+ ```tsx
453
+ import { Heading, Text, VStack } from '@cdx-ui/components';
454
+ import { DataGrid, type GridColDef } from '@cdx-ui/data-grid';
455
+ import type { Account } from './_data';
456
+
457
+ const rows: Account[] = [];
458
+
459
+ const columns: GridColDef<Account>[] = [
460
+ { field: 'id', headerName: 'Account', width: 120 },
461
+ { field: 'name', headerName: 'Name', flex: 1, minWidth: 160 },
462
+ { field: 'type', headerName: 'Type', width: 140 },
463
+ { field: 'status', headerName: 'Status', width: 120 },
464
+ ];
465
+
466
+ export default function DataGridEmptyDemo() {
467
+ return (
468
+ <DataGrid
469
+ rows={rows}
470
+ columns={columns}
471
+ noRowsOverlay={
472
+ <VStack space="xs" className="items-center">
473
+ <Heading size="sm">No matching accounts</Heading>
474
+ <Text color="secondary" size="sm">
475
+ Adjust the search or filters and try again.
476
+ </Text>
477
+ </VStack>
478
+ }
479
+ aria-label="Accounts"
480
+ className="h-75"
481
+ />
482
+ );
483
+ }
484
+ ```
485
+
486
+ ## API
487
+
488
+ ### DataGrid
489
+
490
+ Web-only. Inspired by MUI Data Grid Community props; not a wrap of `@mui/x-data-grid`.
491
+
492
+ | Attribute | Values | Description |
493
+ | ----------- | ----------- | ----------- |
494
+ | `data-slot` | `data-grid` | Shell |
495
+
496
+ ### GridColDef
497
+
498
+ Column definition. `valueGetter`, `valueFormatter`, and `renderCell` take no `apiRef`.
499
+ Use `start`, `center`, or `end` for `align` and `headerAlign`; the legacy `left` and `right`
500
+ values are deprecated aliases.
501
+
502
+ | Prop | Type | Default | Description |
503
+ | --- | --- | --- | --- |
504
+ | `field` | `string` | — | — |
505
+ | `headerName?` | `string` | — | — |
506
+ | `width?` | `number` | — | — |
507
+ | `minWidth?` | `number` | — | — |
508
+ | `flex?` | `number` | — | — |
509
+ | `align?` | `'start' \| 'center' \| 'end' \| 'left' \| 'right'` | `'start'` | Logical cell-content alignment. `left` and `right` are deprecated compatibility aliases for `start` and `end`. |
510
+ | `headerAlign?` | `'start' \| 'center' \| 'end' \| 'left' \| 'right'` | — | Logical header-content alignment. Defaults to `align`. `left` and `right` are deprecated compatibility aliases for `start` and `end`. |
511
+ | `sortable?` | `boolean` | — | — |
512
+ | `filterable?` | `boolean` | — | — |
513
+ | `type?` | `'string'` | — | — |
514
+ | `valueGetter?` | `((value: unknown, row: GridValidRowModel, col: GridColDef<GridValidRowModel>) => unknown)` | — | — |
515
+ | `valueFormatter?` | `((value: unknown, row: GridValidRowModel, col: GridColDef<GridValidRowModel>) => ReactNode \| string)` | — | — |
516
+ | `renderCell?` | `((params: GridRenderCellParams<GridValidRowModel>) => ReactNode)` | — | — |
517
+ | `renderHeader?` | `(() => ReactNode)` | — | — |
518
+
519
+ ## Accessibility
520
+
521
+ The grid renders a semantic HTML table on web. Sortable headers expose `aria-sort`. Select-all and row checkboxes are labelled.
@@ -0,0 +1,147 @@
1
+ # Date Field (https://design.candescent.com/docs/components/date-field)
2
+
3
+ Resources: [Figma](https://www.figma.com/design/0lEVMVlLj8ZS4fgItr3pmd/%E2%AD%90-Forge-DS--Components?node-id=11787-9802), [Storybook](https://victorious-wave-0daadf00f.6.azurestaticapps.net/?path=/story/date-time-datefield--default)
4
+
5
+ `DateField` is a segmented input for typing a date or a month. Values are `DateId` strings — `YYYY-MM-DD` in date mode and `YYYY-MM-01` in month mode.
6
+
7
+ ```tsx
8
+ import { DateField } from '@cdx-ui/components';
9
+ ```
10
+
11
+ ## Basic
12
+
13
+ Wrap `DateField.Input` in `DateField.Group` and control the value with `value` and `onValueChange`. Empty segments show localized placeholders until the user types.
14
+
15
+ ```tsx
16
+ import { useState } from 'react';
17
+ import { DateField } from '@cdx-ui/components';
18
+ import type { DateId, MonthId } from '@cdx-ui/formatters';
19
+
20
+ export default function DateFieldBasicDemo() {
21
+ const [value, setValue] = useState<DateId | MonthId | undefined>();
22
+
23
+ return (
24
+ <DateField
25
+ mode="date"
26
+ value={value}
27
+ onValueChange={setValue}
28
+ aria-label="Transfer date"
29
+ className="w-full max-w-xs"
30
+ >
31
+ <DateField.Group>
32
+ <DateField.Input />
33
+ </DateField.Group>
34
+ </DateField>
35
+ );
36
+ }
37
+ ```
38
+
39
+ ## Month mode
40
+
41
+ Set `mode` to `month` to enter only a month and year. The wire value fixes the day to the first (`YYYY-MM-01`).
42
+
43
+ ```tsx
44
+ import { useState } from 'react';
45
+ import { DateField } from '@cdx-ui/components';
46
+ import { monthId, type DateId, type MonthId } from '@cdx-ui/formatters';
47
+
48
+ export default function DateFieldMonthDemo() {
49
+ const [value, setValue] = useState<DateId | MonthId | undefined>(monthId('2026-07-01'));
50
+
51
+ return (
52
+ <DateField
53
+ mode="month"
54
+ value={value}
55
+ onValueChange={setValue}
56
+ aria-label="Statement month"
57
+ className="w-full max-w-xs"
58
+ >
59
+ <DateField.Group>
60
+ <DateField.Input />
61
+ </DateField.Group>
62
+ </DateField>
63
+ );
64
+ }
65
+ ```
66
+
67
+ ## API
68
+
69
+ ### DateField
70
+
71
+ Root of the compound. Owns the value, `mode`, and `locale`, and provides `variant`, `size`, and `fullWidth` styling context to `DateField.Group`.
72
+
73
+ | Prop | Type | Default | Description |
74
+ | --- | --- | --- | --- |
75
+ | `className?` | `string` | — | — |
76
+ | `children?` | `ReactNode` | — | — |
77
+ | `variant?` | `'outline' \| null` | — | — |
78
+ | `size?` | `'default' \| 'small' \| null` | — | — |
79
+ | `fullWidth?` | `boolean` | — | When true (the default), the group stretches to fill its container; when false, it hugs the segments. |
80
+ | `labels?` | `Partial<DateComponentLabels>` | — | Overrides the accessible labels announced for each segment. |
81
+ | `asChild?` | `boolean` | — | — |
82
+ | `value?` | `DateId \| MonthId` | — | Controlled value: a `DateId` (`YYYY-MM-DD`) in date mode, or a `MonthId` (`YYYY-MM-01`) in month mode. Build one with `dateId(...)` / `monthId(...)` from `@cdx-ui/formatters` — a bare string will not type-check. |
83
+ | `defaultValue?` | `DateId \| MonthId` | — | Uncontrolled initial value, in the same format as `value`. |
84
+ | `onValueChange?` | `((value: DateId \| MonthId) => void)` | — | Called with the new value once every segment is filled, or `undefined` when the field is cleared. |
85
+ | `mode?` | `'date' \| 'month'` | — | Which segments to render: `date` shows month, day, and year; `month` shows month and year only. |
86
+ | `locale?` | `string` | — | BCP-47 locale that controls segment order and separators. Defaults to `en-US`. |
87
+ | `isDisabled?` | `boolean` | — | — |
88
+ | `isReadOnly?` | `boolean` | — | — |
89
+ | `isInvalid?` | `boolean` | — | — |
90
+ | `isRequired?` | `boolean` | — | — |
91
+
92
+ Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
93
+
94
+ ## Sub-components
95
+
96
+ ### DateField.Group
97
+
98
+ Input chrome that surrounds the segments, sharing `Input`'s outline styling. Add a trailing `DateField.Suffix` inside it for a picker trigger.
99
+
100
+ | Prop | Type | Default | Description |
101
+ | --- | --- | --- | --- |
102
+ | `className?` | `string` | — | — |
103
+ | `children?` | `ReactNode` | — | — |
104
+ | `variant?` | `'outline' \| null` | — | — |
105
+ | `size?` | `'default' \| 'small' \| null` | — | — |
106
+ | `fullWidth?` | `boolean` | — | — |
107
+
108
+ Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
109
+
110
+ ### DateField.Input
111
+
112
+ Renders the editable segments. It renders styled segments by default; pass a render function as `children` to customize an individual segment.
113
+
114
+ | Prop | Type | Default | Description |
115
+ | --- | --- | --- | --- |
116
+ | `className?` | `string` | — | — |
117
+ | `children?` | `((segment: DateFieldSegmentPrimitiveProps["segment"]) => ReactNode)` | — | — |
118
+ | `slot?` | `'start' \| 'end'` | — | — |
119
+
120
+ Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
121
+
122
+ ### DateField.Segment
123
+
124
+ A single editable or literal segment, yielded to the `DateField.Input` render function so a specific segment type can be styled.
125
+
126
+ | Prop | Type | Default | Description |
127
+ | --- | --- | --- | --- |
128
+ | `className?` | `string` | — | — |
129
+ | `asChild?` | `boolean` | — | — |
130
+ | `segmentIndex?` | `number` | — | — |
131
+ | `segment` | `DateSegment` | — | — |
132
+
133
+ ### DateField.Suffix
134
+
135
+ Trailing content inside `DateField.Group`, typically a picker trigger icon. Set `asChild` to render a custom trigger element in its place.
136
+
137
+ | Prop | Type | Default | Description |
138
+ | --- | --- | --- | --- |
139
+ | `className?` | `string` | — | — |
140
+ | `children?` | `ReactNode` | — | — |
141
+ | `asChild?` | `boolean` | — | — |
142
+
143
+ Inherits all [`ViewProps`](https://reactnative.dev/docs/view#props).
144
+
145
+ ## Accessibility
146
+
147
+ Give the field an accessible name with `aria-label` or by pairing it with `Field.Label`; the root carries no label of its own. Each segment is individually focusable and editable with the keyboard, and `labels` overrides the name announced for each one. While `isDisabled` or `isReadOnly`, segments do not accept edits.