@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
@@ -107,7 +107,7 @@ const StackRoot = React.forwardRef<HTMLElement, StackProps>(function Stack(
107
107
 
108
108
  // Handle responsive direction
109
109
  if (isResponsiveDirection(direction)) {
110
- directionClass = styles.directionResponsive;
110
+ directionClass = styles.directionResponsive ?? "";
111
111
  const vars: Record<string, string> = {};
112
112
  const baseDirection = direction.base ?? "column";
113
113
  const smDirection = direction.sm ?? baseDirection;
@@ -121,12 +121,12 @@ const StackRoot = React.forwardRef<HTMLElement, StackProps>(function Stack(
121
121
  vars["--fui-stack-direction-xl"] = xlDirection;
122
122
  inlineStyle = vars as unknown as React.CSSProperties;
123
123
  } else {
124
- directionClass = styles[direction];
124
+ directionClass = styles[direction] ?? "";
125
125
  }
126
126
 
127
127
  // Handle responsive gap
128
128
  if (isResponsiveGap(gap)) {
129
- gapClass = styles.gapResponsive;
129
+ gapClass = styles.gapResponsive ?? false;
130
130
  const gapVars: Record<string, string> = {};
131
131
  if (gap.base) gapVars["--fui-stack-gap"] = resolveLayoutGap(gap.base);
132
132
  if (gap.sm) gapVars["--fui-stack-gap-sm"] = resolveLayoutGap(gap.sm);
@@ -1,15 +1,9 @@
1
1
  {
2
2
  "$schema": "https://usefragments.com/schemas/contract.v1.json",
3
3
  "name": "Switch",
4
- "description": "Binary on/off switch for settings and preferences. Provides immediate visual feedback and is ideal for options that take effect instantly.",
5
- "category": "forms",
6
- "tags": [
7
- "switch",
8
- "toggle",
9
- "boolean",
10
- "settings",
11
- "preference"
12
- ],
4
+ "description": "Toggles a setting that takes effect immediately.",
5
+ "category": "inputs",
6
+ "tags": ["switch", "toggle", "boolean", "settings", "preference"],
13
7
  "status": "stable",
14
8
  "sourcePath": "src/components/Switch/index.tsx",
15
9
  "exportName": "Switch",
@@ -78,11 +72,7 @@
78
72
  "description": "Switch track size",
79
73
  "default": "md",
80
74
  "required": false,
81
- "values": [
82
- "sm",
83
- "md",
84
- "lg"
85
- ]
75
+ "values": ["sm", "md", "lg"]
86
76
  },
87
77
  "className": {
88
78
  "type": "string",
@@ -117,35 +107,34 @@
117
107
  },
118
108
  "usage": {
119
109
  "when": [
120
- "Binary settings that take effect immediately (e.g., dark mode, notifications)",
121
- "Enabling/disabling features in a settings panel",
122
- "Options where the result is immediately visible",
123
- "Mobile-friendly boolean inputs"
110
+ "Settings that apply the moment they change",
111
+ "Turning a feature on or off in a settings panel",
112
+ "The result is visible straight away"
124
113
  ],
125
114
  "whenNot": [
126
- "Multiple options in a group (use checkbox group)",
127
- "Selection requires form submission to take effect (use checkbox)",
128
- "Yes/No questions in forms (use radio buttons)",
129
- "Complex multi-state options (use select or radio)"
115
+ "Choices that only apply on submit (use Checkbox)",
116
+ "Several options at once (use a Checkbox group)",
117
+ "Yes/no questions in a form (use RadioGroup)",
118
+ "More than two states (use Select or RadioGroup)"
130
119
  ],
131
120
  "guidelines": [
132
- "Switch should always have a visible label explaining what it controls",
133
- "The \"on\" state should be the positive/enabling action",
134
- "Changes should take effect immediately - no save button needed",
135
- "Include helperText for switches whose effect isn't obvious from the label",
136
- "Group related switches visually in settings panels"
121
+ "The label names what is being turned on",
122
+ "On always means enabled, never the reverse",
123
+ "Apply the change immediately no save button",
124
+ "Add helperText when the label alone is ambiguous",
125
+ "Stack related switches together"
137
126
  ],
138
127
  "accessibility": [
139
- "Uses role=\"switch\" with aria-checked for proper semantics",
140
- "Must have an accessible label (visible or aria-label)",
141
- "Focus indicator must be clearly visible",
142
- "State change must be announced by screen readers"
128
+ "role=\"switch\" with aria-checked",
129
+ "Every switch has a label, visible or aria-label",
130
+ "Focus ring stays visible",
131
+ "Flipping it is announced"
143
132
  ]
144
133
  },
145
134
  "examples": [
146
135
  {
147
136
  "name": "Default Off",
148
- "description": "Switch in the off state",
137
+ "description": "Nothing happens until the user flips it.",
149
138
  "code": "<StatefulSwitch label=\"Email notifications\" />",
150
139
  "args": {
151
140
  "label": "Email notifications"
@@ -153,37 +142,37 @@
153
142
  },
154
143
  {
155
144
  "name": "Checked",
156
- "description": "Switch in the on state",
157
- "code": "<StatefulSwitch checked label=\"Dark mode\" />",
145
+ "description": "Starts on; the track fills with the accent colour.",
146
+ "code": "<StatefulSwitch defaultChecked label=\"Dark mode\" />",
158
147
  "args": {
159
- "checked": true,
148
+ "defaultChecked": true,
160
149
  "label": "Dark mode"
161
150
  }
162
151
  },
163
152
  {
164
153
  "name": "With Helper Text",
165
- "description": "Switch with explanatory helper text",
166
- "code": "<StatefulSwitch\n checked\n label=\"Auto-save\"\n helperText=\"Automatically save changes as you type\"\n/>",
154
+ "description": "Second line says what the setting actually does.",
155
+ "code": "<StatefulSwitch\n defaultChecked\n label=\"Auto-save\"\n helperText=\"Automatically save changes as you type\"\n/>",
167
156
  "args": {
168
- "checked": true,
157
+ "defaultChecked": true,
169
158
  "label": "Auto-save",
170
159
  "helperText": "Automatically save changes as you type"
171
160
  }
172
161
  },
173
162
  {
174
163
  "name": "Sizes",
175
- "description": "Available size variants",
176
- "code": "<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <StatefulSwitch size=\"sm\" checked label=\"Small switch\" />\n <StatefulSwitch size=\"md\" checked label=\"Medium switch (default)\" />\n <StatefulSwitch size=\"lg\" checked label=\"Large switch\" />\n</div>"
164
+ "description": "Three track sizes: sm, md, lg.",
165
+ "code": "<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <StatefulSwitch size=\"sm\" defaultChecked label=\"Small switch\" />\n <StatefulSwitch size=\"md\" defaultChecked label=\"Medium switch (default)\" />\n <StatefulSwitch size=\"lg\" defaultChecked label=\"Large switch\" />\n</div>"
177
166
  },
178
167
  {
179
168
  "name": "Disabled States",
180
- "description": "Non-interactive switches showing both states",
169
+ "description": "Locked off and locked on, both dimmed.",
181
170
  "code": "<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>\n <Switch disabled label=\"Premium feature (upgrade required)\" />\n <Switch disabled checked label=\"System managed (read-only)\" />\n</div>"
182
171
  },
183
172
  {
184
173
  "name": "Settings Panel",
185
- "description": "Multiple switches in a realistic settings layout",
186
- "code": "<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '320px' }}>\n <StatefulSwitch\n checked\n label=\"Push notifications\"\n helperText=\"Receive push notifications on your device\"\n />\n <StatefulSwitch\n checked\n label=\"Email digest\"\n helperText=\"Weekly summary of your activity\"\n />\n <StatefulSwitch\n label=\"Marketing emails\"\n helperText=\"Product updates and promotional offers\"\n />\n</div>"
174
+ "description": "Stacked switches sharing one rhythm and helper column.",
175
+ "code": "<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '320px' }}>\n <StatefulSwitch\n defaultChecked\n label=\"Push notifications\"\n helperText=\"Receive push notifications on your device\"\n />\n <StatefulSwitch\n defaultChecked\n label=\"Email digest\"\n helperText=\"Weekly summary of your activity\"\n />\n <StatefulSwitch\n label=\"Marketing emails\"\n helperText=\"Product updates and promotional offers\"\n />\n</div>"
187
176
  }
188
177
  ],
189
178
  "relations": [
@@ -218,9 +207,7 @@
218
207
  },
219
208
  "ai": {
220
209
  "compositionPattern": "compound",
221
- "subComponents": [
222
- "Root"
223
- ]
210
+ "subComponents": ["Root"]
224
211
  },
225
212
  "provenance": {
226
213
  "source": "migrated",
@@ -7,28 +7,72 @@
7
7
 
8
8
  .root {
9
9
  --_switch-off-bg: light-dark(
10
- color-mix(in srgb, var(--fui-bg-elevated) 92%, var(--fui-text-primary) 8%),
11
- color-mix(in srgb, var(--fui-bg-elevated) 82%, var(--fui-text-primary) 18%)
10
+ color-mix(
11
+ in srgb,
12
+ var(--fui-bg-elevated, #{$fui-bg-elevated}) 92%,
13
+ var(--fui-text-primary, #{$fui-text-primary}) 8%
14
+ ),
15
+ color-mix(
16
+ in srgb,
17
+ var(--fui-bg-elevated, #{$fui-bg-elevated}) 82%,
18
+ var(--fui-text-primary, #{$fui-text-primary}) 18%
19
+ )
12
20
  );
13
21
  --_switch-off-bg-hover: light-dark(
14
- color-mix(in srgb, var(--fui-bg-elevated) 88%, var(--fui-text-primary) 12%),
15
- color-mix(in srgb, var(--fui-bg-elevated) 76%, var(--fui-text-primary) 24%)
22
+ color-mix(
23
+ in srgb,
24
+ var(--fui-bg-elevated, #{$fui-bg-elevated}) 88%,
25
+ var(--fui-text-primary, #{$fui-text-primary}) 12%
26
+ ),
27
+ color-mix(
28
+ in srgb,
29
+ var(--fui-bg-elevated, #{$fui-bg-elevated}) 76%,
30
+ var(--fui-text-primary, #{$fui-text-primary}) 24%
31
+ )
16
32
  );
17
33
  --_switch-off-border: light-dark(
18
- color-mix(in srgb, var(--fui-border-strong) 72%, var(--fui-text-primary) 28%),
19
- color-mix(in srgb, var(--fui-border-strong) 58%, var(--fui-text-primary) 42%)
34
+ color-mix(
35
+ in srgb,
36
+ var(--fui-border-strong, #{$fui-border-strong}) 72%,
37
+ var(--fui-text-primary, #{$fui-text-primary}) 28%
38
+ ),
39
+ color-mix(
40
+ in srgb,
41
+ var(--fui-border-strong, #{$fui-border-strong}) 58%,
42
+ var(--fui-text-primary, #{$fui-text-primary}) 42%
43
+ )
20
44
  );
21
45
  --_switch-off-border-hover: light-dark(
22
- color-mix(in srgb, var(--fui-border-strong) 58%, var(--fui-text-primary) 42%),
23
- color-mix(in srgb, var(--fui-border-strong) 44%, var(--fui-text-primary) 56%)
46
+ color-mix(
47
+ in srgb,
48
+ var(--fui-border-strong, #{$fui-border-strong}) 58%,
49
+ var(--fui-text-primary, #{$fui-text-primary}) 42%
50
+ ),
51
+ color-mix(
52
+ in srgb,
53
+ var(--fui-border-strong, #{$fui-border-strong}) 44%,
54
+ var(--fui-text-primary, #{$fui-text-primary}) 56%
55
+ )
24
56
  );
25
57
  --_switch-thumb-bg: light-dark(
26
- color-mix(in srgb, var(--fui-bg-primary) 98%, white 2%),
27
- color-mix(in srgb, var(--fui-bg-primary) 56%, var(--fui-text-primary) 44%)
58
+ color-mix(in srgb, var(--fui-bg-primary, #{$fui-bg-primary}) 98%, white 2%),
59
+ color-mix(
60
+ in srgb,
61
+ var(--fui-bg-primary, #{$fui-bg-primary}) 56%,
62
+ var(--fui-text-primary, #{$fui-text-primary}) 44%
63
+ )
28
64
  );
29
65
  --_switch-thumb-border: light-dark(
30
- color-mix(in srgb, var(--fui-border-strong) 68%, var(--fui-text-primary) 32%),
31
- color-mix(in srgb, var(--fui-border-strong) 45%, var(--fui-text-primary) 55%)
66
+ color-mix(
67
+ in srgb,
68
+ var(--fui-border-strong, #{$fui-border-strong}) 68%,
69
+ var(--fui-text-primary, #{$fui-text-primary}) 32%
70
+ ),
71
+ color-mix(
72
+ in srgb,
73
+ var(--fui-border-strong, #{$fui-border-strong}) 45%,
74
+ var(--fui-text-primary, #{$fui-text-primary}) 55%
75
+ )
32
76
  );
33
77
 
34
78
  @include target.hit-area("compact");
@@ -85,11 +129,8 @@
85
129
  box-shadow var(--fui-transition-normal, $fui-transition-normal);
86
130
 
87
131
  .root[data-checked] & {
88
- background-color: var(--fui-button-primary-base, $fui-color-accent);
89
- border-color: var(
90
- --fui-button-primary-border,
91
- var(--fui-button-primary-base, #{$fui-color-accent})
92
- );
132
+ background-color: var(--fui-control-checked-bg, $fui-color-accent);
133
+ border-color: var(--fui-control-checked-border, $fui-color-accent);
93
134
  box-shadow: inset 0 1px 0 color-mix(in srgb, white 24%, transparent);
94
135
  }
95
136
 
@@ -99,11 +140,8 @@
99
140
  }
100
141
 
101
142
  .root:not([data-disabled])[data-checked] &:hover {
102
- background-color: var(--fui-button-primary-hover, $fui-color-accent);
103
- border-color: var(
104
- --fui-button-primary-border-hover,
105
- var(--fui-button-primary-hover, #{$fui-color-accent})
106
- );
143
+ background-color: var(--fui-control-checked-bg-hover, $fui-color-accent-hover);
144
+ border-color: var(--fui-control-checked-border-hover, $fui-color-accent-hover);
107
145
  }
108
146
 
109
147
  .root:focus-visible & {
@@ -139,7 +177,7 @@
139
177
  box-sizing: border-box;
140
178
  width: var(--_fui-switch-thumb-size);
141
179
  height: var(--_fui-switch-thumb-size);
142
- border-radius: 50%;
180
+ border-radius: var(--fui-radius-full, $fui-radius-full);
143
181
  pointer-events: none;
144
182
  background-color: var(--_switch-thumb-bg);
145
183
  border: var(--fui-stroke-hairline, 1px) solid var(--_switch-thumb-border);
@@ -155,10 +193,10 @@
155
193
 
156
194
  .root[data-checked] & {
157
195
  transform: translate(var(--_fui-switch-travel), -50%);
158
- background-color: var(--fui-button-primary-color, #fff);
196
+ background-color: var(--fui-control-checked-color, $fui-color-on-accent);
159
197
  border-color: color-mix(
160
198
  in srgb,
161
- var(--fui-button-primary-active, #{$fui-color-accent}) 28%,
199
+ var(--fui-control-checked-border, #{$fui-color-accent}) 28%,
162
200
  transparent
163
201
  );
164
202
  }
@@ -198,7 +236,7 @@
198
236
  }
199
237
 
200
238
  .root[data-checked] .track {
201
- border-color: var(--fui-button-primary-base, $fui-color-accent);
239
+ border-color: var(--fui-control-checked-border, $fui-color-accent);
202
240
  }
203
241
  }
204
242
 
@@ -1,14 +1,9 @@
1
1
  {
2
2
  "$schema": "https://usefragments.com/schemas/contract.v1.json",
3
3
  "name": "Table",
4
- "description": "Semantic HTML table with compound API. For data-rich tables with sorting and selection, use DataTable.",
4
+ "description": "Renders tabular data as a real HTML table headers, rows, footer.",
5
5
  "category": "display",
6
- "tags": [
7
- "table",
8
- "semantic",
9
- "html",
10
- "layout"
11
- ],
6
+ "tags": ["table", "semantic", "html", "layout"],
12
7
  "status": "stable",
13
8
  "sourcePath": "src/components/Table/index.tsx",
14
9
  "exportName": "Table",
@@ -26,10 +21,7 @@
26
21
  "description": "Table density",
27
22
  "default": "md",
28
23
  "required": false,
29
- "values": [
30
- "sm",
31
- "md"
32
- ]
24
+ "values": ["sm", "md"]
33
25
  },
34
26
  "striped": {
35
27
  "type": "boolean",
@@ -61,22 +53,19 @@
61
53
  },
62
54
  "usage": {
63
55
  "when": [
64
- "Displaying simple tabular data with semantic HTML",
65
- "Static data that does not need sorting or selection",
66
- "Showing structured information with headers and rows",
67
- "Tables with footers or captions"
56
+ "The data is static — read it, do not interact with it",
57
+ "You need real thead/tbody/tfoot semantics",
58
+ "The table needs a caption or a totals footer"
68
59
  ],
69
60
  "whenNot": [
70
- "Data that needs sorting (use DataTable)",
71
- "Data that needs row selection (use DataTable)",
72
- "Data that needs clickable rows (use DataTable)",
73
- "Simple lists (use List component)"
61
+ "Rows need sorting, selection, or clicking (use DataTable)",
62
+ "Content is a single column of items (use List)"
74
63
  ],
75
64
  "guidelines": [
76
- "Use Table.HeaderCell for column headers (adds scope=\"col\" by default)",
77
- "Use Table.Caption for table descriptions (can be visually hidden)",
78
- "Keep tables simple use DataTable for interactive features",
79
- "Consider mobile responsiveness; table scrolls horizontally on small screens"
65
+ "Header cells go in Table.HeaderCell it sets scope=\"col\" for you",
66
+ "Give every table a caption or aria-label; visuallyHidden keeps it off screen",
67
+ "Reach for density, not the deprecated size prop",
68
+ "Narrow viewports scroll the table sideways keep column count low"
80
69
  ],
81
70
  "accessibility": [
82
71
  "Semantic HTML table elements (thead, tbody, tfoot, th, td)",
@@ -88,37 +77,42 @@
88
77
  "examples": [
89
78
  {
90
79
  "name": "Default",
91
- "description": "Basic semantic table",
80
+ "description": "Header row plus body rows, no extra styling.",
92
81
  "code": "<Table aria-label=\"Team members\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Name</Table.HeaderCell>\n <Table.HeaderCell>Role</Table.HeaderCell>\n <Table.HeaderCell>Status</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Alice Johnson</Table.Cell>\n <Table.Cell>Engineer</Table.Cell>\n <Table.Cell>Active</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Bob Smith</Table.Cell>\n <Table.Cell>Designer</Table.Cell>\n <Table.Cell>Active</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Carol Williams</Table.Cell>\n <Table.Cell>PM</Table.Cell>\n <Table.Cell>Away</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"
93
82
  },
83
+ {
84
+ "name": "Empty",
85
+ "description": "Keep the headers and fill one full-width cell so the layout holds.",
86
+ "code": "<Table aria-label=\"Team members\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Name</Table.HeaderCell>\n <Table.HeaderCell>Role</Table.HeaderCell>\n <Table.HeaderCell>Status</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell colSpan={3}>No team members yet.</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"
87
+ },
94
88
  {
95
89
  "name": "Striped",
96
- "description": "Alternating row backgrounds for readability",
90
+ "description": "Row tint alternates so the eye tracks across wide rows.",
97
91
  "code": "<Table striped aria-label=\"Inventory\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Item</Table.HeaderCell>\n <Table.HeaderCell>Category</Table.HeaderCell>\n <Table.HeaderCell>Qty</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Widget A</Table.Cell>\n <Table.Cell>Hardware</Table.Cell>\n <Table.Cell>120</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Widget B</Table.Cell>\n <Table.Cell>Software</Table.Cell>\n <Table.Cell>85</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Widget C</Table.Cell>\n <Table.Cell>Hardware</Table.Cell>\n <Table.Cell>200</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Widget D</Table.Cell>\n <Table.Cell>Software</Table.Cell>\n <Table.Cell>50</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"
98
92
  },
99
93
  {
100
94
  "name": "Bordered",
101
- "description": "Table with bordered container",
95
+ "description": "A border wraps the data so it reads as one block on a busy page.",
102
96
  "code": "<Table bordered aria-label=\"Pricing\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Plan</Table.HeaderCell>\n <Table.HeaderCell>Price</Table.HeaderCell>\n <Table.HeaderCell>Features</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Basic</Table.Cell>\n <Table.Cell>$9/mo</Table.Cell>\n <Table.Cell>5 projects</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Pro</Table.Cell>\n <Table.Cell>$29/mo</Table.Cell>\n <Table.Cell>Unlimited</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"
103
97
  },
104
98
  {
105
99
  "name": "Compact",
106
- "description": "Small, dense table",
107
- "code": "<Table size=\"sm\" aria-label=\"Shortcuts\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Key</Table.HeaderCell>\n <Table.HeaderCell>Action</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Ctrl+S</Table.Cell>\n <Table.Cell>Save</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Ctrl+Z</Table.Cell>\n <Table.Cell>Undo</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Ctrl+C</Table.Cell>\n <Table.Cell>Copy</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"
100
+ "description": "Tighter rows fit more data in the same height.",
101
+ "code": "<Table density=\"compact\" aria-label=\"Shortcuts\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Key</Table.HeaderCell>\n <Table.HeaderCell>Action</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Ctrl+S</Table.Cell>\n <Table.Cell>Save</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Ctrl+Z</Table.Cell>\n <Table.Cell>Undo</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Ctrl+C</Table.Cell>\n <Table.Cell>Copy</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"
108
102
  },
109
103
  {
110
104
  "name": "With Caption",
111
- "description": "Table with visible caption",
105
+ "description": "A visible caption titles the data for every reader.",
112
106
  "code": "<Table aria-label=\"Q1 results\">\n <Table.Caption>Quarterly Results (Q1 2026)</Table.Caption>\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Metric</Table.HeaderCell>\n <Table.HeaderCell>Value</Table.HeaderCell>\n <Table.HeaderCell>Change</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Revenue</Table.Cell>\n <Table.Cell>$1.2M</Table.Cell>\n <Table.Cell>+15%</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Users</Table.Cell>\n <Table.Cell>24,500</Table.Cell>\n <Table.Cell>+8%</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"
113
107
  },
114
108
  {
115
109
  "name": "Screen Reader Caption",
116
- "description": "Visually hidden caption for screen-reader context while keeping visual UI compact",
117
- "code": "<Table\n aria-label=\"API keys\"\n wrapperProps={{ 'data-demo': 'table-wrapper' }}\n wrapperClassName=\"demo-table-wrapper\"\n>\n <Table.Caption visuallyHidden>API keys and last-used timestamps</Table.Caption>\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Name</Table.HeaderCell>\n <Table.HeaderCell>Prefix</Table.HeaderCell>\n <Table.HeaderCell>Last Used</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Deploy</Table.Cell>\n <Table.Cell>frg_live_...</Table.Cell>\n <Table.Cell>2 hours ago</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>CI</Table.Cell>\n <Table.Cell>frg_test_...</Table.Cell>\n <Table.Cell>Yesterday</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"
110
+ "description": "The caption reaches screen readers only; the layout stays tight.",
111
+ "code": "<Table aria-label=\"API keys\">\n <Table.Caption visuallyHidden>API keys and last-used timestamps</Table.Caption>\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Name</Table.HeaderCell>\n <Table.HeaderCell>Prefix</Table.HeaderCell>\n <Table.HeaderCell>Last Used</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Deploy</Table.Cell>\n <Table.Cell>frg_live_...</Table.Cell>\n <Table.Cell>2 hours ago</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>CI</Table.Cell>\n <Table.Cell>frg_test_...</Table.Cell>\n <Table.Cell>Yesterday</Table.Cell>\n </Table.Row>\n </Table.Body>\n</Table>"
118
112
  },
119
113
  {
120
114
  "name": "With Footer",
121
- "description": "Table with footer row for totals",
115
+ "description": "Totals sit in a footer that stays separate from the data.",
122
116
  "code": "<Table bordered aria-label=\"Expenses\">\n <Table.Head>\n <Table.Row>\n <Table.HeaderCell>Category</Table.HeaderCell>\n <Table.HeaderCell>Amount</Table.HeaderCell>\n </Table.Row>\n </Table.Head>\n <Table.Body>\n <Table.Row>\n <Table.Cell>Marketing</Table.Cell>\n <Table.Cell>$12,000</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Engineering</Table.Cell>\n <Table.Cell>$45,000</Table.Cell>\n </Table.Row>\n <Table.Row>\n <Table.Cell>Operations</Table.Cell>\n <Table.Cell>$8,000</Table.Cell>\n </Table.Row>\n </Table.Body>\n <Table.Footer>\n <Table.Row>\n <Table.Cell>Total</Table.Cell>\n <Table.Cell>$65,000</Table.Cell>\n </Table.Row>\n </Table.Footer>\n</Table>"
123
117
  }
124
118
  ],
@@ -141,23 +135,11 @@
141
135
  "wrapperClassName/wrapperProps - customize outer scroll wrapper",
142
136
  "Table.Caption - caption with visuallyHidden prop (hidden is deprecated alias)"
143
137
  ],
144
- "a11yRules": [
145
- "A11Y_TABLE_HEADERS",
146
- "A11Y_TABLE_CAPTION"
147
- ]
138
+ "a11yRules": ["A11Y_TABLE_HEADERS", "A11Y_TABLE_CAPTION"]
148
139
  },
149
140
  "ai": {
150
141
  "compositionPattern": "compound",
151
- "subComponents": [
152
- "Root",
153
- "Head",
154
- "Body",
155
- "Footer",
156
- "Row",
157
- "Cell",
158
- "HeaderCell",
159
- "Caption"
160
- ],
142
+ "subComponents": ["Root", "Head", "Body", "Footer", "Row", "Cell", "HeaderCell", "Caption"],
161
143
  "commonPatterns": [
162
144
  "<Table><Table.Head><Table.Row><Table.HeaderCell>Name</Table.HeaderCell></Table.Row></Table.Head><Table.Body><Table.Row><Table.Cell>Alice</Table.Cell></Table.Row></Table.Body></Table>"
163
145
  ]
@@ -50,7 +50,7 @@
50
50
  .headerContent {
51
51
  display: flex;
52
52
  align-items: center;
53
- gap: var(--fui-raw-space-4);
53
+ gap: var(--fui-raw-space-4, 4px);
54
54
  }
55
55
 
56
56
  .row {
@@ -78,6 +78,17 @@
78
78
  @include table-chrome.body-cell;
79
79
  }
80
80
 
81
+ // Unbordered ledger edge: the first column starts at the surrounding surface's
82
+ // own inset so a table inside a card reads as part of the card, not a box within
83
+ // a box. A bordered table owns its frame and keeps the recipe's inline inset.
84
+ .wrapper:not(.bordered) > .table {
85
+ > .thead > .row > .th:first-child,
86
+ > .tbody > .row > .td:first-child,
87
+ > .tfoot > .row > .td:first-child {
88
+ padding-inline-start: 0;
89
+ }
90
+ }
91
+
81
92
  .selected {
82
93
  --fui-table-row-bg: var(
83
94
  --fui-table-row-selected-bg,
@@ -112,8 +123,9 @@
112
123
  }
113
124
 
114
125
  .bordered {
115
- overflow: hidden;
116
- border: var(--fui-table-divider-size, var(--fui-stroke-hairline)) solid
126
+ overflow-x: auto;
127
+ overflow-y: hidden;
128
+ border: var(--fui-table-divider-size, var(--fui-stroke-hairline, $fui-stroke-hairline)) solid
117
129
  var(--fui-table-border, var(--fui-border, #{$fui-border}));
118
130
  border-radius: var(--fui-radius-md, $fui-radius-md);
119
131
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://usefragments.com/schemas/contract.v1.json",
3
3
  "name": "TableOfContents",
4
- "description": "Sticky sidebar navigation for long-form content or filterable lists. Renders a quiet, flush index with nested indentation and an ink-weight active state.",
4
+ "description": "Indexes a long page and marks the section currently in view.",
5
5
  "category": "navigation",
6
6
  "tags": [
7
7
  "toc",
@@ -20,7 +20,8 @@
20
20
  "children: node (required)",
21
21
  "label: string (default: Table of contents)",
22
22
  "title: string (default: On This Page)",
23
- "hideTitle: boolean (default: false)"
23
+ "hideTitle: boolean (default: false)",
24
+ "hideSubItems: boolean (default: false)"
24
25
  ],
25
26
  "props": {
26
27
  "children": {
@@ -45,28 +46,34 @@
45
46
  "description": "Hide the visible title",
46
47
  "default": "false",
47
48
  "required": false
49
+ },
50
+ "hideSubItems": {
51
+ "type": "boolean",
52
+ "description": "Hide indented items and nested groups",
53
+ "default": "false",
54
+ "required": false
48
55
  }
49
56
  },
50
57
  "usage": {
51
58
  "when": [
52
- "Long-form content pages (docs, blog posts, articles)",
53
- "Component documentation with multiple sections",
54
- "Filterable list sidebars where items are grouped by category",
55
- "Any page with 3+ headings or nested sections that benefit from quick navigation"
59
+ "Docs, articles, and other long reads",
60
+ "Reference pages with many sections",
61
+ "Filterable sidebars grouped by category",
62
+ "Anything past three headings"
56
63
  ],
57
64
  "whenNot": [
58
- "Short pages with only 1-2 sections",
59
- "Primary site navigation (use Sidebar or Header)",
60
- "Step-by-step flows (use Stepper)"
65
+ "Pages with one or two sections",
66
+ "Site navigation (use Sidebar or Header)",
67
+ "Steps in an order (use Stepper)"
61
68
  ],
62
69
  "guidelines": [
63
- "Pair with a scroll spy hook (e.g., IntersectionObserver) to track active heading",
64
- "Use TableOfContents.Group to nest items under a labeled, optionally-collapsible parent",
65
- "The legacy `indent` boolean on Item is preserved for back-compat; prefer Group for new code",
66
- "Place in a sticky aside for best UX",
67
- "Heading IDs must match between TOC items and the actual DOM headings",
68
- "TableOfContents.Item performs smooth scrolling by default; call event.preventDefault() in onClick to override",
69
- "Group is uncontrolled (defaultOpen=true) by default; pass open + onOpenChange for controlled state"
70
+ "Drive the active item from an IntersectionObserver scroll spy",
71
+ "Sub-items show by default pass hideSubItems for a compact index",
72
+ "Group nests items under a labelled, optionally collapsible parent",
73
+ "Item ids must match the real heading ids",
74
+ "Items smooth-scroll call preventDefault() in onClick to take over",
75
+ "Group is uncontrolled and open by default; pass open and onOpenChange to drive it",
76
+ "The legacy indent boolean still works; prefer Group in new code"
70
77
  ],
71
78
  "accessibility": [
72
79
  "Uses <nav aria-label=\"Table of contents\"> for landmark navigation",
@@ -79,27 +86,32 @@
79
86
  "examples": [
80
87
  {
81
88
  "name": "Default",
82
- "description": "Basic table of contents with section links",
89
+ "description": "Sections and their subsections, indented.",
83
90
  "code": "<TableOfContents>\n <TableOfContents.Item id=\"introduction\">Introduction</TableOfContents.Item>\n <TableOfContents.Item id=\"getting-started\">Getting Started</TableOfContents.Item>\n <TableOfContents.Item id=\"installation\" indent>Installation</TableOfContents.Item>\n <TableOfContents.Item id=\"configuration\" indent>Configuration</TableOfContents.Item>\n <TableOfContents.Item id=\"api-reference\">API Reference</TableOfContents.Item>\n <TableOfContents.Item id=\"examples\">Examples</TableOfContents.Item>\n</TableOfContents>"
84
91
  },
92
+ {
93
+ "name": "Top-level Only",
94
+ "description": "Drops subsections when the index would crowd.",
95
+ "code": "<TableOfContents hideSubItems>\n <TableOfContents.Item id=\"overview\">Overview</TableOfContents.Item>\n <TableOfContents.Item id=\"basic-usage\" indent>Basic usage</TableOfContents.Item>\n <TableOfContents.Item id=\"advanced-usage\" indent>Advanced usage</TableOfContents.Item>\n <TableOfContents.Item id=\"accessibility\">Accessibility</TableOfContents.Item>\n</TableOfContents>"
96
+ },
85
97
  {
86
98
  "name": "Nested Groups",
87
- "description": "Filterable list grouped by category with clear nested indentation",
99
+ "description": "Collapsible categories with counts.",
88
100
  "code": "<TableOfContents title=\"Components\">\n <TableOfContents.Item id=\"all\" active>All</TableOfContents.Item>\n <TableOfContents.Group label=\"Primitives\" trailing={<span>3</span>}>\n <TableOfContents.Item id=\"button\">Button</TableOfContents.Item>\n <TableOfContents.Item id=\"card\">Card</TableOfContents.Item>\n <TableOfContents.Item id=\"input\">Input</TableOfContents.Item>\n </TableOfContents.Group>\n <TableOfContents.Group label=\"Custom\" defaultOpen={false}>\n <TableOfContents.Item id=\"features\">Features</TableOfContents.Item>\n <TableOfContents.Item id=\"plans\">Plans</TableOfContents.Item>\n </TableOfContents.Group>\n</TableOfContents>"
89
101
  },
90
102
  {
91
103
  "name": "With Active Item",
92
- "description": "Active state highlighting the current section",
104
+ "description": "The current section stays marked while you read.",
93
105
  "code": "<TableOfContents>\n <TableOfContents.Item id=\"overview\">Overview</TableOfContents.Item>\n <TableOfContents.Item id=\"setup\" active>Setup</TableOfContents.Item>\n <TableOfContents.Item id=\"usage\" indent>Basic Usage</TableOfContents.Item>\n <TableOfContents.Item id=\"advanced\" indent>Advanced</TableOfContents.Item>\n <TableOfContents.Item id=\"props\">Props</TableOfContents.Item>\n <TableOfContents.Item id=\"accessibility\">Accessibility</TableOfContents.Item>\n</TableOfContents>"
94
106
  },
95
107
  {
96
108
  "name": "Custom Title",
97
- "description": "Table of contents with a custom title",
109
+ "description": "Any heading in place of the default.",
98
110
  "code": "<TableOfContents title=\"Contents\">\n <TableOfContents.Item id=\"chapter-1\">Chapter 1: The Beginning</TableOfContents.Item>\n <TableOfContents.Item id=\"chapter-2\">Chapter 2: The Middle</TableOfContents.Item>\n <TableOfContents.Item id=\"chapter-3\">Chapter 3: The End</TableOfContents.Item>\n</TableOfContents>"
99
111
  },
100
112
  {
101
113
  "name": "No Title",
102
- "description": "Table of contents without a visible title",
114
+ "description": "Bare list where the surrounding layout already says enough.",
103
115
  "code": "<TableOfContents hideTitle>\n <TableOfContents.Item id=\"section-a\">Section A</TableOfContents.Item>\n <TableOfContents.Item id=\"section-b\" active>Section B</TableOfContents.Item>\n <TableOfContents.Item id=\"section-c\">Section C</TableOfContents.Item>\n</TableOfContents>"
104
116
  }
105
117
  ],
@@ -124,6 +136,7 @@
124
136
  "propsSummary": [
125
137
  "title: string - visible heading (default \"On This Page\")",
126
138
  "hideTitle: boolean - hide the title",
139
+ "hideSubItems: boolean - hide indented items and nested groups (default false)",
127
140
  "label: string - aria-label for nav landmark",
128
141
  "TableOfContents.Item id: string - heading ID to link to",
129
142
  "TableOfContents.Item active: boolean - highlight the current item with ink and weight",