@usefragments/ui 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (457) hide show
  1. package/README.md +4 -4
  2. package/dist/assets/fragments-wordmark.cjs +2 -2
  3. package/dist/assets/fragments-wordmark.d.ts.map +1 -1
  4. package/dist/assets/fragments-wordmark.js +2 -2
  5. package/dist/assets/ui.css +4720 -4159
  6. package/dist/chart.cjs +24 -6
  7. package/dist/chart.js +24 -6
  8. package/dist/codeblock.cjs +55 -29
  9. package/dist/codeblock.js +55 -29
  10. package/dist/colorpicker.cjs +3 -1
  11. package/dist/colorpicker.js +3 -1
  12. package/dist/components/Accordion/Accordion.module.scss.cjs +8 -8
  13. package/dist/components/Accordion/Accordion.module.scss.js +8 -8
  14. package/dist/components/Alert/Alert.module.scss.cjs +15 -12
  15. package/dist/components/Alert/Alert.module.scss.js +15 -12
  16. package/dist/components/Alert/index.cjs +7 -1
  17. package/dist/components/Alert/index.d.ts +12 -6
  18. package/dist/components/Alert/index.d.ts.map +1 -1
  19. package/dist/components/Alert/index.js +7 -1
  20. package/dist/components/AppShell/AppShell.module.scss.cjs +14 -14
  21. package/dist/components/AppShell/AppShell.module.scss.js +14 -14
  22. package/dist/components/Avatar/Avatar.module.scss.cjs +14 -14
  23. package/dist/components/Avatar/Avatar.module.scss.js +14 -14
  24. package/dist/components/Badge/Badge.module.scss.cjs +19 -19
  25. package/dist/components/Badge/Badge.module.scss.js +19 -19
  26. package/dist/components/BentoGrid/BentoGrid.module.scss.cjs +14 -14
  27. package/dist/components/BentoGrid/BentoGrid.module.scss.js +14 -14
  28. package/dist/components/Box/Box.module.scss.cjs +152 -152
  29. package/dist/components/Box/Box.module.scss.js +152 -152
  30. package/dist/components/Box/index.cjs +64 -75
  31. package/dist/components/Box/index.d.ts +16 -16
  32. package/dist/components/Box/index.d.ts.map +1 -1
  33. package/dist/components/Box/index.js +64 -75
  34. package/dist/components/Breadcrumbs/Breadcrumbs.module.scss.cjs +8 -8
  35. package/dist/components/Breadcrumbs/Breadcrumbs.module.scss.js +8 -8
  36. package/dist/components/Button/Button.module.scss.cjs +14 -14
  37. package/dist/components/Button/Button.module.scss.js +14 -14
  38. package/dist/components/Card/Card.module.scss.cjs +29 -17
  39. package/dist/components/Card/Card.module.scss.js +30 -18
  40. package/dist/components/Card/index.cjs +8 -0
  41. package/dist/components/Card/index.d.ts +12 -2
  42. package/dist/components/Card/index.d.ts.map +1 -1
  43. package/dist/components/Card/index.js +8 -0
  44. package/dist/components/Chart/Chart.module.scss.cjs +15 -15
  45. package/dist/components/Chart/Chart.module.scss.js +15 -15
  46. package/dist/components/Chart/index.d.ts.map +1 -1
  47. package/dist/components/Checkbox/Checkbox.module.scss.cjs +9 -9
  48. package/dist/components/Checkbox/Checkbox.module.scss.js +9 -9
  49. package/dist/components/Checkbox/index.cjs +2 -2
  50. package/dist/components/Checkbox/index.d.ts.map +1 -1
  51. package/dist/components/Checkbox/index.js +2 -2
  52. package/dist/components/Chip/Chip.module.scss.cjs +15 -15
  53. package/dist/components/Chip/Chip.module.scss.js +15 -15
  54. package/dist/components/Chip/index.cjs +2 -1
  55. package/dist/components/Chip/index.d.ts.map +1 -1
  56. package/dist/components/Chip/index.js +2 -1
  57. package/dist/components/CodeBlock/CodeBlock.module.scss.cjs +26 -23
  58. package/dist/components/CodeBlock/CodeBlock.module.scss.js +26 -23
  59. package/dist/components/CodeBlock/css-variables-theme.cjs +98 -0
  60. package/dist/components/CodeBlock/css-variables-theme.d.ts +27 -0
  61. package/dist/components/CodeBlock/css-variables-theme.d.ts.map +1 -0
  62. package/dist/components/CodeBlock/css-variables-theme.js +98 -0
  63. package/dist/components/CodeBlock/index.d.ts +17 -3
  64. package/dist/components/CodeBlock/index.d.ts.map +1 -1
  65. package/dist/components/Collapsible/Collapsible.module.scss.cjs +9 -9
  66. package/dist/components/Collapsible/Collapsible.module.scss.js +9 -9
  67. package/dist/components/ColorPicker/ColorPicker.module.scss.cjs +14 -14
  68. package/dist/components/ColorPicker/ColorPicker.module.scss.js +14 -14
  69. package/dist/components/ColorPicker/index.d.ts.map +1 -1
  70. package/dist/components/Combobox/Combobox.module.scss.cjs +21 -21
  71. package/dist/components/Combobox/Combobox.module.scss.js +21 -21
  72. package/dist/components/Combobox/index.cjs +17 -1
  73. package/dist/components/Combobox/index.d.ts.map +1 -1
  74. package/dist/components/Combobox/index.js +17 -1
  75. package/dist/components/Command/Command.module.scss.cjs +11 -11
  76. package/dist/components/Command/Command.module.scss.js +11 -11
  77. package/dist/components/Command/index.cjs +26 -15
  78. package/dist/components/Command/index.d.ts +2 -2
  79. package/dist/components/Command/index.d.ts.map +1 -1
  80. package/dist/components/Command/index.js +26 -15
  81. package/dist/components/ConversationList/ConversationList.module.scss.cjs +10 -10
  82. package/dist/components/ConversationList/ConversationList.module.scss.js +10 -10
  83. package/dist/components/DataTable/DataTable.icons.cjs +6 -33
  84. package/dist/components/DataTable/DataTable.icons.d.ts.map +1 -1
  85. package/dist/components/DataTable/DataTable.icons.js +6 -33
  86. package/dist/components/DataTable/DataTable.module.scss.cjs +27 -27
  87. package/dist/components/DataTable/DataTable.module.scss.js +27 -27
  88. package/dist/components/DataTable/index.d.ts.map +1 -1
  89. package/dist/components/DatePicker/DatePicker.module.scss.cjs +33 -33
  90. package/dist/components/DatePicker/DatePicker.module.scss.js +33 -33
  91. package/dist/components/DatePicker/index.d.ts.map +1 -1
  92. package/dist/components/Dialog/Dialog.module.scss.cjs +14 -14
  93. package/dist/components/Dialog/Dialog.module.scss.js +14 -14
  94. package/dist/components/Dialog/index.cjs +11 -14
  95. package/dist/components/Dialog/index.d.ts +7 -7
  96. package/dist/components/Dialog/index.d.ts.map +1 -1
  97. package/dist/components/Dialog/index.js +11 -14
  98. package/dist/components/Drawer/Drawer.module.scss.cjs +29 -29
  99. package/dist/components/Drawer/Drawer.module.scss.js +29 -29
  100. package/dist/components/Editor/Editor.module.scss.cjs +17 -17
  101. package/dist/components/Editor/Editor.module.scss.js +17 -17
  102. package/dist/components/Editor/index.d.ts +10 -10
  103. package/dist/components/Editor/index.d.ts.map +1 -1
  104. package/dist/components/EmptyState/EmptyState.module.scss.cjs +11 -8
  105. package/dist/components/EmptyState/EmptyState.module.scss.js +11 -8
  106. package/dist/components/EmptyState/index.cjs +8 -6
  107. package/dist/components/EmptyState/index.d.ts +9 -4
  108. package/dist/components/EmptyState/index.d.ts.map +1 -1
  109. package/dist/components/EmptyState/index.js +8 -6
  110. package/dist/components/Field/Field.module.scss.cjs +5 -5
  111. package/dist/components/Field/Field.module.scss.js +5 -5
  112. package/dist/components/Field/index.cjs +9 -1
  113. package/dist/components/Field/index.d.ts.map +1 -1
  114. package/dist/components/Field/index.js +9 -1
  115. package/dist/components/Fieldset/Fieldset.module.scss.cjs +3 -3
  116. package/dist/components/Fieldset/Fieldset.module.scss.js +3 -3
  117. package/dist/components/Grid/index.cjs +1 -1
  118. package/dist/components/Grid/index.js +1 -1
  119. package/dist/components/Header/Header.module.scss.cjs +33 -33
  120. package/dist/components/Header/Header.module.scss.js +33 -33
  121. package/dist/components/Header/index.cjs +17 -38
  122. package/dist/components/Header/index.d.ts +15 -11
  123. package/dist/components/Header/index.d.ts.map +1 -1
  124. package/dist/components/Header/index.js +17 -38
  125. package/dist/components/Icon/Icon.module.scss.cjs +15 -15
  126. package/dist/components/Icon/Icon.module.scss.js +15 -15
  127. package/dist/components/IconButton/IconButton.module.scss.cjs +8 -8
  128. package/dist/components/IconButton/IconButton.module.scss.js +8 -8
  129. package/dist/components/IconButton/index.cjs +2 -1
  130. package/dist/components/IconButton/index.d.ts.map +1 -1
  131. package/dist/components/IconButton/index.js +2 -1
  132. package/dist/components/Image/Image.module.scss.cjs +27 -27
  133. package/dist/components/Image/Image.module.scss.js +27 -27
  134. package/dist/components/Input/Input.module.scss.cjs +17 -17
  135. package/dist/components/Input/Input.module.scss.js +17 -17
  136. package/dist/components/Link/Link.module.scss.cjs +14 -10
  137. package/dist/components/Link/Link.module.scss.js +14 -10
  138. package/dist/components/Link/index.d.ts +1 -1
  139. package/dist/components/Link/index.d.ts.map +1 -1
  140. package/dist/components/List/List.module.scss.cjs +19 -19
  141. package/dist/components/List/List.module.scss.js +19 -19
  142. package/dist/components/Listbox/Listbox.module.scss.cjs +8 -8
  143. package/dist/components/Listbox/Listbox.module.scss.js +8 -8
  144. package/dist/components/Loading/Loading.module.scss.cjs +34 -34
  145. package/dist/components/Loading/Loading.module.scss.js +34 -34
  146. package/dist/components/Loading/index.cjs +1 -1
  147. package/dist/components/Loading/index.js +1 -1
  148. package/dist/components/Markdown/Markdown.module.scss.cjs +1 -1
  149. package/dist/components/Markdown/Markdown.module.scss.js +1 -1
  150. package/dist/components/Markdown/index.d.ts +2 -2
  151. package/dist/components/Markdown/index.d.ts.map +1 -1
  152. package/dist/components/Menu/Menu.module.scss.cjs +14 -14
  153. package/dist/components/Menu/Menu.module.scss.js +14 -14
  154. package/dist/components/Message/Message.module.scss.cjs +18 -18
  155. package/dist/components/Message/Message.module.scss.js +18 -18
  156. package/dist/components/NavigationMenu/NavigationMenu.module.scss.cjs +34 -31
  157. package/dist/components/NavigationMenu/NavigationMenu.module.scss.js +34 -31
  158. package/dist/components/NavigationMenu/index.cjs +32 -15
  159. package/dist/components/NavigationMenu/index.d.ts +12 -6
  160. package/dist/components/NavigationMenu/index.d.ts.map +1 -1
  161. package/dist/components/NavigationMenu/index.js +32 -15
  162. package/dist/components/Pagination/Pagination.module.scss.cjs +10 -10
  163. package/dist/components/Pagination/Pagination.module.scss.js +10 -10
  164. package/dist/components/Popover/Popover.module.scss.cjs +10 -10
  165. package/dist/components/Popover/Popover.module.scss.js +10 -10
  166. package/dist/components/Progress/Progress.module.scss.cjs +25 -25
  167. package/dist/components/Progress/Progress.module.scss.js +25 -25
  168. package/dist/components/Prompt/Prompt.module.scss.cjs +28 -28
  169. package/dist/components/Prompt/Prompt.module.scss.js +28 -28
  170. package/dist/components/RadioGroup/RadioGroup.module.scss.cjs +15 -15
  171. package/dist/components/RadioGroup/RadioGroup.module.scss.js +15 -15
  172. package/dist/components/ScrollArea/ScrollArea.module.scss.cjs +5 -5
  173. package/dist/components/ScrollArea/ScrollArea.module.scss.js +5 -5
  174. package/dist/components/ScrollArea/index.d.ts +4 -4
  175. package/dist/components/ScrollArea/index.d.ts.map +1 -1
  176. package/dist/components/ScrollArea/scroll-state.d.ts +5 -5
  177. package/dist/components/Select/Select.module.scss.cjs +21 -21
  178. package/dist/components/Select/Select.module.scss.js +21 -21
  179. package/dist/components/Separator/Separator.module.scss.cjs +11 -11
  180. package/dist/components/Separator/Separator.module.scss.js +11 -11
  181. package/dist/components/Sidebar/Sidebar.module.scss.cjs +43 -43
  182. package/dist/components/Sidebar/Sidebar.module.scss.js +43 -43
  183. package/dist/components/Sidebar/index.cjs +12 -35
  184. package/dist/components/Sidebar/index.d.ts +19 -19
  185. package/dist/components/Sidebar/index.d.ts.map +1 -1
  186. package/dist/components/Sidebar/index.js +12 -35
  187. package/dist/components/Skeleton/Skeleton.module.scss.cjs +50 -46
  188. package/dist/components/Skeleton/Skeleton.module.scss.js +50 -46
  189. package/dist/components/Slider/Slider.module.scss.cjs +12 -12
  190. package/dist/components/Slider/Slider.module.scss.js +12 -12
  191. package/dist/components/Stack/Stack.module.scss.cjs +25 -25
  192. package/dist/components/Stack/Stack.module.scss.js +25 -25
  193. package/dist/components/Stack/index.cjs +1 -1
  194. package/dist/components/Stack/index.js +1 -1
  195. package/dist/components/Switch/Switch.module.scss.cjs +9 -9
  196. package/dist/components/Switch/Switch.module.scss.js +9 -9
  197. package/dist/components/Table/Table.module.scss.cjs +19 -19
  198. package/dist/components/Table/Table.module.scss.js +19 -19
  199. package/dist/components/TableOfContents/TableOfContents.module.scss.cjs +15 -15
  200. package/dist/components/TableOfContents/TableOfContents.module.scss.js +15 -15
  201. package/dist/components/TableOfContents/index.cjs +13 -9
  202. package/dist/components/TableOfContents/index.d.ts +5 -3
  203. package/dist/components/TableOfContents/index.d.ts.map +1 -1
  204. package/dist/components/TableOfContents/index.js +13 -9
  205. package/dist/components/Tabs/Tabs.module.scss.cjs +12 -12
  206. package/dist/components/Tabs/Tabs.module.scss.js +12 -12
  207. package/dist/components/Tabs/index.cjs +26 -6
  208. package/dist/components/Tabs/index.d.ts.map +1 -1
  209. package/dist/components/Tabs/index.js +26 -6
  210. package/dist/components/Text/Text.module.scss.cjs +87 -75
  211. package/dist/components/Text/Text.module.scss.js +87 -75
  212. package/dist/components/Text/index.cjs +49 -41
  213. package/dist/components/Text/index.d.ts +12 -11
  214. package/dist/components/Text/index.d.ts.map +1 -1
  215. package/dist/components/Text/index.js +49 -41
  216. package/dist/components/Textarea/Textarea.module.scss.cjs +24 -24
  217. package/dist/components/Textarea/Textarea.module.scss.js +24 -24
  218. package/dist/components/Theme/index.cjs +2 -1
  219. package/dist/components/Theme/index.d.ts.map +1 -1
  220. package/dist/components/Theme/index.js +2 -1
  221. package/dist/components/ThemeToggle/ThemeToggle.module.scss.cjs +9 -6
  222. package/dist/components/ThemeToggle/ThemeToggle.module.scss.js +9 -6
  223. package/dist/components/ThemeToggle/index.cjs +31 -6
  224. package/dist/components/ThemeToggle/index.d.ts +7 -2
  225. package/dist/components/ThemeToggle/index.d.ts.map +1 -1
  226. package/dist/components/ThemeToggle/index.js +32 -7
  227. package/dist/components/ThinkingIndicator/ThinkingIndicator.module.scss.cjs +13 -13
  228. package/dist/components/ThinkingIndicator/ThinkingIndicator.module.scss.js +13 -13
  229. package/dist/components/Toast/Toast.module.scss.cjs +20 -20
  230. package/dist/components/Toast/Toast.module.scss.js +20 -20
  231. package/dist/components/ToggleGroup/ToggleGroup.module.scss.cjs +17 -17
  232. package/dist/components/ToggleGroup/ToggleGroup.module.scss.js +17 -17
  233. package/dist/components/Tooltip/Tooltip.module.scss.cjs +3 -3
  234. package/dist/components/Tooltip/Tooltip.module.scss.js +3 -3
  235. package/dist/components/Tooltip/index.cjs +24 -40
  236. package/dist/components/Tooltip/index.d.ts +4 -4
  237. package/dist/components/Tooltip/index.d.ts.map +1 -1
  238. package/dist/components/Tooltip/index.js +24 -40
  239. package/dist/components/VisuallyHidden/index.d.ts +2 -2
  240. package/dist/data-table.cjs +2 -1
  241. package/dist/data-table.js +2 -1
  242. package/dist/datepicker.cjs +3 -2
  243. package/dist/datepicker.js +3 -2
  244. package/dist/editor.cjs +68 -28
  245. package/dist/editor.js +68 -28
  246. package/dist/index.cjs +1 -1
  247. package/dist/index.d.ts +1 -1
  248. package/dist/index.d.ts.map +1 -1
  249. package/dist/index.js +2 -2
  250. package/dist/markdown.cjs +21 -29
  251. package/dist/markdown.js +21 -29
  252. package/dist/measurements/generated.cjs +9 -1
  253. package/dist/measurements/generated.d.ts +7 -0
  254. package/dist/measurements/generated.d.ts.map +1 -1
  255. package/dist/measurements/generated.js +9 -1
  256. package/dist/utils/a11y.cjs +5 -2
  257. package/dist/utils/a11y.d.ts +5 -5
  258. package/dist/utils/a11y.d.ts.map +1 -1
  259. package/dist/utils/a11y.js +5 -2
  260. package/dist/utils/canonical-stamp.cjs +2 -8
  261. package/dist/utils/canonical-stamp.d.ts.map +1 -1
  262. package/dist/utils/canonical-stamp.js +1 -7
  263. package/dist/utils/css-warning.cjs +1 -1
  264. package/dist/utils/css-warning.js +1 -1
  265. package/dist/utils/env.cjs +17 -0
  266. package/dist/utils/env.d.ts +3 -0
  267. package/dist/utils/env.d.ts.map +1 -0
  268. package/dist/utils/env.js +17 -0
  269. package/dist/utils/keyboard-shortcuts.cjs +3 -10
  270. package/dist/utils/keyboard-shortcuts.d.ts +4 -4
  271. package/dist/utils/keyboard-shortcuts.d.ts.map +1 -1
  272. package/dist/utils/keyboard-shortcuts.js +3 -10
  273. package/dist/utils/seed-derivation.cjs +10 -6
  274. package/dist/utils/seed-derivation.d.ts.map +1 -1
  275. package/dist/utils/seed-derivation.js +10 -6
  276. package/fragments.json +1 -1
  277. package/package.json +6 -4
  278. package/src/assets/fragments-logo.tsx +2 -2
  279. package/src/assets/fragments-wordmark.tsx +4 -2
  280. package/src/components/Accordion/Accordion.contract.json +24 -48
  281. package/src/components/Alert/Alert.contract.json +37 -53
  282. package/src/components/Alert/Alert.module.scss +24 -0
  283. package/src/components/Alert/index.tsx +55 -29
  284. package/src/components/AppShell/AppShell.contract.json +34 -51
  285. package/src/components/AppShell/AppShell.module.scss +53 -40
  286. package/src/components/Avatar/Avatar.contract.json +31 -48
  287. package/src/components/Avatar/Avatar.module.scss +4 -1
  288. package/src/components/Badge/Badge.contract.json +37 -42
  289. package/src/components/Badge/Badge.module.scss +9 -2
  290. package/src/components/BentoGrid/BentoGrid.contract.json +21 -45
  291. package/src/components/Box/Box.contract.json +40 -148
  292. package/src/components/Box/index.tsx +92 -99
  293. package/src/components/Breadcrumbs/Breadcrumbs.contract.json +21 -34
  294. package/src/components/Breadcrumbs/Breadcrumbs.module.scss +12 -7
  295. package/src/components/Button/Button.module.scss +8 -7
  296. package/src/components/ButtonGroup/ButtonGroup.contract.json +32 -47
  297. package/src/components/Card/Card.module.scss +82 -1
  298. package/src/components/Card/index.tsx +21 -2
  299. package/src/components/Chart/Chart.contract.json +21 -29
  300. package/src/components/Chart/index.tsx +36 -6
  301. package/src/components/Checkbox/Checkbox.contract.json +24 -24
  302. package/src/components/Checkbox/Checkbox.module.scss +32 -23
  303. package/src/components/Checkbox/index.tsx +4 -2
  304. package/src/components/Chip/Chip.contract.json +33 -40
  305. package/src/components/Chip/Chip.module.scss +2 -2
  306. package/src/components/Chip/index.tsx +2 -1
  307. package/src/components/CodeBlock/CodeBlock.contract.json +46 -76
  308. package/src/components/CodeBlock/CodeBlock.module.scss +40 -15
  309. package/src/components/CodeBlock/css-variables-theme.ts +102 -0
  310. package/src/components/CodeBlock/index.tsx +91 -35
  311. package/src/components/Collapsible/Collapsible.contract.json +21 -36
  312. package/src/components/ColorPicker/ColorPicker.contract.json +29 -48
  313. package/src/components/ColorPicker/ColorPicker.module.scss +15 -12
  314. package/src/components/ColorPicker/index.tsx +5 -1
  315. package/src/components/Combobox/Combobox.contract.json +36 -37
  316. package/src/components/Combobox/Combobox.module.scss +1 -1
  317. package/src/components/Combobox/index.tsx +31 -5
  318. package/src/components/Command/Command.contract.json +21 -43
  319. package/src/components/Command/index.tsx +58 -47
  320. package/src/components/ConversationList/ConversationList.contract.json +27 -32
  321. package/src/components/DataTable/DataTable.icons.tsx +4 -21
  322. package/src/components/DataTable/DataTable.module.scss +12 -8
  323. package/src/components/DataTable/index.tsx +8 -7
  324. package/src/components/DatePicker/DatePicker.contract.json +27 -28
  325. package/src/components/DatePicker/DatePicker.module.scss +12 -5
  326. package/src/components/DatePicker/index.tsx +5 -2
  327. package/src/components/Dialog/Dialog.module.scss +3 -3
  328. package/src/components/Dialog/index.tsx +47 -37
  329. package/src/components/Drawer/Drawer.contract.json +22 -36
  330. package/src/components/Editor/Editor.contract.json +31 -48
  331. package/src/components/Editor/Editor.module.scss +36 -14
  332. package/src/components/Editor/index.tsx +240 -179
  333. package/src/components/EmptyState/EmptyState.contract.json +31 -43
  334. package/src/components/EmptyState/EmptyState.module.scss +8 -0
  335. package/src/components/EmptyState/index.tsx +48 -23
  336. package/src/components/Field/Field.contract.json +28 -46
  337. package/src/components/Field/index.tsx +5 -1
  338. package/src/components/Fieldset/Fieldset.contract.json +21 -38
  339. package/src/components/Fieldset/Fieldset.module.scss +10 -3
  340. package/src/components/Form/Form.contract.json +20 -20
  341. package/src/components/Grid/Grid.contract.json +28 -64
  342. package/src/components/Grid/index.tsx +10 -10
  343. package/src/components/Header/Header.contract.json +31 -67
  344. package/src/components/Header/Header.module.scss +36 -21
  345. package/src/components/Header/index.tsx +134 -122
  346. package/src/components/Icon/Icon.contract.json +22 -62
  347. package/src/components/IconButton/IconButton.contract.json +34 -18
  348. package/src/components/IconButton/IconButton.module.scss +6 -7
  349. package/src/components/IconButton/index.tsx +2 -1
  350. package/src/components/Image/Image.contract.json +23 -56
  351. package/src/components/Input/Input.contract.json +26 -32
  352. package/src/components/Input/Input.module.scss +3 -2
  353. package/src/components/Link/Link.contract.json +32 -52
  354. package/src/components/Link/Link.module.scss +23 -6
  355. package/src/components/Link/index.tsx +1 -1
  356. package/src/components/List/List.contract.json +23 -52
  357. package/src/components/List/List.module.scss +1 -1
  358. package/src/components/Listbox/Listbox.contract.json +21 -37
  359. package/src/components/Loading/Loading.contract.json +37 -61
  360. package/src/components/Loading/Loading.module.scss +10 -7
  361. package/src/components/Loading/index.tsx +2 -2
  362. package/src/components/Main/Main.contract.json +17 -9
  363. package/src/components/Markdown/Markdown.contract.json +22 -43
  364. package/src/components/Markdown/Markdown.module.scss +43 -5
  365. package/src/components/Markdown/index.tsx +48 -49
  366. package/src/components/Menu/Menu.contract.json +25 -41
  367. package/src/components/Menu/Menu.module.scss +23 -8
  368. package/src/components/Message/Message.contract.json +29 -52
  369. package/src/components/Message/Message.module.scss +12 -5
  370. package/src/components/NavigationMenu/NavigationMenu.contract.json +36 -45
  371. package/src/components/NavigationMenu/NavigationMenu.module.scss +64 -19
  372. package/src/components/NavigationMenu/index.tsx +105 -81
  373. package/src/components/Pagination/Pagination.contract.json +22 -40
  374. package/src/components/Pagination/Pagination.module.scss +2 -2
  375. package/src/components/Popover/Popover.contract.json +24 -46
  376. package/src/components/Popover/Popover.module.scss +6 -5
  377. package/src/components/Progress/Progress.contract.json +32 -28
  378. package/src/components/Progress/Progress.module.scss +3 -2
  379. package/src/components/Prompt/Prompt.contract.json +31 -47
  380. package/src/components/Prompt/Prompt.module.scss +13 -5
  381. package/src/components/RadioGroup/RadioGroup.contract.json +23 -24
  382. package/src/components/RadioGroup/RadioGroup.module.scss +13 -14
  383. package/src/components/ScrollArea/ScrollArea.contract.json +18 -19
  384. package/src/components/ScrollArea/ScrollArea.module.scss +15 -15
  385. package/src/components/ScrollArea/index.tsx +16 -16
  386. package/src/components/ScrollArea/scroll-state.ts +24 -24
  387. package/src/components/Select/Select.module.scss +2 -2
  388. package/src/components/Separator/Separator.contract.json +24 -48
  389. package/src/components/Sidebar/Sidebar.contract.json +35 -67
  390. package/src/components/Sidebar/Sidebar.module.scss +22 -13
  391. package/src/components/Sidebar/index.tsx +164 -164
  392. package/src/components/Skeleton/Skeleton.contract.json +28 -54
  393. package/src/components/Skeleton/Skeleton.module.scss +27 -10
  394. package/src/components/Slider/Slider.contract.json +27 -39
  395. package/src/components/Slider/Slider.module.scss +3 -3
  396. package/src/components/Stack/Stack.contract.json +29 -56
  397. package/src/components/Stack/Stack.module.scss +13 -12
  398. package/src/components/Stack/index.tsx +3 -3
  399. package/src/components/Switch/Switch.contract.json +33 -46
  400. package/src/components/Switch/Switch.module.scss +64 -26
  401. package/src/components/Table/Table.contract.json +28 -46
  402. package/src/components/Table/Table.module.scss +15 -3
  403. package/src/components/TableOfContents/TableOfContents.contract.json +34 -21
  404. package/src/components/TableOfContents/TableOfContents.module.scss +15 -5
  405. package/src/components/TableOfContents/index.tsx +26 -9
  406. package/src/components/Tabs/Tabs.contract.json +24 -45
  407. package/src/components/Tabs/Tabs.module.scss +1 -1
  408. package/src/components/Tabs/index.tsx +15 -3
  409. package/src/components/Text/Text.contract.json +30 -72
  410. package/src/components/Text/Text.module.scss +21 -4
  411. package/src/components/Text/index.tsx +113 -75
  412. package/src/components/Textarea/Textarea.contract.json +25 -43
  413. package/src/components/Textarea/Textarea.module.scss +2 -4
  414. package/src/components/Theme/Theme.contract.json +32 -51
  415. package/src/components/Theme/index.tsx +2 -1
  416. package/src/components/ThemeToggle/ThemeToggle.module.scss +23 -7
  417. package/src/components/ThemeToggle/index.tsx +43 -7
  418. package/src/components/ThinkingIndicator/ThinkingIndicator.contract.json +23 -40
  419. package/src/components/Toast/Toast.contract.json +30 -40
  420. package/src/components/Toast/Toast.module.scss +1 -1
  421. package/src/components/ToggleGroup/ToggleGroup.contract.json +29 -30
  422. package/src/components/ToggleGroup/ToggleGroup.module.scss +38 -5
  423. package/src/components/Tooltip/Tooltip.contract.json +31 -52
  424. package/src/components/Tooltip/index.tsx +19 -24
  425. package/src/components/VisuallyHidden/VisuallyHidden.contract.json +22 -44
  426. package/src/components/VisuallyHidden/index.tsx +5 -5
  427. package/src/index.ts +2 -2
  428. package/src/measurements/generated.ts +9 -2
  429. package/src/measurements/measurements.json +7 -0
  430. package/src/recipes/_boolean-range.scss +3 -11
  431. package/src/recipes/_field.scss +5 -1
  432. package/src/recipes/_layout.scss +14 -7
  433. package/src/recipes/_popup.scss +12 -2
  434. package/src/recipes/_prose.scss +13 -5
  435. package/src/recipes/_table-chrome.scss +16 -2
  436. package/src/scss.d.ts +1 -1
  437. package/src/styles/globals.scss +20 -19
  438. package/src/tokens/_computed.scss +5 -16
  439. package/src/tokens/_derive.scss +112 -210
  440. package/src/tokens/_measurements.catalog.generated.css +6 -1
  441. package/src/tokens/_measurements.generated.scss +14 -1
  442. package/src/tokens/_mixins.scss +7 -8
  443. package/src/tokens/_palettes.scss +39 -167
  444. package/src/tokens/_seeds.scss +20 -20
  445. package/src/tokens/_variables.scss +183 -38
  446. package/src/utils/a11y.tsx +69 -69
  447. package/src/utils/aria.ts +3 -3
  448. package/src/utils/canonical-stamp.ts +2 -12
  449. package/src/utils/css-warning.ts +7 -7
  450. package/src/utils/env.ts +25 -0
  451. package/src/utils/keyboard-shortcuts.ts +131 -126
  452. package/src/utils/seed-derivation.ts +10 -6
  453. package/src/components/Button/Button.contract.json +0 -218
  454. package/src/components/Card/Card.contract.json +0 -175
  455. package/src/components/DataTable/DataTable.contract.json +0 -302
  456. package/src/components/Dialog/Dialog.contract.json +0 -159
  457. package/src/components/Select/Select.contract.json +0 -259
@@ -1,14 +1,9 @@
1
1
  {
2
2
  "$schema": "https://usefragments.com/schemas/contract.v1.json",
3
3
  "name": "Breadcrumbs",
4
- "description": "Breadcrumb navigation showing the current page location within a hierarchy. Helps users navigate back through parent pages.",
4
+ "description": "Shows where the user is and links back up the hierarchy.",
5
5
  "category": "navigation",
6
- "tags": [
7
- "breadcrumbs",
8
- "navigation",
9
- "hierarchy",
10
- "wayfinding"
11
- ],
6
+ "tags": ["breadcrumbs", "navigation", "hierarchy", "wayfinding"],
12
7
  "status": "stable",
13
8
  "sourcePath": "src/components/Breadcrumbs/index.tsx",
14
9
  "exportName": "Breadcrumbs",
@@ -44,21 +39,22 @@
44
39
  },
45
40
  "usage": {
46
41
  "when": [
47
- "Showing hierarchical page location (e.g., Home > Category > Product)",
48
- "Allowing quick navigation to parent pages",
49
- "Multi-level content structures like documentation or e-commerce"
42
+ "Nested content more than two levels deep",
43
+ "Jumping back to a parent in one click",
44
+ "Documentation and catalogue hierarchies"
50
45
  ],
51
46
  "whenNot": [
52
- "Flat navigation with no hierarchy (use Tabs or Header nav)",
53
- "Step-by-step wizards (use Stepper)",
47
+ "Flat structures with no parents (use Tabs or header navigation)",
48
+ "Steps in an order (use Stepper)",
54
49
  "Primary navigation (use Sidebar or Header)"
55
50
  ],
56
51
  "guidelines": [
57
- "Always include the current page as the last, non-linked item",
58
- "Keep labels short and descriptive",
59
- "Use maxItems to collapse long paths, keeping first and last visible",
60
- "The separator defaults to \"/\" but can be customized",
61
- "Use the label prop to customize the nav landmark name (defaults to \"Breadcrumb\")"
52
+ "End on the current page, unlinked",
53
+ "Short labels the trail is a path, not a summary",
54
+ "Set maxItems to fold long paths, keeping first and last",
55
+ "The separator defaults to a slash and takes any node",
56
+ "Set label to rename the landmark (defaults to \"Breadcrumb\")",
57
+ "Crumbs truncate at 200px so one long title cannot push the rest out"
62
58
  ],
63
59
  "accessibility": [
64
60
  "Uses <nav aria-label=\"Breadcrumb\"> for landmark navigation",
@@ -70,27 +66,27 @@
70
66
  "examples": [
71
67
  {
72
68
  "name": "Default",
73
- "description": "Basic breadcrumb navigation",
69
+ "description": "Each ancestor links; the last one does not.",
74
70
  "code": "<Breadcrumbs>\n <Breadcrumbs.Item href=\"#\">Home</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Products</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Category</Breadcrumbs.Item>\n <Breadcrumbs.Item current>Current Page</Breadcrumbs.Item>\n</Breadcrumbs>"
75
71
  },
76
72
  {
77
73
  "name": "With Icons",
78
- "description": "Breadcrumbs with icons on items",
74
+ "description": "Glyphs mark what kind of thing each level is.",
79
75
  "code": "<Breadcrumbs>\n <Breadcrumbs.Item\n href=\"#\"\n icon={\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path d=\"M8 1.25l-7 6v7.5c0 .138.112.25.25.25H5.5V10h5v5h4.25a.25.25 0 0 0 .25-.25v-7.5l-7-6z\" />\n </svg>\n }\n >\n Home\n </Breadcrumbs.Item>\n <Breadcrumbs.Item\n href=\"#\"\n icon={\n <svg viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path d=\"M1.75 1A1.75 1.75 0 0 0 0 2.75v10.5C0 14.216.784 15 1.75 15h12.5A1.75 1.75 0 0 0 16 13.25v-8.5A1.75 1.75 0 0 0 14.25 3H7.5a.25.25 0 0 1-.2-.1l-.9-1.2C6.07 1.26 5.55 1 5 1H1.75z\" />\n </svg>\n }\n >\n Documents\n </Breadcrumbs.Item>\n <Breadcrumbs.Item current>Report.pdf</Breadcrumbs.Item>\n</Breadcrumbs>"
80
76
  },
81
77
  {
82
78
  "name": "Collapsed",
83
- "description": "Long breadcrumb trail collapsed with ellipsis",
79
+ "description": "Middle levels fold behind an ellipsis.",
84
80
  "code": "<Breadcrumbs maxItems={3}>\n <Breadcrumbs.Item href=\"#\">Home</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Category</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Subcategory</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Section</Breadcrumbs.Item>\n <Breadcrumbs.Item current>Current Page</Breadcrumbs.Item>\n</Breadcrumbs>"
85
81
  },
86
82
  {
87
83
  "name": "Custom Separator",
88
- "description": "Breadcrumbs with a custom chevron separator",
84
+ "description": "Any node can replace the slash.",
89
85
  "code": "<Breadcrumbs\n separator={\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path fillRule=\"evenodd\" d=\"M6.22 3.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L9.94 8 6.22 4.28a.75.75 0 0 1 0-1.06z\" />\n </svg>\n }\n>\n <Breadcrumbs.Item href=\"#\">Home</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Settings</Breadcrumbs.Item>\n <Breadcrumbs.Item current>Profile</Breadcrumbs.Item>\n</Breadcrumbs>"
90
86
  },
91
87
  {
92
88
  "name": "Custom Landmark Label",
93
- "description": "Override the nav landmark label for screen readers",
89
+ "description": "Renames the landmark screen readers announce.",
94
90
  "code": "<Breadcrumbs label=\"Documentation breadcrumbs\">\n <Breadcrumbs.Item href=\"#\">Docs</Breadcrumbs.Item>\n <Breadcrumbs.Item href=\"#\">Components</Breadcrumbs.Item>\n <Breadcrumbs.Item current>Breadcrumbs</Breadcrumbs.Item>\n</Breadcrumbs>"
95
91
  }
96
92
  ],
@@ -115,21 +111,12 @@
115
111
  "Breadcrumbs.Item current: boolean - marks current page",
116
112
  "Breadcrumbs.Item icon: ReactNode - icon before label"
117
113
  ],
118
- "a11yRules": [
119
- "A11Y_NAV_LANDMARK",
120
- "A11Y_ARIA_CURRENT",
121
- "A11Y_TARGET_SIZE_MIN"
122
- ]
114
+ "a11yRules": ["A11Y_NAV_LANDMARK", "A11Y_ARIA_CURRENT", "A11Y_TARGET_SIZE_MIN"]
123
115
  },
124
116
  "ai": {
125
117
  "compositionPattern": "compound",
126
- "subComponents": [
127
- "Item",
128
- "Separator"
129
- ],
130
- "requiredChildren": [
131
- "Item"
132
- ],
118
+ "subComponents": ["Item", "Separator"],
119
+ "requiredChildren": ["Item"],
133
120
  "commonPatterns": [
134
121
  "<Breadcrumbs><Breadcrumbs.Item href=\"/\">Home</Breadcrumbs.Item><Breadcrumbs.Item href=\"/products\">Products</Breadcrumbs.Item><Breadcrumbs.Item current>Widget</Breadcrumbs.Item></Breadcrumbs>"
135
122
  ]
@@ -1,8 +1,8 @@
1
- @use '../../tokens/variables' as *;
2
- @use '../../tokens/mixins' as *;
3
- @use '../../recipes/action' as action;
4
- @use '../../recipes/target' as target;
5
- @use '../../recipes/typography' as typography;
1
+ @use "../../tokens/variables" as *;
2
+ @use "../../tokens/mixins" as *;
3
+ @use "../../recipes/action" as action;
4
+ @use "../../recipes/target" as target;
5
+ @use "../../recipes/typography" as typography;
6
6
 
7
7
  // Root nav wrapper
8
8
  .root {
@@ -40,9 +40,12 @@
40
40
  white-space: nowrap;
41
41
  overflow: hidden;
42
42
  text-overflow: ellipsis;
43
+ // Intentional truncation width: one long crumb must not push the rest of the
44
+ // trail off screen. Keep in sync with .current below.
43
45
  max-width: 200px;
44
46
  border-radius: var(--fui-radius-sm, $fui-radius-sm);
45
- transition: color var(--fui-transition-fast, $fui-transition-fast),
47
+ transition:
48
+ color var(--fui-transition-fast, $fui-transition-fast),
46
49
  background-color var(--fui-transition-fast, $fui-transition-fast);
47
50
 
48
51
  &:hover {
@@ -65,6 +68,7 @@
65
68
  white-space: nowrap;
66
69
  overflow: hidden;
67
70
  text-overflow: ellipsis;
71
+ // Intentional truncation width — matches .link above.
68
72
  max-width: 200px;
69
73
  }
70
74
 
@@ -92,7 +96,8 @@
92
96
  border-radius: var(--fui-radius-sm, $fui-radius-sm);
93
97
  color: var(--fui-text-secondary, $fui-text-secondary);
94
98
  cursor: pointer;
95
- transition: color var(--fui-transition-fast, $fui-transition-fast),
99
+ transition:
100
+ color var(--fui-transition-fast, $fui-transition-fast),
96
101
  background-color var(--fui-transition-fast, $fui-transition-fast);
97
102
 
98
103
  &:hover {
@@ -24,7 +24,6 @@
24
24
  color: var(--_button-color);
25
25
  font-weight: var(--fui-font-weight-medium, $fui-font-weight-medium);
26
26
  white-space: nowrap;
27
- user-select: none;
28
27
 
29
28
  // A composed link — `Button asChild` cloning an <a>, or an anchor rendered
30
29
  // as a child — must wear the button's own foreground, never the global
@@ -146,8 +145,10 @@
146
145
  --_button-bg: var(--fui-button-neutral-bg);
147
146
  --_button-bg-hover: var(--fui-button-neutral-bg-hover);
148
147
  --_button-bg-active: var(--fui-button-neutral-bg-active);
149
- --_button-border: var(--fui-button-neutral-border);
150
- --_button-border-hover: var(--fui-button-neutral-border-hover);
148
+ // Secondary hierarchy comes from its fill. The transparent border preserves
149
+ // control geometry while leaving visible neutral borders to `.outlined`.
150
+ --_button-border: transparent;
151
+ --_button-border-hover: transparent;
151
152
  --_button-color: var(--fui-button-neutral-color, var(--fui-text-primary, #{$fui-text-primary}));
152
153
  --_button-shadow: var(--fui-button-neutral-shadow);
153
154
  --_button-shadow-hover: var(--fui-button-neutral-shadow);
@@ -297,17 +298,17 @@
297
298
 
298
299
  @media (prefers-contrast: more) {
299
300
  .secondary {
300
- border-width: 2px;
301
+ border-width: var(--fui-stroke-default, 2px);
301
302
  border-color: var(--fui-text-primary, $fui-text-primary);
302
303
  }
303
304
 
304
305
  .outlined {
305
- border-width: 2px;
306
+ border-width: var(--fui-stroke-default, 2px);
306
307
  border-color: var(--fui-text-primary, $fui-text-primary);
307
308
  }
308
309
 
309
310
  .ghost {
310
- border-width: 2px;
311
+ border-width: var(--fui-stroke-default, 2px);
311
312
 
312
313
  &:hover:not(:disabled) {
313
314
  border-color: var(--fui-text-primary, $fui-text-primary);
@@ -315,7 +316,7 @@
315
316
  }
316
317
 
317
318
  .link {
318
- border-width: 2px;
319
+ border-width: var(--fui-stroke-default, 2px);
319
320
 
320
321
  &:hover:not(:disabled) {
321
322
  border-color: var(--fui-color-accent, $fui-color-accent);
@@ -1,15 +1,9 @@
1
1
  {
2
2
  "$schema": "https://usefragments.com/schemas/contract.v1.json",
3
3
  "name": "ButtonGroup",
4
- "description": "Groups related buttons together with consistent spacing and alignment. Useful for action bars, toolbars, and related button sets.",
5
- "category": "forms",
6
- "tags": [
7
- "button",
8
- "group",
9
- "toolbar",
10
- "actions",
11
- "layout"
12
- ],
4
+ "description": "Lays out related buttons in a row with one shared gap and alignment.",
5
+ "category": "actions",
6
+ "tags": ["button", "group", "toolbar", "actions", "layout"],
13
7
  "status": "stable",
14
8
  "sourcePath": "src/components/ButtonGroup/index.tsx",
15
9
  "exportName": "ButtonGroup",
@@ -30,12 +24,7 @@
30
24
  "description": "Spacing between buttons",
31
25
  "default": "sm",
32
26
  "required": false,
33
- "values": [
34
- "none",
35
- "xs",
36
- "sm",
37
- "md"
38
- ]
27
+ "values": ["none", "xs", "sm", "md"]
39
28
  },
40
29
  "wrap": {
41
30
  "type": "boolean",
@@ -47,57 +36,57 @@
47
36
  "type": "enum",
48
37
  "description": "Alignment of buttons",
49
38
  "required": false,
50
- "values": [
51
- "start",
52
- "center",
53
- "end"
54
- ]
39
+ "values": ["start", "center", "end"]
55
40
  }
56
41
  },
57
42
  "usage": {
58
43
  "when": [
59
- "Grouping related actions together",
60
- "Creating toolbars or action bars",
61
- "Form submit/cancel button pairs",
44
+ "Confirm/cancel pairs at the end of a form",
45
+ "Toolbars and action bars",
62
46
  "Pagination controls"
63
47
  ],
64
48
  "whenNot": [
65
- "Unrelated buttons (use Stack instead)",
66
- "Navigation links (use nav element)",
67
- "Single button (no grouping needed)"
49
+ "Unrelated buttons use Stack",
50
+ "Navigation links use a nav element",
51
+ "A single button"
68
52
  ],
69
53
  "guidelines": [
70
- "Keep button groups focused on related actions",
71
- "Use consistent button variants within a group",
72
- "Consider visual hierarchy - primary action should stand out",
73
- "Limit to 2-4 buttons per group for clarity",
74
- "Pass role/aria-label/id/data-* directly to ButtonGroup when you need semantic grouping hooks"
54
+ "Two to four buttons; more belongs in a Menu",
55
+ "Confirming action goes last",
56
+ "One primary button per group",
57
+ "align=\"end\" for form footers",
58
+ "Pass role, aria-label, id and data-* straight through to ButtonGroup"
75
59
  ],
76
60
  "accessibility": [
77
- "Group provides semantic relationship between buttons",
78
- "Each button remains individually focusable",
79
- "Consider using role=\"group\" with aria-label for screen readers"
61
+ "Each button stays individually focusable",
62
+ "Add role=\"group\" plus aria-label when the set needs a name",
63
+ "Order buttons the way they read, not the way they look"
80
64
  ]
81
65
  },
82
66
  "examples": [
83
67
  {
84
68
  "name": "Default",
85
- "description": "Basic button group with default spacing",
69
+ "description": "Confirming action sits last in the row.",
86
70
  "code": "<ButtonGroup>\n <Button variant=\"secondary\">Cancel</Button>\n <Button variant=\"primary\">Save</Button>\n</ButtonGroup>"
87
71
  },
88
72
  {
89
- "name": "Gap Variants",
90
- "description": "Different spacing options",
91
- "code": "<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>\n <ButtonGroup gap=\"none\">\n <Button variant=\"secondary\" size=\"sm\">None</Button>\n <Button variant=\"secondary\" size=\"sm\">Gap</Button>\n </ButtonGroup>\n <ButtonGroup gap=\"xs\">\n <Button variant=\"secondary\" size=\"sm\">XS</Button>\n <Button variant=\"secondary\" size=\"sm\">Gap</Button>\n </ButtonGroup>\n <ButtonGroup gap=\"sm\">\n <Button variant=\"secondary\" size=\"sm\">SM</Button>\n <Button variant=\"secondary\" size=\"sm\">Gap</Button>\n </ButtonGroup>\n <ButtonGroup gap=\"md\">\n <Button variant=\"secondary\" size=\"sm\">MD</Button>\n <Button variant=\"secondary\" size=\"sm\">Gap</Button>\n </ButtonGroup>\n</div>"
73
+ "name": "Spacing",
74
+ "description": "Four gap steps, from touching to airy.",
75
+ "code": "import { Stack } from '@/components/Stack';\n\n<Stack direction=\"column\" gap=\"md\">\n <ButtonGroup gap=\"none\">\n <Button variant=\"secondary\" size=\"sm\">None</Button>\n <Button variant=\"secondary\" size=\"sm\">Gap</Button>\n </ButtonGroup>\n <ButtonGroup gap=\"xs\">\n <Button variant=\"secondary\" size=\"sm\">XS</Button>\n <Button variant=\"secondary\" size=\"sm\">Gap</Button>\n </ButtonGroup>\n <ButtonGroup gap=\"sm\">\n <Button variant=\"secondary\" size=\"sm\">SM</Button>\n <Button variant=\"secondary\" size=\"sm\">Gap</Button>\n </ButtonGroup>\n <ButtonGroup gap=\"md\">\n <Button variant=\"secondary\" size=\"sm\">MD</Button>\n <Button variant=\"secondary\" size=\"sm\">Gap</Button>\n </ButtonGroup>\n</Stack>"
92
76
  },
93
77
  {
94
78
  "name": "Alignment",
95
- "description": "Different alignment options",
96
- "code": "<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', width: '300px' }}>\n <ButtonGroup align=\"start\">\n <Button variant=\"secondary\" size=\"sm\">Start</Button>\n <Button variant=\"secondary\" size=\"sm\">Aligned</Button>\n </ButtonGroup>\n <ButtonGroup align=\"center\">\n <Button variant=\"secondary\" size=\"sm\">Center</Button>\n <Button variant=\"secondary\" size=\"sm\">Aligned</Button>\n </ButtonGroup>\n <ButtonGroup align=\"end\">\n <Button variant=\"secondary\" size=\"sm\">End</Button>\n <Button variant=\"secondary\" size=\"sm\">Aligned</Button>\n </ButtonGroup>\n</div>"
79
+ "description": "Pins the row to the left, centre, or right of its container.",
80
+ "code": "import { Stack } from '@/components/Stack';\n\n<Stack direction=\"column\" gap=\"md\">\n <ButtonGroup align=\"start\">\n <Button variant=\"secondary\" size=\"sm\">Start</Button>\n <Button variant=\"secondary\" size=\"sm\">Aligned</Button>\n </ButtonGroup>\n <ButtonGroup align=\"center\">\n <Button variant=\"secondary\" size=\"sm\">Center</Button>\n <Button variant=\"secondary\" size=\"sm\">Aligned</Button>\n </ButtonGroup>\n <ButtonGroup align=\"end\">\n <Button variant=\"secondary\" size=\"sm\">End</Button>\n <Button variant=\"secondary\" size=\"sm\">Aligned</Button>\n </ButtonGroup>\n</Stack>"
81
+ },
82
+ {
83
+ "name": "Wrapping",
84
+ "description": "Buttons drop to a second line instead of overflowing.",
85
+ "code": "<ButtonGroup wrap>\n <Button variant=\"secondary\" size=\"sm\">Approve</Button>\n <Button variant=\"secondary\" size=\"sm\">Request changes</Button>\n <Button variant=\"secondary\" size=\"sm\">Reassign reviewer</Button>\n <Button variant=\"secondary\" size=\"sm\">Move to backlog</Button>\n <Button variant=\"secondary\" size=\"sm\">Archive</Button>\n</ButtonGroup>"
97
86
  },
98
87
  {
99
88
  "name": "Form Actions",
100
- "description": "Common pattern for form submit/cancel",
89
+ "description": "Right-aligned pair, named for screen readers.",
101
90
  "code": "<ButtonGroup align=\"end\" role=\"group\" aria-label=\"Form actions\">\n <Button variant=\"ghost\">Cancel</Button>\n <Button variant=\"primary\">Submit</Button>\n</ButtonGroup>"
102
91
  }
103
92
  ],
@@ -121,15 +110,11 @@
121
110
  "align: start|center|end - alignment",
122
111
  "Pass-through DOM props supported on root (id, role, aria-*, data-*, handlers)"
123
112
  ],
124
- "a11yRules": [
125
- "A11Y_GROUP_LABEL"
126
- ]
113
+ "a11yRules": ["A11Y_GROUP_LABEL"]
127
114
  },
128
115
  "ai": {
129
116
  "compositionPattern": "compound",
130
- "subComponents": [
131
- "Root"
132
- ]
117
+ "subComponents": ["Root"]
133
118
  },
134
119
  "provenance": {
135
120
  "source": "migrated",
@@ -1,8 +1,29 @@
1
1
  @use "../../tokens/variables" as *;
2
2
  @use "../../tokens/mixins" as *;
3
+ @use "../../recipes/action" as action;
3
4
  @use "../../recipes/surface" as surface;
4
5
  @use "../../recipes/typography" as typography;
5
6
 
7
+ // The private inset channels are element-scoped signals between a card's own
8
+ // classes, but custom properties inherit by default — a Card nested inside
9
+ // another Card (docs previews, dashboard panels) would receive the outer
10
+ // card's forced/requested inset and lose its padding. Register them as
11
+ // non-inheriting so each card resolves only its own channels.
12
+ @property --_card-root-forced-inset {
13
+ syntax: "*";
14
+ inherits: false;
15
+ }
16
+
17
+ @property --_card-root-requested-inset {
18
+ syntax: "*";
19
+ inherits: false;
20
+ }
21
+
22
+ @property --_card-body-inset {
23
+ syntax: "*";
24
+ inherits: false;
25
+ }
26
+
6
27
  @layer fui.components {
7
28
  .card {
8
29
  @include surface-elevated;
@@ -88,6 +109,65 @@
88
109
  overflow: hidden;
89
110
  }
90
111
 
112
+ // Accent capsule — the earned-moment surface (demo banner, upgrade panel,
113
+ // onboarding resume capsule). Accent-tinted hairline, radial accent wash
114
+ // from the top-right corner. Radius matches the default card.
115
+ .accent {
116
+ position: relative;
117
+ overflow: hidden;
118
+ background-color: var(--fui-card-accent-bg, #{$fui-card-accent-bg});
119
+ border-color: var(--fui-card-accent-border, #{$fui-card-accent-border});
120
+ border-radius: var(--fui-card-accent-radius, #{$fui-card-accent-radius});
121
+ box-shadow: none;
122
+
123
+ &::before {
124
+ content: "";
125
+ position: absolute;
126
+ inset: 0;
127
+ pointer-events: none;
128
+ background: radial-gradient(
129
+ 90% 70% at 100% -10%,
130
+ color-mix(in srgb, var(--fui-color-accent, #{$fui-color-accent}) 13%, transparent),
131
+ transparent 62%
132
+ );
133
+ }
134
+ }
135
+
136
+ // Accent tones — same capsule, state-coloured hairline + wash. Chroma is
137
+ // earned by state (SPEC §4.4): danger = a merge is held, warning =
138
+ // enforcement lapsed, neutral = waiting (no wash at all).
139
+ .toneDanger {
140
+ border-color: var(--fui-color-danger-border, #{$fui-color-danger-border});
141
+
142
+ &::before {
143
+ background: radial-gradient(
144
+ 90% 70% at 100% -10%,
145
+ var(--fui-color-danger-bg, #{$fui-color-danger-bg}),
146
+ transparent 62%
147
+ );
148
+ }
149
+ }
150
+
151
+ .toneWarning {
152
+ border-color: var(--fui-color-warning-border, #{$fui-color-warning-border});
153
+
154
+ &::before {
155
+ background: radial-gradient(
156
+ 90% 70% at 100% -10%,
157
+ var(--fui-color-warning-bg, #{$fui-color-warning-bg}),
158
+ transparent 62%
159
+ );
160
+ }
161
+ }
162
+
163
+ .toneNeutral {
164
+ border-color: var(--fui-border, #{$fui-border});
165
+
166
+ &::before {
167
+ content: none;
168
+ }
169
+ }
170
+
91
171
  // Padding
92
172
  .paddingNone {
93
173
  --_card-root-requested-inset: #{surface.inset("panel")};
@@ -152,9 +232,10 @@
152
232
  align-items: center;
153
233
  justify-content: space-between;
154
234
  gap: var(--fui-raw-space-12, 12px);
155
- min-height: var(--fui-control-track-md, 32px);
235
+ min-height: #{action.track("md")};
156
236
  padding: #{surface.inset("compact")};
157
237
  margin-bottom: 0;
238
+ background-color: var(--fui-card-header-bg, var(--fui-bg-subtle, #{$fui-bg-subtle}));
158
239
  border-bottom: var(--fui-stroke-hairline, 1px) solid var(--fui-border, $fui-border);
159
240
 
160
241
  // Multi-line copy: top-align trailing controls with the title line.
@@ -21,9 +21,19 @@ export interface CardProps extends Omit<React.HTMLAttributes<HTMLElement>, "chil
21
21
  * - `panel`: hairline-bordered panel with zero own padding, designed for
22
22
  * compound use with `Card.Header divided` + `Card.Body` so each region
23
23
  * manages its own spacing.
24
+ * - `accent`: the earned-moment capsule — accent-tinted hairline, radial
25
+ * accent wash, soft fixed radius. Reserve for the few surfaces that earn
26
+ * emphasis (demo banner, upgrade panel, onboarding resume), never for
27
+ * routine content.
24
28
  * @default "default"
25
29
  * @see https://usefragments.com/components/card#variants */
26
- variant?: "default" | "outlined" | "outline" | "elevated" | "stat" | "panel";
30
+ variant?: "default" | "outlined" | "outline" | "elevated" | "stat" | "panel" | "accent";
31
+ /** Semantic tone of the `accent` capsule. The wash and hairline follow the
32
+ * tone so the same earned-moment idiom can carry state: `danger` (a merge is
33
+ * held), `warning` (enforcement lapsed), `neutral` (waiting — ink hairline,
34
+ * no wash). Ignored for other variants.
35
+ * @default "accent" */
36
+ tone?: "accent" | "danger" | "warning" | "neutral";
27
37
  /** Inner padding.
28
38
  * @default "md" */
29
39
  padding?: "none" | "sm" | "md" | "lg";
@@ -67,7 +77,7 @@ export interface CardFooterProps extends React.HTMLAttributes<HTMLDivElement> {
67
77
  // ============================================
68
78
 
69
79
  interface CardContextValue {
70
- variant: "default" | "outlined" | "elevated" | "stat" | "panel";
80
+ variant: "default" | "outlined" | "elevated" | "stat" | "panel" | "accent";
71
81
  padding: "none" | "sm" | "md" | "lg";
72
82
  isInteractive: boolean;
73
83
  }
@@ -100,9 +110,17 @@ function composeEventHandlers<E extends { defaultPrevented: boolean }>(
100
110
  // Components
101
111
  // ============================================
102
112
 
113
+ const toneMap = {
114
+ accent: undefined,
115
+ danger: styles.toneDanger,
116
+ warning: styles.toneWarning,
117
+ neutral: styles.toneNeutral,
118
+ } as const;
119
+
103
120
  function CardRoot({
104
121
  children,
105
122
  variant: variantProp = "default",
123
+ tone = "accent",
106
124
  padding = "md",
107
125
  as: Component = "article",
108
126
  className,
@@ -120,6 +138,7 @@ function CardRoot({
120
138
  const classes = [
121
139
  styles.card,
122
140
  styles[variant],
141
+ variant === "accent" && tone !== "accent" && toneMap[tone],
123
142
  paddingMap[padding],
124
143
  isInteractive && styles.interactive,
125
144
  className,
@@ -1,14 +1,9 @@
1
1
  {
2
2
  "$schema": "https://usefragments.com/schemas/contract.v1.json",
3
3
  "name": "Chart",
4
- "description": "Composable chart wrapper for recharts with theme-aware tooltips, legends, and color integration.",
4
+ "description": "Plots your data with tooltips, legends, and colors that track the theme.",
5
5
  "category": "display",
6
- "tags": [
7
- "chart",
8
- "graph",
9
- "data-visualization",
10
- "recharts"
11
- ],
6
+ "tags": ["chart", "graph", "data-visualization", "recharts"],
12
7
  "status": "stable",
13
8
  "dependencies": [
14
9
  {
@@ -55,48 +50,47 @@
55
50
  },
56
51
  "usage": {
57
52
  "when": [
58
- "Displaying data trends over time",
59
- "Comparing categorical data",
60
- "Showing distribution or composition",
61
- "Dashboard data visualizations"
53
+ "A trend over time is the point",
54
+ "Categories need comparing side by side",
55
+ "A whole splits into parts worth seeing"
62
56
  ],
63
57
  "whenNot": [
64
- "Simple numeric values (use Text or Badge)",
65
- "Progress toward a goal (use Progress)",
66
- "Tabular data without visualization (use Table)"
58
+ "One number tells the story (use Text or Badge)",
59
+ "Distance to a goal (use Progress)",
60
+ "Readers need exact values (use Table)"
67
61
  ],
68
62
  "guidelines": [
69
- "Use ChartContainer to wrap recharts chart components",
70
- "Define a ChartConfig to map data keys to labels and colors (and optionally icons for custom legend/tooltip UIs)",
71
- "Use FUI CSS variables for colors so charts adapt to theme changes",
72
- "Use ChartTooltip and ChartLegend for consistent themed overlays",
73
- "ChartTooltip and ChartLegend accept custom content renderers for advanced formatting"
63
+ "Wrap every recharts chart in ChartContainer",
64
+ "Map each data key to a label and color in ChartConfig",
65
+ "Colors come from --fui-* variables so both themes stay readable",
66
+ "Pair with ChartTooltip and ChartLegend rather than recharts' own",
67
+ "Give the container a real height recharts cannot measure zero"
74
68
  ],
75
69
  "accessibility": [
76
- "Charts include recharts accessibilityLayer by default",
77
- "Provide meaningful labels in ChartConfig for screen readers",
78
- "Consider providing a data table alternative for complex charts"
70
+ "accessibilityLayer is on by default",
71
+ "ChartConfig labels are what screen readers read",
72
+ "Pass dataTable to offer the same numbers as text"
79
73
  ]
80
74
  },
81
75
  "examples": [
82
76
  {
83
77
  "name": "Line Chart",
84
- "description": "Multi-series line chart showing trends over time",
78
+ "description": "Two series share one scale, so the gap between them reads instantly.",
85
79
  "code": "<div style={{ width: '100%', height: 300 }}>\n <ChartContainer\n config={{\n revenue: { label: 'Revenue', color: 'var(--fui-color-accent)' },\n users: { label: 'Users', color: 'var(--fui-color-info)' },\n }}\n >\n <LineChart data={monthlyData} margin={{ top: 5, right: 20, bottom: 5, left: 0 }}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"month\" />\n <YAxis />\n <ChartTooltip />\n <ChartLegend />\n <Line type=\"monotone\" dataKey=\"revenue\" stroke=\"var(--fui-color-accent)\" strokeWidth={2} dot={false} />\n <Line type=\"monotone\" dataKey=\"users\" stroke=\"var(--fui-color-info)\" strokeWidth={2} dot={false} />\n </LineChart>\n </ChartContainer>\n</div>"
86
80
  },
87
81
  {
88
82
  "name": "Bar Chart",
89
- "description": "Categorical bar chart comparing device sessions",
83
+ "description": "Fixed categories, compared by height — the safest default.",
90
84
  "code": "<div style={{ width: '100%', height: 300 }}>\n <ChartContainer\n config={{\n sessions: { label: 'Sessions', color: 'var(--fui-color-accent)' },\n }}\n >\n <BarChart data={deviceData} margin={{ top: 5, right: 20, bottom: 5, left: 0 }}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"device\" />\n <YAxis />\n <ChartTooltip />\n <Bar dataKey=\"sessions\" fill=\"var(--fui-color-accent)\" radius={[4, 4, 0, 0]} />\n </BarChart>\n </ChartContainer>\n</div>"
91
85
  },
92
86
  {
93
87
  "name": "Area Chart",
94
- "description": "Filled area chart showing revenue trend",
88
+ "description": "The fill under the line stresses volume, not just direction.",
95
89
  "code": "<div style={{ width: '100%', height: 300 }}>\n <ChartContainer\n config={{\n revenue: { label: 'Revenue', color: 'var(--fui-color-accent)' },\n }}\n >\n <AreaChart data={monthlyData} margin={{ top: 5, right: 20, bottom: 5, left: 0 }}>\n <CartesianGrid strokeDasharray=\"3 3\" />\n <XAxis dataKey=\"month\" />\n <YAxis />\n <ChartTooltip />\n <Area type=\"monotone\" dataKey=\"revenue\" stroke=\"var(--fui-color-accent)\" fill=\"var(--fui-color-accent)\" fillOpacity={0.15} strokeWidth={2} />\n </AreaChart>\n </ChartContainer>\n</div>"
96
90
  },
97
91
  {
98
92
  "name": "Pie Chart",
99
- "description": "Donut chart showing browser share distribution",
93
+ "description": "Parts of one whole keep it under six slices or it stops reading.",
100
94
  "code": "<div style={{ width: '100%', height: 300 }}>\n <ChartContainer\n config={{\n Chrome: { label: 'Chrome', color: 'var(--fui-color-accent)' },\n Firefox: { label: 'Firefox', color: 'var(--fui-color-info)' },\n Safari: { label: 'Safari', color: 'var(--fui-color-success)' },\n Edge: { label: 'Edge', color: 'var(--fui-color-warning)' },\n }}\n >\n <PieChart>\n <ChartTooltip />\n <ChartLegend />\n <Pie\n data={browserData}\n dataKey=\"value\"\n nameKey=\"name\"\n cx=\"50%\"\n cy=\"50%\"\n innerRadius={60}\n outerRadius={90}\n strokeWidth={2}\n >\n {browserData.map((entry) => (\n <Cell key={entry.name} fill={entry.color} />\n ))}\n </Pie>\n </PieChart>\n </ChartContainer>\n</div>"
101
95
  }
102
96
  ],
@@ -123,9 +117,7 @@
123
117
  "children: ReactElement - recharts chart component",
124
118
  "Chart.Tooltip / Chart.Legend support custom content renderers for advanced overlays"
125
119
  ],
126
- "a11yRules": [
127
- "A11Y_CHART_LABEL"
128
- ]
120
+ "a11yRules": ["A11Y_CHART_LABEL"]
129
121
  },
130
122
  "provenance": {
131
123
  "source": "migrated",