@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
@@ -6,8 +6,10 @@ import { useState, useCallback, useEffect, useMemo } from "react";
6
6
  // Lazy-loaded dependency (shiki)
7
7
  // ============================================
8
8
 
9
+ type ShikiThemeInput = string | typeof import("./css-variables-theme").FUI_CSS_VARIABLES_THEME;
10
+
9
11
  let _codeToHtml:
10
- | ((code: string, options: { lang: string; theme: string }) => Promise<string>)
12
+ | ((code: string, options: { lang: string; theme: ShikiThemeInput }) => Promise<string>)
11
13
  | null = null;
12
14
  let _shikiLoadPromise: Promise<void> | null = null;
13
15
  let _shikiFailed = false;
@@ -28,7 +30,9 @@ async function loadShikiDeps() {
28
30
  await _shikiLoadPromise;
29
31
  }
30
32
  import { TabsRoot, TabsList, Tab, TabsPanel } from "../Tabs";
33
+ import { FUI_CSS_VARIABLES_THEME } from "./css-variables-theme";
31
34
  import styles from "./CodeBlock.module.scss";
35
+ import { isDevelopmentBuild, isProductionBuild } from "../../utils/env";
32
36
 
33
37
  export type CodeBlockLanguage =
34
38
  | "tsx"
@@ -76,6 +80,7 @@ const LANGUAGE_ALIASES: Partial<Record<CodeBlockLanguage, string>> = {
76
80
 
77
81
  /** Available syntax highlighting themes */
78
82
  export type CodeBlockTheme =
83
+ | "css-variables"
79
84
  | "synthwave-84"
80
85
  | "github-dark"
81
86
  | "github-light"
@@ -95,7 +100,7 @@ export interface CodeBlockProps extends React.HTMLAttributes<HTMLDivElement> {
95
100
  code: string;
96
101
  /** Programming language for syntax highlighting */
97
102
  language?: CodeBlockLanguage;
98
- /** Syntax highlighting theme */
103
+ /** Syntax highlighting theme. Default follows `--fui-code-token-*` via shiki css-variables. */
99
104
  theme?: CodeBlockTheme;
100
105
  /** Show copy button */
101
106
  showCopy?: boolean;
@@ -125,6 +130,12 @@ export interface CodeBlockProps extends React.HTMLAttributes<HTMLDivElement> {
125
130
  defaultCollapsed?: boolean;
126
131
  /** Number of lines to show when collapsed */
127
132
  collapsedLines?: number;
133
+ /**
134
+ * Collapse control copy. `lines` keeps “Show N more lines” / “Show less”
135
+ * (docs prose). `expand` is one right-aligned Expand / Collapse control
136
+ * for preview+code capsules.
137
+ */
138
+ collapseAction?: "lines" | "expand";
128
139
  /** Compact mode with reduced padding */
129
140
  compact?: boolean;
130
141
  /** Show a persistent copy button (always visible, uses Button component) */
@@ -547,14 +558,22 @@ function processShikiHtml(html: string, options: ProcessOptions): string {
547
558
  const lineClass = lineClasses.join(" ");
548
559
  const diffMarker = isAdded ? "+" : isRemoved ? "-" : " ";
549
560
 
550
- if (showLineNumbers || hasDiff) {
551
- const lineNumHtml = showLineNumbers
552
- ? `<span class="line-number">${displayLineNum}</span>`
561
+ const lineNumHtml =
562
+ showLineNumbers || hasDiff
563
+ ? `${showLineNumbers ? `<span class="line-number">${displayLineNum}</span>` : ""}${
564
+ hasDiff ? `<span class="diff-marker">${diffMarker}</span>` : ""
565
+ }`
553
566
  : "";
554
- const diffMarkerHtml = hasDiff ? `<span class="diff-marker">${diffMarker}</span>` : "";
555
- return `<span class="${lineClass}">${lineNumHtml}${diffMarkerHtml}${line}</span>`;
567
+
568
+ // Shiki already wraps each row in <span class="line">; merge into that span
569
+ // instead of nesting a second .line (which breaks the inline-block row layout).
570
+ if (/^<span class="line([^"]*)">/.test(line)) {
571
+ return line.replace(
572
+ /^<span class="line([^"]*)">/,
573
+ `<span class="${lineClass}$1">${lineNumHtml}`
574
+ );
556
575
  }
557
- return `<span class="${lineClass}">${line}</span>`;
576
+ return `<span class="${lineClass}">${lineNumHtml}${line}</span>`;
558
577
  });
559
578
 
560
579
  // Reconstruct the HTML
@@ -565,7 +584,7 @@ const CodeBlockBase = React.forwardRef<HTMLDivElement, CodeBlockProps>(function
565
584
  {
566
585
  code,
567
586
  language = "tsx",
568
- theme = "one-dark-pro",
587
+ theme = "css-variables",
569
588
  showCopy = true,
570
589
  title,
571
590
  filename,
@@ -580,6 +599,7 @@ const CodeBlockBase = React.forwardRef<HTMLDivElement, CodeBlockProps>(function
580
599
  collapsible = false,
581
600
  defaultCollapsed = false,
582
601
  collapsedLines = 5,
602
+ collapseAction = "lines",
583
603
  compact = false,
584
604
  persistentCopy = false,
585
605
  copyPlacement = "auto",
@@ -591,7 +611,10 @@ const CodeBlockBase = React.forwardRef<HTMLDivElement, CodeBlockProps>(function
591
611
  ref
592
612
  ) {
593
613
  const [copied, setCopied] = useState(false);
594
- const [highlight, setHighlight] = useState<{ html: string; loading: boolean }>({ html: '', loading: true });
614
+ const [highlight, setHighlight] = useState<{ html: string; loading: boolean }>({
615
+ html: "",
616
+ loading: true,
617
+ });
595
618
  const [isCollapsed, setIsCollapsed] = useState(defaultCollapsed);
596
619
 
597
620
  const trimmedCode = useMemo(() => normalizeCode(code, language), [code, language]);
@@ -624,7 +647,7 @@ const CodeBlockBase = React.forwardRef<HTMLDivElement, CodeBlockProps>(function
624
647
  const fallbackHtml = `<pre class="shiki"><code>${escapeHtml(visibleCode)}</code></pre>`;
625
648
 
626
649
  if (_shikiFailed || !_codeToHtml) {
627
- if (_shikiFailed && process.env.NODE_ENV === "development") {
650
+ if (_shikiFailed && isDevelopmentBuild()) {
628
651
  console.warn(
629
652
  "[@usefragments/ui] CodeBlock: shiki is not installed. " +
630
653
  "Install it with: npm install shiki"
@@ -635,7 +658,9 @@ const CodeBlockBase = React.forwardRef<HTMLDivElement, CodeBlockProps>(function
635
658
 
636
659
  try {
637
660
  const resolvedLang = LANGUAGE_ALIASES[language] || language;
638
- const html = await _codeToHtml(visibleCode, { lang: resolvedLang, theme });
661
+ const shikiTheme: ShikiThemeInput =
662
+ theme === "css-variables" ? FUI_CSS_VARIABLES_THEME : theme;
663
+ const html = await _codeToHtml(visibleCode, { lang: resolvedLang, theme: shikiTheme });
639
664
  return processShikiHtml(html, {
640
665
  showLineNumbers,
641
666
  startLineNumber,
@@ -644,7 +669,7 @@ const CodeBlockBase = React.forwardRef<HTMLDivElement, CodeBlockProps>(function
644
669
  removedLines: removedSet,
645
670
  });
646
671
  } catch (err) {
647
- if (process.env.NODE_ENV !== "production") {
672
+ if (!isProductionBuild()) {
648
673
  console.error("Syntax highlighting failed:", err);
649
674
  }
650
675
  return fallbackHtml;
@@ -679,7 +704,7 @@ const CodeBlockBase = React.forwardRef<HTMLDivElement, CodeBlockProps>(function
679
704
  setTimeout(() => setCopied(false), 2000);
680
705
  onCopy?.();
681
706
  } catch (err) {
682
- if (process.env.NODE_ENV !== "production") {
707
+ if (!isProductionBuild()) {
683
708
  console.error("Failed to copy:", err);
684
709
  }
685
710
  }
@@ -714,9 +739,13 @@ const CodeBlockBase = React.forwardRef<HTMLDivElement, CodeBlockProps>(function
714
739
  : undefined;
715
740
 
716
741
  return (
717
- <div ref={ref} {...htmlProps} className={classNames} data-theme="dark">
718
- {title && <div className={styles.title}>{title}</div>}
719
- <div className={wrapperClasses} style={wrapperStyle}>
742
+ <div ref={ref} {...htmlProps} className={classNames} data-slot="code-block">
743
+ {title && (
744
+ <div className={styles.title} data-slot="code-block-title">
745
+ {title}
746
+ </div>
747
+ )}
748
+ <div className={wrapperClasses} style={wrapperStyle} data-slot="code-block-frame">
720
749
  {shouldRenderHeader && (
721
750
  <div className={styles.header}>
722
751
  <span className={styles.filename}>{filename ?? ""}</span>
@@ -773,11 +802,17 @@ const CodeBlockBase = React.forwardRef<HTMLDivElement, CodeBlockProps>(function
773
802
  <button
774
803
  type="button"
775
804
  onClick={toggleCollapsed}
776
- className={styles.collapseButton}
805
+ className={
806
+ collapseAction === "expand"
807
+ ? `${styles.collapseButton} ${styles.collapseExpand}`
808
+ : styles.collapseButton
809
+ }
777
810
  aria-expanded={!isCollapsed}
778
811
  aria-label={isCollapsed ? "Expand code" : "Collapse code"}
779
812
  >
780
- {isCollapsed ? (
813
+ {collapseAction === "expand" ? (
814
+ <span>{isCollapsed ? "Expand" : "Collapse"}</span>
815
+ ) : isCollapsed ? (
781
816
  <>
782
817
  <ChevronDownIcon className={styles.icon} />
783
818
  <span>Show {totalLines - collapsedLines} more lines</span>
@@ -834,6 +869,14 @@ export interface TabbedCodeBlockProps {
834
869
  wordWrap?: boolean;
835
870
  /** Maximum height in pixels (enables scrolling) */
836
871
  maxHeight?: number;
872
+ /** Allow collapsing/expanding each tab's code (forwarded to every panel) */
873
+ collapsible?: boolean;
874
+ /** Initial collapsed state (only applies when collapsible is true) */
875
+ defaultCollapsed?: boolean;
876
+ /** Number of lines to show when collapsed */
877
+ collapsedLines?: number;
878
+ /** Forwarded to every panel (see CodeBlock `collapseAction`) */
879
+ collapseAction?: "lines" | "expand";
837
880
  /** Additional class name */
838
881
  className?: string;
839
882
  /** Callback fired when a tab's copy button is clicked. Receives the tab label. */
@@ -852,6 +895,10 @@ function TabbedCodeBlock({
852
895
  tabsVariant = "pills",
853
896
  wordWrap,
854
897
  maxHeight,
898
+ collapsible,
899
+ defaultCollapsed,
900
+ collapsedLines,
901
+ collapseAction,
855
902
  className,
856
903
  onCopy,
857
904
  }: TabbedCodeBlockProps) {
@@ -864,28 +911,37 @@ function TabbedCodeBlock({
864
911
  {tabs.map((tab, index) => {
865
912
  const tabValue = tab.value ?? tab.label;
866
913
  return (
867
- <Tab key={`${tabValue}-${index}`} value={tabValue}>
868
- {tab.label}
869
- </Tab>
914
+ <Tab key={`${tabValue}-${index}`} value={tabValue}>
915
+ {tab.label}
916
+ </Tab>
870
917
  );
871
918
  })}
872
919
  </TabsList>
873
920
  {tabs.map((tab, index) => {
874
921
  const tabValue = tab.value ?? tab.label;
875
922
  return (
876
- <TabsPanel key={`${tabValue}-panel-${index}`} value={tabValue} flush className={styles.tabbedPanel}>
877
- <CodeBlockBase
878
- code={tab.code}
879
- language={tab.language}
880
- theme={theme}
881
- showCopy={showCopy}
882
- copyPlacement={copyPlacement}
883
- showLineNumbers={showLineNumbers}
884
- wordWrap={wordWrap}
885
- maxHeight={maxHeight}
886
- onCopy={onCopy ? () => onCopy(tab.label) : undefined}
887
- />
888
- </TabsPanel>
923
+ <TabsPanel
924
+ key={`${tabValue}-panel-${index}`}
925
+ value={tabValue}
926
+ flush
927
+ className={styles.tabbedPanel}
928
+ >
929
+ <CodeBlockBase
930
+ code={tab.code}
931
+ language={tab.language}
932
+ theme={theme}
933
+ showCopy={showCopy}
934
+ copyPlacement={copyPlacement}
935
+ showLineNumbers={showLineNumbers}
936
+ wordWrap={wordWrap}
937
+ maxHeight={maxHeight}
938
+ collapsible={collapsible}
939
+ defaultCollapsed={defaultCollapsed}
940
+ collapsedLines={collapsedLines}
941
+ collapseAction={collapseAction}
942
+ onCopy={onCopy ? () => onCopy(tab.label) : undefined}
943
+ />
944
+ </TabsPanel>
889
945
  );
890
946
  })}
891
947
  </TabsRoot>
@@ -1,15 +1,9 @@
1
1
  {
2
2
  "$schema": "https://usefragments.com/schemas/contract.v1.json",
3
3
  "name": "Collapsible",
4
- "description": "An interactive component that expands/collapses to show or hide content",
4
+ "description": "Shows or hides one region of content behind a trigger.",
5
5
  "category": "layout",
6
- "tags": [
7
- "collapsible",
8
- "expandable",
9
- "accordion",
10
- "disclosure",
11
- "toggle"
12
- ],
6
+ "tags": ["collapsible", "expandable", "accordion", "disclosure", "toggle"],
13
7
  "status": "stable",
14
8
  "sourcePath": "src/components/Collapsible/index.tsx",
15
9
  "exportName": "Collapsible",
@@ -51,22 +45,21 @@
51
45
  },
52
46
  "usage": {
53
47
  "when": [
54
- "Showing/hiding additional content on demand",
55
- "Building accordions or expandable sections",
56
- "Collapsible navigation sections",
57
- "FAQ sections with expandable answers",
58
- "Settings panels with grouped options"
48
+ "Detail most readers do not need",
49
+ "Optional or advanced settings",
50
+ "Navigation sections that fold away",
51
+ "Building a disclosure the other components do not cover"
59
52
  ],
60
53
  "whenNot": [
61
- "Single item disclosure (use Accordion instead)",
62
- "Navigation menus with complex interactions (use Menu)",
63
- "Modal or overlay content (use Dialog or Popover)"
54
+ "Several sections that should coordinate (use Accordion)",
55
+ "Content that must overlay the page (use Dialog or Popover)",
56
+ "Action lists (use Menu)"
64
57
  ],
65
58
  "guidelines": [
66
- "Use clear trigger labels that indicate expandable content",
67
- "Consider defaultOpen for primary content users often need",
68
- "Keep trigger text concise but descriptive",
69
- "Use chevron icons consistently to indicate collapsible state"
59
+ "The trigger should say what opens, not 'click here'",
60
+ "defaultOpen for content most users want on arrival",
61
+ "Keep the trigger to a short phrase",
62
+ "Keep the chevron direction consistent across the page"
70
63
  ],
71
64
  "accessibility": [
72
65
  "Trigger must have aria-expanded to indicate state",
@@ -78,32 +71,32 @@
78
71
  "examples": [
79
72
  {
80
73
  "name": "Default",
81
- "description": "Basic collapsible with trigger and content",
74
+ "description": "Starts closed and opens on click.",
82
75
  "code": "<Collapsible>\n <Collapsible.Trigger>Click to expand</Collapsible.Trigger>\n <Collapsible.Content>\n <p>This content is hidden by default and revealed when the trigger is clicked.</p>\n </Collapsible.Content>\n</Collapsible>"
83
76
  },
84
77
  {
85
78
  "name": "Default Open",
86
- "description": "Collapsible that starts in the expanded state",
79
+ "description": "Starts open for content most users want.",
87
80
  "code": "<Collapsible defaultOpen>\n <Collapsible.Trigger>Section Title</Collapsible.Trigger>\n <Collapsible.Content>\n <p>This content is visible by default. Click the trigger to collapse.</p>\n </Collapsible.Content>\n</Collapsible>"
88
81
  },
89
82
  {
90
83
  "name": "Chevron Start",
91
- "description": "Collapsible with chevron icon on the left",
84
+ "description": "Marker leads the label instead of trailing it.",
92
85
  "code": "<Collapsible>\n <Collapsible.Trigger chevronPosition=\"start\">Navigation</Collapsible.Trigger>\n <Collapsible.Content>\n <ul style={{ margin: 0, paddingLeft: '1.5rem' }}>\n <li>Dashboard</li>\n <li>Settings</li>\n <li>Profile</li>\n </ul>\n </Collapsible.Content>\n</Collapsible>"
93
86
  },
94
87
  {
95
88
  "name": "No Chevron",
96
- "description": "Collapsible without chevron indicator",
89
+ "description": "Bare trigger when the surrounding layout signals enough.",
97
90
  "code": "<Collapsible>\n <Collapsible.Trigger showChevron={false}>Show more details</Collapsible.Trigger>\n <Collapsible.Content>\n <p>Hidden details that appear when triggered.</p>\n </Collapsible.Content>\n</Collapsible>"
98
91
  },
99
92
  {
100
93
  "name": "Disabled",
101
- "description": "Collapsible in disabled state",
94
+ "description": "Locked shut and skipped by the keyboard.",
102
95
  "code": "<Collapsible disabled>\n <Collapsible.Trigger>Cannot toggle (disabled)</Collapsible.Trigger>\n <Collapsible.Content>\n <p>This content cannot be shown because the collapsible is disabled.</p>\n </Collapsible.Content>\n</Collapsible>"
103
96
  },
104
97
  {
105
98
  "name": "Multiple Sections",
106
- "description": "Multiple independent collapsible sections",
99
+ "description": "Independent regions that ignore each other.",
107
100
  "code": "<div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>\n <Collapsible defaultOpen>\n <Collapsible.Trigger>Getting Started</Collapsible.Trigger>\n <Collapsible.Content>\n <p>Introduction and setup instructions.</p>\n </Collapsible.Content>\n </Collapsible>\n <Collapsible>\n <Collapsible.Trigger>Advanced Usage</Collapsible.Trigger>\n <Collapsible.Content>\n <p>Advanced configuration options.</p>\n </Collapsible.Content>\n </Collapsible>\n <Collapsible>\n <Collapsible.Trigger>API Reference</Collapsible.Trigger>\n <Collapsible.Content>\n <p>Complete API documentation.</p>\n </Collapsible.Content>\n </Collapsible>\n</div>"
108
101
  }
109
102
  ],
@@ -131,19 +124,11 @@
131
124
  "onOpenChange: (open: boolean) => void - state change callback",
132
125
  "disabled: boolean - prevents interaction"
133
126
  ],
134
- "a11yRules": [
135
- "A11Y_EXPANDED_STATE",
136
- "A11Y_REGION_LABEL",
137
- "A11Y_KEYBOARD_NAV"
138
- ]
127
+ "a11yRules": ["A11Y_EXPANDED_STATE", "A11Y_REGION_LABEL", "A11Y_KEYBOARD_NAV"]
139
128
  },
140
129
  "ai": {
141
130
  "compositionPattern": "compound",
142
- "subComponents": [
143
- "Root",
144
- "Trigger",
145
- "Content"
146
- ]
131
+ "subComponents": ["Root", "Trigger", "Content"]
147
132
  },
148
133
  "provenance": {
149
134
  "source": "migrated",
@@ -1,16 +1,9 @@
1
1
  {
2
2
  "$schema": "https://usefragments.com/schemas/contract.v1.json",
3
3
  "name": "ColorPicker",
4
- "description": "Color selection control with hex input and visual picker. Displays a swatch that opens a full color picker on click.",
5
- "category": "forms",
6
- "tags": [
7
- "color",
8
- "picker",
9
- "input",
10
- "hex",
11
- "swatch",
12
- "theme"
13
- ],
4
+ "description": "Selects a color through a visual picker and hexadecimal input.",
5
+ "category": "inputs",
6
+ "tags": ["color", "picker", "input", "hex", "swatch", "theme"],
14
7
  "status": "stable",
15
8
  "dependencies": [
16
9
  {
@@ -88,11 +81,7 @@
88
81
  "description": "Size variant",
89
82
  "default": "md",
90
83
  "required": false,
91
- "values": [
92
- "sm",
93
- "md",
94
- "lg"
95
- ]
84
+ "values": ["sm", "md", "lg"]
96
85
  },
97
86
  "showInput": {
98
87
  "type": "boolean",
@@ -103,68 +92,67 @@
103
92
  },
104
93
  "usage": {
105
94
  "when": [
106
- "Theme customization interfaces",
107
- "Brand color selection",
108
- "Design tool color inputs",
109
- "User preference settings for colors"
95
+ "Theme and brand customisation",
96
+ "Any colour the user must pick freely",
97
+ "Design tool inputs"
110
98
  ],
111
99
  "whenNot": [
112
- "Predefined color options only (use RadioGroup with swatches)",
113
- "Simple color display without editing (use a colored Badge)",
114
- "Color indication only (use semantic color tokens)"
100
+ "A fixed palette (use RadioGroup with swatches)",
101
+ "Showing a colour without editing it (use a tinted Badge)",
102
+ "Status colour that should come from a token"
115
103
  ],
116
104
  "guidelines": [
117
- "Always provide a label to describe what the color is for",
118
- "Use helperText to explain color usage or constraints",
119
- "Consider providing color presets alongside the picker for common choices",
120
- "Validate hex format (#RRGGBB) on input"
105
+ "Label says what the colour is for",
106
+ "Use helperText for constraints, such as contrast rules",
107
+ "Offer presets next to the picker for the common choices",
108
+ "Validate the hex as #RRGGBB before accepting it"
121
109
  ],
122
110
  "accessibility": [
123
- "Label is associated with the color input",
124
- "Swatch button has appropriate aria-label",
125
- "Color picker popup is keyboard accessible",
126
- "Hex input allows direct text entry"
111
+ "Label is tied to the hex input",
112
+ "The swatch button carries its own aria-label",
113
+ "The picker popup is reachable from the keyboard",
114
+ "Users can type a hex instead of dragging"
127
115
  ]
128
116
  },
129
117
  "examples": [
130
118
  {
131
119
  "name": "Default",
132
- "description": "Basic color picker with label",
120
+ "description": "Swatch opens the picker; the hex field accepts typing.",
133
121
  "code": "<ColorPicker\n label=\"Brand Color\"\n defaultValue=\"#3b82f6\"\n/>"
134
122
  },
135
123
  {
136
124
  "name": "With Helper Text",
137
- "description": "Color picker with helper text",
125
+ "description": "Supporting line says where the colour will be used.",
138
126
  "code": "<ColorPicker\n label=\"Primary Color\"\n defaultValue=\"#10b981\"\n helperText=\"This color will be used for buttons and links\"\n/>"
139
127
  },
140
128
  {
141
129
  "name": "Controlled",
142
- "description": "Controlled color picker that logs changes",
130
+ "description": "The parent owns the value and sees every change.",
143
131
  "code": "<ControlledColorPickerDemo />"
144
132
  },
145
133
  {
146
134
  "name": "Multiple Pickers",
147
- "description": "Multiple color pickers for theme configuration",
135
+ "description": "A stacked set reads as one palette.",
148
136
  "code": "<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '240px' }}>\n <ColorPicker label=\"Primary\" defaultValue=\"#3b82f6\" />\n <ColorPicker label=\"Success\" defaultValue=\"#22c55e\" />\n <ColorPicker label=\"Warning\" defaultValue=\"#f59e0b\" />\n <ColorPicker label=\"Danger\" defaultValue=\"#ef4444\" />\n</div>"
149
137
  },
150
138
  {
151
139
  "name": "Compact",
152
- "description": "Small size with swatch only (no input)",
140
+ "description": "showInput={false} drops the hex field, leaving a swatch row.",
153
141
  "code": "<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>\n <ColorPicker defaultValue=\"#ef4444\" size=\"sm\" showInput={false} />\n <ColorPicker defaultValue=\"#f59e0b\" size=\"sm\" showInput={false} />\n <ColorPicker defaultValue=\"#22c55e\" size=\"sm\" showInput={false} />\n <ColorPicker defaultValue=\"#3b82f6\" size=\"sm\" showInput={false} />\n</div>"
154
142
  },
155
143
  {
156
144
  "name": "Sizes",
157
- "description": "Different size variants",
145
+ "description": "Three swatch sizes: sm, md, lg.",
158
146
  "code": "<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '240px' }}>\n <ColorPicker label=\"Small\" defaultValue=\"#3b82f6\" size=\"sm\" />\n <ColorPicker label=\"Medium (default)\" defaultValue=\"#3b82f6\" size=\"md\" />\n <ColorPicker label=\"Large\" defaultValue=\"#3b82f6\" size=\"lg\" />\n</div>"
159
147
  },
160
148
  {
161
149
  "name": "Error State",
162
- "description": "Color picker with error styling",
163
- "code": "<ColorPicker\n label=\"Brand Color\"\n defaultValue=\"#000000\"\n error\n helperText=\"Please select a valid brand color\"\n/>"
150
+ "description": "Red border on the hex field, and the reason below it.",
151
+ "code": "<ColorPicker\n label=\"Brand Color\"\n defaultValue=\"#7c3aed\"\n error\n helperText=\"This color fails contrast against the page background\"\n/>"
164
152
  },
165
153
  {
166
154
  "name": "Disabled",
167
- "description": "Disabled color picker",
155
+ "description": "Swatch will not open and the hex field will not accept typing.",
168
156
  "code": "<ColorPicker\n label=\"Locked Color\"\n defaultValue=\"#64748b\"\n helperText=\"This color cannot be changed\"\n disabled\n/>"
169
157
  }
170
158
  ],
@@ -198,18 +186,11 @@
198
186
  "size: sm|md|lg - size variant",
199
187
  "showInput: boolean - show hex input field"
200
188
  ],
201
- "a11yRules": [
202
- "A11Y_LABEL_REQUIRED",
203
- "A11Y_FOCUS_VISIBLE",
204
- "A11Y_TARGET_SIZE_MIN"
205
- ]
189
+ "a11yRules": ["A11Y_LABEL_REQUIRED", "A11Y_FOCUS_VISIBLE", "A11Y_TARGET_SIZE_MIN"]
206
190
  },
207
191
  "ai": {
208
192
  "compositionPattern": "compound",
209
- "subComponents": [
210
- "Root",
211
- "preload"
212
- ]
193
+ "subComponents": ["Root", "preload"]
213
194
  },
214
195
  "provenance": {
215
196
  "source": "migrated",
@@ -1,14 +1,19 @@
1
- @use '../../tokens/variables' as *;
2
- @use '../../tokens/mixins' as *;
3
- @use '../../recipes/action';
4
- @use '../../recipes/field';
5
- @use '../../recipes/popup';
6
-
7
- // Local component tokens
1
+ @use "../../tokens/variables" as *;
2
+ @use "../../tokens/mixins" as *;
3
+ @use "../../recipes/action";
4
+ @use "../../recipes/field";
5
+ @use "../../recipes/popup";
6
+
7
+ // Local component tokens.
8
+ //
9
+ // The raw pixel values in this file (200px here, and the 80px/120px hex-input
10
+ // min-widths below) are deliberate, not missed tokens: react-colorful lays the
11
+ // saturation/hue canvas out in fixed pixels, and the hex field has to stay wide
12
+ // enough for a full "#rrggbb" string. Spacing tokens do not map onto either
13
+ // constraint, so these stay literal.
8
14
  $fui-colorpicker-size: 200px !default; // react-colorful saturation/hue square
9
15
  $fui-colorpicker-hue-height: $fui-target-size-min !default;
10
16
  $fui-colorpicker-pointer-size: $fui-target-size-min !default;
11
- $fui-colorpicker-pointer-border: 2px !default;
12
17
 
13
18
  .wrapper {
14
19
  @include field.wrapper;
@@ -44,7 +49,6 @@ $fui-colorpicker-pointer-border: 2px !default;
44
49
  min-width: 80px;
45
50
  flex: 0 0 auto;
46
51
  }
47
-
48
52
  }
49
53
 
50
54
  .sizeMd {
@@ -75,7 +79,6 @@ $fui-colorpicker-pointer-border: 2px !default;
75
79
  .hexInput {
76
80
  min-width: 120px;
77
81
  }
78
-
79
82
  }
80
83
 
81
84
  .inputWrapper {
@@ -133,7 +136,7 @@ $fui-colorpicker-pointer-border: 2px !default;
133
136
  :global(.react-colorful__pointer) {
134
137
  width: var(--fui-colorpicker-pointer-size, #{$fui-colorpicker-pointer-size});
135
138
  height: var(--fui-colorpicker-pointer-size, #{$fui-colorpicker-pointer-size});
136
- border: $fui-colorpicker-pointer-border solid var(--fui-text-inverse, $fui-text-inverse);
139
+ border: var(--fui-stroke-default, 2px) solid var(--fui-text-inverse, $fui-text-inverse);
137
140
  box-shadow: var(--fui-shadow-md, $fui-shadow-md);
138
141
  }
139
142
  }
@@ -144,7 +147,7 @@ $fui-colorpicker-pointer-border: 2px !default;
144
147
 
145
148
  @media (prefers-contrast: more) {
146
149
  .swatch {
147
- border-width: 2px;
150
+ border-width: var(--fui-stroke-default, 2px);
148
151
  border-color: var(--fui-text-primary, $fui-text-primary);
149
152
  }
150
153
  }
@@ -25,7 +25,7 @@ function loadColorfulDeps(): Promise<void> {
25
25
  _HexColorPicker = rc.HexColorPicker;
26
26
  } catch {
27
27
  _colorfulFailed = true;
28
- if (process.env.NODE_ENV === "development") {
28
+ if (isDevelopmentBuild()) {
29
29
  console.warn(
30
30
  "[@usefragments/ui] ColorPicker: react-colorful is not installed. " +
31
31
  "Install it with: npm install react-colorful"
@@ -55,6 +55,7 @@ import { Field } from "@base-ui/react/field";
55
55
  import { useResolvedControlSize } from "../ComponentDefaults";
56
56
  import { Input } from "../Input";
57
57
  import styles from "./ColorPicker.module.scss";
58
+ import { isDevelopmentBuild } from "../../utils/env";
58
59
 
59
60
  export interface ColorPickerProps extends Omit<
60
61
  React.HTMLAttributes<HTMLDivElement>,
@@ -192,6 +193,9 @@ const ColorPickerRoot = React.forwardRef<HTMLDivElement, ColorPickerProps>(funct
192
193
  onChange={handleInputChange}
193
194
  onBlur={handleInputBlur}
194
195
  disabled={disabled}
196
+ // Without this the hex field keeps its neutral border while the
197
+ // helper text turns red, so the error reads as a stray message.
198
+ error={error}
195
199
  size={size}
196
200
  className={styles.hexInput}
197
201
  inputClassName={styles.hexInputField}