@usefragments/ui 1.0.2 → 1.2.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 (326) hide show
  1. package/README.md +16 -16
  2. package/dist/assets/fragments-wordmark.cjs +30 -0
  3. package/dist/assets/fragments-wordmark.d.ts +13 -0
  4. package/dist/assets/fragments-wordmark.d.ts.map +1 -0
  5. package/dist/assets/fragments-wordmark.js +30 -0
  6. package/dist/assets/ui.css +3234 -3116
  7. package/dist/components/Accordion/Accordion.module.scss.cjs +8 -8
  8. package/dist/components/Accordion/Accordion.module.scss.js +8 -8
  9. package/dist/components/Accordion/index.cjs +22 -10
  10. package/dist/components/Accordion/index.d.ts.map +1 -1
  11. package/dist/components/Accordion/index.js +22 -10
  12. package/dist/components/Alert/Alert.module.scss.cjs +13 -13
  13. package/dist/components/Alert/Alert.module.scss.js +13 -13
  14. package/dist/components/AppShell/AppShell.module.scss.cjs +22 -10
  15. package/dist/components/AppShell/AppShell.module.scss.js +22 -10
  16. package/dist/components/AppShell/index.cjs +1 -1
  17. package/dist/components/AppShell/index.js +1 -1
  18. package/dist/components/Avatar/Avatar.module.scss.cjs +13 -13
  19. package/dist/components/Avatar/Avatar.module.scss.js +13 -13
  20. package/dist/components/Badge/Badge.module.scss.cjs +16 -16
  21. package/dist/components/Badge/Badge.module.scss.js +16 -16
  22. package/dist/components/BentoGrid/BentoGrid.module.scss.cjs +14 -14
  23. package/dist/components/BentoGrid/BentoGrid.module.scss.js +14 -14
  24. package/dist/components/Box/Box.module.scss.cjs +152 -152
  25. package/dist/components/Box/Box.module.scss.js +152 -152
  26. package/dist/components/Breadcrumbs/Breadcrumbs.module.scss.cjs +8 -8
  27. package/dist/components/Breadcrumbs/Breadcrumbs.module.scss.js +8 -8
  28. package/dist/components/Button/Button.module.scss.cjs +13 -13
  29. package/dist/components/Button/Button.module.scss.js +13 -13
  30. package/dist/components/Card/Card.module.scss.cjs +17 -17
  31. package/dist/components/Card/Card.module.scss.js +17 -17
  32. package/dist/components/Card/index.d.ts +3 -3
  33. package/dist/components/Card/index.d.ts.map +1 -1
  34. package/dist/components/Chart/Chart.module.scss.cjs +15 -15
  35. package/dist/components/Chart/Chart.module.scss.js +15 -15
  36. package/dist/components/Checkbox/Checkbox.module.scss.cjs +11 -11
  37. package/dist/components/Checkbox/Checkbox.module.scss.js +11 -11
  38. package/dist/components/Chip/Chip.module.scss.cjs +15 -15
  39. package/dist/components/Chip/Chip.module.scss.js +15 -15
  40. package/dist/components/CodeBlock/CodeBlock.module.scss.cjs +21 -21
  41. package/dist/components/CodeBlock/CodeBlock.module.scss.js +21 -21
  42. package/dist/components/Collapsible/Collapsible.module.scss.cjs +10 -10
  43. package/dist/components/Collapsible/Collapsible.module.scss.js +10 -10
  44. package/dist/components/ColorPicker/ColorPicker.module.scss.cjs +14 -14
  45. package/dist/components/ColorPicker/ColorPicker.module.scss.js +14 -14
  46. package/dist/components/Combobox/Combobox.module.scss.cjs +23 -23
  47. package/dist/components/Combobox/Combobox.module.scss.js +23 -23
  48. package/dist/components/Combobox/index.cjs +106 -9
  49. package/dist/components/Combobox/index.d.ts.map +1 -1
  50. package/dist/components/Combobox/index.js +106 -9
  51. package/dist/components/Command/Command.module.scss.cjs +11 -11
  52. package/dist/components/Command/Command.module.scss.js +11 -11
  53. package/dist/components/ConversationList/ConversationList.module.scss.cjs +10 -10
  54. package/dist/components/ConversationList/ConversationList.module.scss.js +10 -10
  55. package/dist/components/DataTable/DataTable.module.scss.cjs +37 -34
  56. package/dist/components/DataTable/DataTable.module.scss.js +37 -34
  57. package/dist/components/DataTable/index.d.ts +3 -1
  58. package/dist/components/DataTable/index.d.ts.map +1 -1
  59. package/dist/components/DatePicker/DatePicker.module.scss.cjs +33 -33
  60. package/dist/components/DatePicker/DatePicker.module.scss.js +33 -33
  61. package/dist/components/DatePicker/index.d.ts +1 -1
  62. package/dist/components/DatePicker/index.d.ts.map +1 -1
  63. package/dist/components/Dialog/Dialog.module.scss.cjs +14 -14
  64. package/dist/components/Dialog/Dialog.module.scss.js +14 -14
  65. package/dist/components/Drawer/Drawer.module.scss.cjs +28 -28
  66. package/dist/components/Drawer/Drawer.module.scss.js +28 -28
  67. package/dist/components/Drawer/index.cjs +20 -3
  68. package/dist/components/Drawer/index.d.ts.map +1 -1
  69. package/dist/components/Drawer/index.js +20 -3
  70. package/dist/components/Editor/Editor.module.scss.cjs +17 -17
  71. package/dist/components/Editor/Editor.module.scss.js +17 -17
  72. package/dist/components/EmptyState/EmptyState.module.scss.cjs +8 -8
  73. package/dist/components/EmptyState/EmptyState.module.scss.js +8 -8
  74. package/dist/components/Field/Field.module.scss.cjs +4 -4
  75. package/dist/components/Field/Field.module.scss.js +4 -4
  76. package/dist/components/Field/index.cjs +10 -9
  77. package/dist/components/Field/index.d.ts +7 -7
  78. package/dist/components/Field/index.d.ts.map +1 -1
  79. package/dist/components/Field/index.js +10 -9
  80. package/dist/components/Fieldset/Fieldset.module.scss.cjs +3 -3
  81. package/dist/components/Fieldset/Fieldset.module.scss.js +3 -3
  82. package/dist/components/Header/Header.module.scss.cjs +44 -29
  83. package/dist/components/Header/Header.module.scss.js +44 -29
  84. package/dist/components/Header/index.cjs +56 -3
  85. package/dist/components/Header/index.d.ts +25 -3
  86. package/dist/components/Header/index.d.ts.map +1 -1
  87. package/dist/components/Header/index.js +56 -3
  88. package/dist/components/Icon/Icon.module.scss.cjs +8 -8
  89. package/dist/components/Icon/Icon.module.scss.js +8 -8
  90. package/dist/components/IconButton/IconButton.module.scss.cjs +8 -8
  91. package/dist/components/IconButton/IconButton.module.scss.js +8 -8
  92. package/dist/components/Image/Image.module.scss.cjs +27 -27
  93. package/dist/components/Image/Image.module.scss.js +27 -27
  94. package/dist/components/Input/Input.module.scss.cjs +19 -19
  95. package/dist/components/Input/Input.module.scss.js +19 -19
  96. package/dist/components/Link/Link.module.scss.cjs +10 -10
  97. package/dist/components/Link/Link.module.scss.js +10 -10
  98. package/dist/components/List/List.module.scss.cjs +19 -19
  99. package/dist/components/List/List.module.scss.js +19 -19
  100. package/dist/components/Listbox/Listbox.module.scss.cjs +8 -8
  101. package/dist/components/Listbox/Listbox.module.scss.js +8 -8
  102. package/dist/components/Loading/Loading.module.scss.cjs +30 -30
  103. package/dist/components/Loading/Loading.module.scss.js +30 -30
  104. package/dist/components/Main/Main.module.scss.cjs +26 -0
  105. package/dist/components/Main/Main.module.scss.js +26 -0
  106. package/dist/components/Main/index.cjs +128 -0
  107. package/dist/components/Main/index.d.ts +22 -0
  108. package/dist/components/Main/index.d.ts.map +1 -0
  109. package/dist/components/Main/index.js +111 -0
  110. package/dist/components/Markdown/Markdown.module.scss.cjs +1 -1
  111. package/dist/components/Markdown/Markdown.module.scss.js +1 -1
  112. package/dist/components/Menu/Menu.module.scss.cjs +14 -14
  113. package/dist/components/Menu/Menu.module.scss.js +14 -14
  114. package/dist/components/Message/Message.module.scss.cjs +18 -18
  115. package/dist/components/Message/Message.module.scss.js +18 -18
  116. package/dist/components/NavigationMenu/NavigationMenu.module.scss.cjs +28 -28
  117. package/dist/components/NavigationMenu/NavigationMenu.module.scss.js +28 -28
  118. package/dist/components/Pagination/Pagination.module.scss.cjs +7 -7
  119. package/dist/components/Pagination/Pagination.module.scss.js +7 -7
  120. package/dist/components/Popover/Popover.module.scss.cjs +10 -10
  121. package/dist/components/Popover/Popover.module.scss.js +10 -10
  122. package/dist/components/Popover/index.cjs +27 -2
  123. package/dist/components/Popover/index.d.ts.map +1 -1
  124. package/dist/components/Popover/index.js +27 -2
  125. package/dist/components/Progress/Progress.module.scss.cjs +25 -25
  126. package/dist/components/Progress/Progress.module.scss.js +25 -25
  127. package/dist/components/Prompt/Prompt.module.scss.cjs +18 -18
  128. package/dist/components/Prompt/Prompt.module.scss.js +18 -18
  129. package/dist/components/RadioGroup/RadioGroup.module.scss.cjs +17 -17
  130. package/dist/components/RadioGroup/RadioGroup.module.scss.js +17 -17
  131. package/dist/components/RadioGroup/index.cjs +2 -0
  132. package/dist/components/RadioGroup/index.d.ts +2 -0
  133. package/dist/components/RadioGroup/index.d.ts.map +1 -1
  134. package/dist/components/RadioGroup/index.js +2 -0
  135. package/dist/components/ScrollArea/ScrollArea.module.scss.cjs +10 -10
  136. package/dist/components/ScrollArea/ScrollArea.module.scss.js +10 -10
  137. package/dist/components/Select/Select.module.scss.cjs +17 -17
  138. package/dist/components/Select/Select.module.scss.js +17 -17
  139. package/dist/components/Separator/Separator.module.scss.cjs +10 -10
  140. package/dist/components/Separator/Separator.module.scss.js +10 -10
  141. package/dist/components/Sidebar/Sidebar.module.scss.cjs +42 -42
  142. package/dist/components/Sidebar/Sidebar.module.scss.js +42 -42
  143. package/dist/components/Skeleton/Skeleton.module.scss.cjs +38 -38
  144. package/dist/components/Skeleton/Skeleton.module.scss.js +38 -38
  145. package/dist/components/Slider/Slider.module.scss.cjs +12 -12
  146. package/dist/components/Slider/Slider.module.scss.js +12 -12
  147. package/dist/components/Table/Table.module.scss.cjs +19 -19
  148. package/dist/components/Table/Table.module.scss.js +19 -19
  149. package/dist/components/TableOfContents/TableOfContents.module.scss.cjs +15 -15
  150. package/dist/components/TableOfContents/TableOfContents.module.scss.js +15 -15
  151. package/dist/components/TableOfContents/index.cjs +22 -42
  152. package/dist/components/TableOfContents/index.d.ts +3 -3
  153. package/dist/components/TableOfContents/index.d.ts.map +1 -1
  154. package/dist/components/TableOfContents/index.js +22 -42
  155. package/dist/components/Tabs/Tabs.module.scss.cjs +12 -12
  156. package/dist/components/Tabs/Tabs.module.scss.js +12 -12
  157. package/dist/components/Text/Text.module.scss.cjs +51 -51
  158. package/dist/components/Text/Text.module.scss.js +51 -51
  159. package/dist/components/Textarea/Textarea.module.scss.cjs +23 -23
  160. package/dist/components/Textarea/Textarea.module.scss.js +23 -23
  161. package/dist/components/Theme/ThemeToggle.module.scss.cjs +6 -6
  162. package/dist/components/Theme/ThemeToggle.module.scss.js +6 -6
  163. package/dist/components/ThinkingIndicator/ThinkingIndicator.module.scss.cjs +13 -13
  164. package/dist/components/ThinkingIndicator/ThinkingIndicator.module.scss.js +13 -13
  165. package/dist/components/Toast/Toast.module.scss.cjs +21 -21
  166. package/dist/components/Toast/Toast.module.scss.js +21 -21
  167. package/dist/components/Toggle/Toggle.module.scss.cjs +13 -13
  168. package/dist/components/Toggle/Toggle.module.scss.js +13 -13
  169. package/dist/components/ToggleGroup/ToggleGroup.module.scss.cjs +17 -17
  170. package/dist/components/ToggleGroup/ToggleGroup.module.scss.js +17 -17
  171. package/dist/components/Tooltip/Tooltip.module.scss.cjs +3 -3
  172. package/dist/components/Tooltip/Tooltip.module.scss.js +3 -3
  173. package/dist/data-table.cjs +58 -41
  174. package/dist/data-table.js +59 -41
  175. package/dist/datepicker.cjs +32 -72
  176. package/dist/datepicker.js +32 -72
  177. package/dist/index.cjs +89 -85
  178. package/dist/index.d.ts +2 -0
  179. package/dist/index.d.ts.map +1 -1
  180. package/dist/index.js +4 -0
  181. package/fragments.json +1 -1
  182. package/package.json +9 -8
  183. package/src/assets/fragments-wordmark.tsx +47 -0
  184. package/src/components/Accordion/index.tsx +13 -3
  185. package/src/components/Alert/Alert.module.scss +15 -2
  186. package/src/components/AppShell/AppShell.module.scss +73 -15
  187. package/src/components/AppShell/index.tsx +1 -1
  188. package/src/components/Button/Button.module.scss +19 -20
  189. package/src/components/Card/Card.module.scss +3 -3
  190. package/src/components/Card/index.tsx +3 -3
  191. package/src/components/Checkbox/Checkbox.contract.json +5 -24
  192. package/src/components/Checkbox/Checkbox.module.scss +4 -2
  193. package/src/components/Chip/Chip.contract.json +11 -28
  194. package/src/components/Chip/Chip.module.scss +21 -45
  195. package/src/components/CodeBlock/CodeBlock.module.scss +2 -7
  196. package/src/components/Combobox/Combobox.contract.json +6 -24
  197. package/src/components/Combobox/Combobox.module.scss +3 -2
  198. package/src/components/Combobox/index.tsx +132 -6
  199. package/src/components/DataTable/DataTable.contract.json +16 -23
  200. package/src/components/DataTable/DataTable.module.scss +31 -8
  201. package/src/components/DataTable/index.tsx +25 -4
  202. package/src/components/DatePicker/index.tsx +32 -84
  203. package/src/components/Drawer/index.tsx +38 -12
  204. package/src/components/Field/index.tsx +35 -35
  205. package/src/components/Header/Header.contract.json +41 -1
  206. package/src/components/Header/Header.module.scss +40 -0
  207. package/src/components/Header/index.tsx +88 -2
  208. package/src/components/IconButton/IconButton.contract.json +120 -0
  209. package/src/components/Listbox/Listbox.module.scss +5 -4
  210. package/src/components/Main/Main.contract.json +79 -0
  211. package/src/components/Main/Main.module.scss +31 -0
  212. package/src/components/Main/index.tsx +124 -0
  213. package/src/components/Menu/Menu.module.scss +8 -10
  214. package/src/components/Popover/index.tsx +34 -2
  215. package/src/components/RadioGroup/RadioGroup.contract.json +13 -27
  216. package/src/components/RadioGroup/index.tsx +4 -0
  217. package/src/components/Select/Select.module.scss +13 -12
  218. package/src/components/Table/Table.module.scss +22 -5
  219. package/src/components/TableOfContents/TableOfContents.contract.json +6 -16
  220. package/src/components/TableOfContents/TableOfContents.module.scss +20 -14
  221. package/src/components/TableOfContents/index.tsx +27 -38
  222. package/src/components/Toast/Toast.module.scss +15 -2
  223. package/src/components/ToggleGroup/ToggleGroup.module.scss +4 -1
  224. package/src/index.ts +4 -0
  225. package/src/styles/globals.scss +13 -10
  226. package/src/tokens/_component-properties.scss +26 -0
  227. package/src/tokens/_computed.scss +22 -4
  228. package/src/tokens/_derive.scss +55 -6
  229. package/src/tokens/_palettes.scss +24 -0
  230. package/src/tokens/_seeds.scss +20 -12
  231. package/src/tokens/_variables.scss +110 -63
  232. package/dist/components/Cloud/DashboardLayoutPrototypes.shared.d.ts +0 -33
  233. package/dist/components/Cloud/DashboardLayoutPrototypes.shared.d.ts.map +0 -1
  234. package/dist/components/Cloud/DashboardLayoutPrototypes.shell.d.ts +0 -11
  235. package/dist/components/Cloud/DashboardLayoutPrototypes.shell.d.ts.map +0 -1
  236. package/dist/components/Cloud/PullRequestsPrototypes.content.d.ts +0 -5
  237. package/dist/components/Cloud/PullRequestsPrototypes.content.d.ts.map +0 -1
  238. package/dist/components/Cloud/PullRequestsPrototypes.detail-panels.d.ts +0 -4
  239. package/dist/components/Cloud/PullRequestsPrototypes.detail-panels.d.ts.map +0 -1
  240. package/dist/components/Cloud/PullRequestsPrototypes.detail.d.ts +0 -3
  241. package/dist/components/Cloud/PullRequestsPrototypes.detail.d.ts.map +0 -1
  242. package/dist/components/Cloud/PullRequestsPrototypes.id-data.d.ts +0 -86
  243. package/dist/components/Cloud/PullRequestsPrototypes.id-data.d.ts.map +0 -1
  244. package/dist/components/Cloud/PullRequestsPrototypes.id-page.d.ts +0 -2
  245. package/dist/components/Cloud/PullRequestsPrototypes.id-page.d.ts.map +0 -1
  246. package/src/components/Accordion/Accordion.stories.tsx +0 -106
  247. package/src/components/Alert/Alert.stories.tsx +0 -119
  248. package/src/components/AppShell/AppShell.stories.tsx +0 -156
  249. package/src/components/Avatar/Avatar.stories.tsx +0 -74
  250. package/src/components/Badge/Badge.stories.tsx +0 -92
  251. package/src/components/BentoGrid/BentoGrid.stories.tsx +0 -98
  252. package/src/components/Box/Box.stories.tsx +0 -150
  253. package/src/components/Breadcrumbs/Breadcrumbs.stories.tsx +0 -87
  254. package/src/components/Button/Button.stories.tsx +0 -103
  255. package/src/components/ButtonGroup/ButtonGroup.stories.tsx +0 -97
  256. package/src/components/Card/Card.stories.tsx +0 -144
  257. package/src/components/Chart/Chart.stories.tsx +0 -119
  258. package/src/components/Checkbox/Checkbox.stories.tsx +0 -68
  259. package/src/components/Chip/Chip.stories.tsx +0 -70
  260. package/src/components/Cloud/CloudGovernanceShell.module.scss +0 -88
  261. package/src/components/Cloud/CloudGovernanceShell.stories.tsx +0 -446
  262. package/src/components/Cloud/ControlSizing.module.scss +0 -49
  263. package/src/components/Cloud/ControlSizing.stories.tsx +0 -238
  264. package/src/components/Cloud/DashboardLayoutPrototypes.module.scss +0 -462
  265. package/src/components/Cloud/DashboardLayoutPrototypes.shared.tsx +0 -375
  266. package/src/components/Cloud/DashboardLayoutPrototypes.shell.tsx +0 -147
  267. package/src/components/Cloud/DashboardLayoutPrototypes.stories.tsx +0 -328
  268. package/src/components/Cloud/PullRequestsPrototypes.content.tsx +0 -283
  269. package/src/components/Cloud/PullRequestsPrototypes.detail-panels.tsx +0 -381
  270. package/src/components/Cloud/PullRequestsPrototypes.detail.tsx +0 -204
  271. package/src/components/Cloud/PullRequestsPrototypes.id-data.ts +0 -395
  272. package/src/components/Cloud/PullRequestsPrototypes.id-page.tsx +0 -349
  273. package/src/components/Cloud/PullRequestsPrototypes.stories.tsx +0 -81
  274. package/src/components/CodeBlock/CodeBlock.stories.tsx +0 -147
  275. package/src/components/Collapsible/Collapsible.stories.tsx +0 -94
  276. package/src/components/ColorPicker/ColorPicker.stories.tsx +0 -74
  277. package/src/components/Combobox/Combobox.stories.tsx +0 -133
  278. package/src/components/Command/Command.stories.tsx +0 -102
  279. package/src/components/ConversationList/ConversationList.stories.tsx +0 -93
  280. package/src/components/DataTable/DataTable.stories.tsx +0 -129
  281. package/src/components/DatePicker/DatePicker.stories.tsx +0 -129
  282. package/src/components/Dialog/Dialog.stories.tsx +0 -154
  283. package/src/components/Drawer/Drawer.stories.tsx +0 -144
  284. package/src/components/Editor/Editor.stories.tsx +0 -99
  285. package/src/components/EmptyState/EmptyState.stories.tsx +0 -97
  286. package/src/components/Field/Field.stories.tsx +0 -109
  287. package/src/components/Fieldset/Fieldset.stories.tsx +0 -116
  288. package/src/components/Form/Form.stories.tsx +0 -142
  289. package/src/components/Grid/Grid.stories.tsx +0 -125
  290. package/src/components/Header/Header.stories.tsx +0 -133
  291. package/src/components/Icon/Icon.stories.tsx +0 -80
  292. package/src/components/IconButton/IconButton.stories.tsx +0 -78
  293. package/src/components/Image/Image.stories.tsx +0 -109
  294. package/src/components/Input/Input.stories.tsx +0 -104
  295. package/src/components/Link/Link.stories.tsx +0 -67
  296. package/src/components/List/List.stories.tsx +0 -95
  297. package/src/components/Listbox/Listbox.stories.tsx +0 -81
  298. package/src/components/Loading/Loading.stories.tsx +0 -69
  299. package/src/components/Markdown/Markdown.stories.tsx +0 -75
  300. package/src/components/Menu/Menu.stories.tsx +0 -113
  301. package/src/components/Message/Message.stories.tsx +0 -85
  302. package/src/components/NavigationMenu/NavigationMenu.stories.tsx +0 -161
  303. package/src/components/Pagination/Pagination.stories.tsx +0 -81
  304. package/src/components/Popover/Popover.stories.tsx +0 -152
  305. package/src/components/Progress/Progress.stories.tsx +0 -64
  306. package/src/components/Prompt/Prompt.stories.tsx +0 -93
  307. package/src/components/RadioGroup/RadioGroup.stories.tsx +0 -107
  308. package/src/components/ScrollArea/ScrollArea.stories.tsx +0 -97
  309. package/src/components/Select/Select.stories.tsx +0 -127
  310. package/src/components/Separator/Separator.stories.tsx +0 -84
  311. package/src/components/Sidebar/Sidebar.stories.tsx +0 -122
  312. package/src/components/Skeleton/Skeleton.stories.tsx +0 -80
  313. package/src/components/Slider/Slider.stories.tsx +0 -73
  314. package/src/components/Stack/Stack.stories.tsx +0 -73
  315. package/src/components/Switch/Switch.stories.tsx +0 -59
  316. package/src/components/Table/Table.stories.tsx +0 -219
  317. package/src/components/TableOfContents/TableOfContents.stories.tsx +0 -120
  318. package/src/components/Tabs/Tabs.stories.tsx +0 -136
  319. package/src/components/Text/Text.stories.tsx +0 -133
  320. package/src/components/Textarea/Textarea.stories.tsx +0 -107
  321. package/src/components/Theme/Theme.stories.tsx +0 -95
  322. package/src/components/ThinkingIndicator/ThinkingIndicator.stories.tsx +0 -85
  323. package/src/components/Toast/Toast.stories.tsx +0 -91
  324. package/src/components/ToggleGroup/ToggleGroup.stories.tsx +0 -114
  325. package/src/components/Tooltip/Tooltip.stories.tsx +0 -95
  326. package/src/components/VisuallyHidden/VisuallyHidden.stories.tsx +0 -78
@@ -82,6 +82,8 @@ export interface DataTableProps<T> extends Omit<React.HTMLAttributes<HTMLTableEl
82
82
  onRowSelectionChange?: OnChangeFn<RowSelectionState>;
83
83
  /** Row click handler */
84
84
  onRowClick?: (row: T, event: DataTableRowClickEvent) => void;
85
+ /** Props applied to each rendered data row. Use this for row-level ARIA labels, roles, and data attributes. */
86
+ getRowProps?: (row: T) => React.HTMLAttributes<HTMLTableRowElement>;
85
87
  /** Extract sub-rows from a row for expandable tree tables */
86
88
  getSubRows?: (row: T) => T[] | undefined;
87
89
  /** Controlled expanded state */
@@ -143,7 +145,11 @@ function isInteractiveTarget(target: EventTarget | null, currentTarget: HTMLTabl
143
145
  'button, a, input, select, textarea, [role="button"], [role="link"], [role="checkbox"], [role="switch"]'
144
146
  );
145
147
 
146
- return Boolean(interactiveElement && currentTarget.contains(interactiveElement));
148
+ return Boolean(
149
+ interactiveElement &&
150
+ interactiveElement !== currentTarget &&
151
+ currentTarget.contains(interactiveElement)
152
+ );
147
153
  }
148
154
 
149
155
  function DataTableRoot<T>({
@@ -158,6 +164,7 @@ function DataTableRoot<T>({
158
164
  rowSelection: controlledRowSelection,
159
165
  onRowSelectionChange,
160
166
  onRowClick,
167
+ getRowProps,
161
168
  getSubRows,
162
169
  expanded: controlledExpanded,
163
170
  onExpandedChange,
@@ -411,13 +418,25 @@ function DataTableRoot<T>({
411
418
  const isSelected = selectable ? row.getIsSelected() : false;
412
419
  const depth: number = row.depth ?? 0;
413
420
  const canExpand = hasSubRows && row.getCanExpand();
421
+ const resolvedRowProps = getRowProps?.(row.original) ?? {};
422
+ const {
423
+ className: rowClassName,
424
+ onClick: rowOnClick,
425
+ onKeyDown: rowOnKeyDown,
426
+ tabIndex: rowTabIndex,
427
+ ...rowHtmlProps
428
+ } = resolvedRowProps;
414
429
  const handleRowClick = (event: React.MouseEvent<HTMLTableRowElement>) => {
430
+ rowOnClick?.(event);
431
+ if (event.defaultPrevented) return;
415
432
  if (!onRowClick) return;
416
433
  if (isInteractiveTarget(event.target, event.currentTarget)) return;
417
434
  onRowClick(row.original, event);
418
435
  };
419
436
 
420
437
  const handleRowKeyDown = (event: React.KeyboardEvent<HTMLTableRowElement>) => {
438
+ rowOnKeyDown?.(event);
439
+ if (event.defaultPrevented) return;
421
440
  if (!onRowClick) return;
422
441
  if (isInteractiveTarget(event.target, event.currentTarget)) return;
423
442
  if (event.key === "Enter" || event.key === " ") {
@@ -428,18 +447,20 @@ function DataTableRoot<T>({
428
447
 
429
448
  return (
430
449
  <tr
450
+ {...rowHtmlProps}
431
451
  key={row.id}
432
452
  className={[
433
453
  styles.row,
434
454
  isClickable && styles.clickable,
435
455
  isSelected && styles.selected,
436
456
  depth > 0 && styles.subRow,
457
+ rowClassName,
437
458
  ]
438
459
  .filter(Boolean)
439
460
  .join(" ")}
440
- onClick={isClickable ? handleRowClick : undefined}
441
- onKeyDown={isClickable ? handleRowKeyDown : undefined}
442
- tabIndex={isClickable ? 0 : undefined}
461
+ onClick={isClickable || rowOnClick ? handleRowClick : undefined}
462
+ onKeyDown={isClickable || rowOnKeyDown ? handleRowKeyDown : undefined}
463
+ tabIndex={rowTabIndex ?? (isClickable ? 0 : undefined)}
443
464
  data-selected={isSelected || undefined}
444
465
  data-depth={depth > 0 ? depth : undefined}
445
466
  >
@@ -2,6 +2,8 @@
2
2
 
3
3
  import * as React from "react";
4
4
  import { Popover as BasePopover } from "@base-ui/react/popover";
5
+ import { DayFlag, DayPicker, SelectionState, UI } from "react-day-picker";
6
+ import { format as formatDateWithPattern } from "date-fns";
5
7
  import { useFormFieldIds, type FormFieldProps } from "../../utils/aria";
6
8
  import { useResolvedControlSize } from "../ComponentDefaults";
7
9
  import styles from "./DatePicker.module.scss";
@@ -82,39 +84,6 @@ export interface DatePickerPresetProps extends React.ButtonHTMLAttributes<HTMLBu
82
84
  range?: DateRange;
83
85
  }
84
86
 
85
- // ============================================
86
- // Lazy-loaded dependencies (react-day-picker + date-fns)
87
- // ============================================
88
-
89
- let _DayPicker: any = null;
90
- let _dpUI: any = null;
91
- let _SelectionState: any = null;
92
- let _DayFlag: any = null;
93
- let _formatDate: ((date: Date, fmt: string) => string) | null = null;
94
- let _dpLoaded = false;
95
- let _dpFailed = false;
96
-
97
- function loadDatePickerDeps() {
98
- if (_dpLoaded) return;
99
- _dpLoaded = true;
100
- try {
101
- // eslint-disable-next-line @typescript-eslint/no-require-imports
102
- const rdp = require("react-day-picker");
103
- _DayPicker = rdp.DayPicker;
104
- _dpUI = rdp.UI;
105
- _SelectionState = rdp.SelectionState;
106
- _DayFlag = rdp.DayFlag;
107
- } catch {
108
- _dpFailed = true;
109
- }
110
- try {
111
- // eslint-disable-next-line @typescript-eslint/no-require-imports
112
- _formatDate = require("date-fns").format;
113
- } catch {
114
- _dpFailed = true;
115
- }
116
- }
117
-
118
87
  // ============================================
119
88
  // Icons
120
89
  // ============================================
@@ -219,18 +188,13 @@ function useDatePickerContext() {
219
188
  // ============================================
220
189
 
221
190
  function defaultFormatDate(date: Date): string {
222
- if (_formatDate) return _formatDate(date, "PPP");
223
- return date.toLocaleDateString();
191
+ return formatDateWithPattern(date, "PPP");
224
192
  }
225
193
 
226
194
  function defaultFormatRange(range: DateRange): string {
227
195
  if (!range.from) return "";
228
- if (_formatDate) {
229
- if (!range.to) return _formatDate(range.from, "LLL dd, y");
230
- return `${_formatDate(range.from, "LLL dd, y")} - ${_formatDate(range.to, "LLL dd, y")}`;
231
- }
232
- if (!range.to) return range.from.toLocaleDateString();
233
- return `${range.from.toLocaleDateString()} - ${range.to.toLocaleDateString()}`;
196
+ if (!range.to) return formatDateWithPattern(range.from, "LLL dd, y");
197
+ return `${formatDateWithPattern(range.from, "LLL dd, y")} - ${formatDateWithPattern(range.to, "LLL dd, y")}`;
234
198
  }
235
199
 
236
200
  function formatDateForHiddenInput(date?: Date): string {
@@ -246,32 +210,31 @@ function formatDateForHiddenInput(date?: Date): string {
246
210
  // ============================================
247
211
 
248
212
  function getCalendarClassNames() {
249
- if (!_dpUI || !_SelectionState || !_DayFlag) return {};
250
213
  return {
251
- [_dpUI.Root]: styles.calendar,
252
- [_dpUI.Months]: styles.months,
253
- [_dpUI.Month]: styles.month,
254
- [_dpUI.MonthCaption]: styles.monthCaption,
255
- [_dpUI.CaptionLabel]: styles.captionLabel,
256
- [_dpUI.Nav]: styles.nav,
257
- [_dpUI.PreviousMonthButton]: styles.navButton,
258
- [_dpUI.NextMonthButton]: styles.navButton,
259
- [_dpUI.MonthGrid]: styles.monthGrid,
260
- [_dpUI.Weekdays]: styles.weekdays,
261
- [_dpUI.Weekday]: styles.weekday,
262
- [_dpUI.Weeks]: styles.weeks,
263
- [_dpUI.Week]: styles.week,
264
- [_dpUI.Day]: styles.day,
265
- [_dpUI.DayButton]: styles.dayButton,
266
- [_dpUI.Chevron]: styles.chevron,
267
- [_SelectionState.selected]: styles.selected,
268
- [_SelectionState.range_start]: styles.rangeStart,
269
- [_SelectionState.range_middle]: styles.rangeMiddle,
270
- [_SelectionState.range_end]: styles.rangeEnd,
271
- [_DayFlag.today]: styles.today,
272
- [_DayFlag.outside]: styles.outside,
273
- [_DayFlag.disabled]: styles.disabled,
274
- [_DayFlag.focused]: styles.focused,
214
+ [UI.Root]: styles.calendar,
215
+ [UI.Months]: styles.months,
216
+ [UI.Month]: styles.month,
217
+ [UI.MonthCaption]: styles.monthCaption,
218
+ [UI.CaptionLabel]: styles.captionLabel,
219
+ [UI.Nav]: styles.nav,
220
+ [UI.PreviousMonthButton]: styles.navButton,
221
+ [UI.NextMonthButton]: styles.navButton,
222
+ [UI.MonthGrid]: styles.monthGrid,
223
+ [UI.Weekdays]: styles.weekdays,
224
+ [UI.Weekday]: styles.weekday,
225
+ [UI.Weeks]: styles.weeks,
226
+ [UI.Week]: styles.week,
227
+ [UI.Day]: styles.day,
228
+ [UI.DayButton]: styles.dayButton,
229
+ [UI.Chevron]: styles.chevron,
230
+ [SelectionState.selected]: styles.selected,
231
+ [SelectionState.range_start]: styles.rangeStart,
232
+ [SelectionState.range_middle]: styles.rangeMiddle,
233
+ [SelectionState.range_end]: styles.rangeEnd,
234
+ [DayFlag.today]: styles.today,
235
+ [DayFlag.outside]: styles.outside,
236
+ [DayFlag.disabled]: styles.disabled,
237
+ [DayFlag.focused]: styles.focused,
275
238
  };
276
239
  }
277
240
 
@@ -309,7 +272,6 @@ const DatePickerRoot = React.forwardRef<HTMLDivElement, DatePickerProps>(functio
309
272
  ) {
310
273
  const size = useResolvedControlSize(sizeProp);
311
274
  // Load deps eagerly so date formatters are available in the trigger
312
- loadDatePickerDeps();
313
275
  const [internalSelected, setInternalSelected] = React.useState<Date | null>(selectedProp ?? null);
314
276
  const [internalRange, setInternalRange] = React.useState<DateRange | null>(
315
277
  selectedRangeProp ?? null
@@ -544,8 +506,6 @@ function DatePickerCalendar({
544
506
  numberOfMonths: numberOfMonthsProp,
545
507
  className,
546
508
  }: DatePickerCalendarProps) {
547
- loadDatePickerDeps();
548
-
549
509
  const ctx = useDatePickerContext();
550
510
  const monthCount = numberOfMonthsProp ?? ctx.numberOfMonths;
551
511
 
@@ -557,31 +517,19 @@ function DatePickerCalendar({
557
517
  []
558
518
  );
559
519
 
560
- if (_dpFailed || !_DayPicker) {
561
- if (_dpFailed && process.env.NODE_ENV === "development") {
562
- console.warn(
563
- "[@usefragments/ui] DatePicker: react-day-picker and date-fns are not installed. " +
564
- "Install them with: npm install react-day-picker date-fns"
565
- );
566
- }
567
- return null;
568
- }
569
-
570
520
  const calendarClassNames = getCalendarClassNames();
571
521
 
572
522
  const calendarClasses = className
573
- ? { ...calendarClassNames, [_dpUI.Root]: [styles.calendar, className].join(" ") }
523
+ ? { ...calendarClassNames, [UI.Root]: [styles.calendar, className].join(" ") }
574
524
  : calendarClassNames;
575
525
 
576
- const DayPickerComponent = _DayPicker;
577
-
578
526
  if (ctx.mode === "range") {
579
527
  const rangeSelected = ctx.selectedRange
580
528
  ? { from: ctx.selectedRange.from ?? undefined, to: ctx.selectedRange.to ?? undefined }
581
529
  : undefined;
582
530
 
583
531
  return (
584
- <DayPickerComponent
532
+ <DayPicker
585
533
  mode="range"
586
534
  selected={rangeSelected}
587
535
  onSelect={(range: any) => {
@@ -601,7 +549,7 @@ function DatePickerCalendar({
601
549
  }
602
550
 
603
551
  return (
604
- <DayPickerComponent
552
+ <DayPicker
605
553
  mode="single"
606
554
  selected={ctx.selected ?? undefined}
607
555
  onSelect={(date: any) => {
@@ -92,6 +92,18 @@ export interface DrawerSwipeAreaProps extends React.HTMLAttributes<HTMLDivElemen
92
92
  disabled?: boolean;
93
93
  }
94
94
 
95
+ type DrawerSide = NonNullable<DrawerContentProps["side"]>;
96
+ type DrawerSwipeDirection = NonNullable<DrawerProps["swipeDirection"]>;
97
+
98
+ const SWIPE_DIRECTION_BY_SIDE: Record<DrawerSide, DrawerSwipeDirection> = {
99
+ left: "left",
100
+ right: "right",
101
+ top: "up",
102
+ bottom: "down",
103
+ };
104
+
105
+ const DrawerContentSideContext = React.createContext<(side: DrawerSide) => void>(() => {});
106
+
95
107
  function getAsChildElement(children: React.ReactNode, componentName: string): React.ReactElement {
96
108
  if (!React.isValidElement(children)) {
97
109
  throw new Error(`${componentName} with asChild requires a single valid React element child.`);
@@ -138,19 +150,24 @@ function DrawerRoot({
138
150
  snapPoints,
139
151
  disablePointerDismissal,
140
152
  }: DrawerProps) {
153
+ const [contentSide, setContentSide] = React.useState<DrawerSide>("right");
154
+ const resolvedSwipeDirection = swipeDirection ?? SWIPE_DIRECTION_BY_SIDE[contentSide];
155
+
141
156
  return (
142
- <BaseDrawer.Root
143
- open={open}
144
- defaultOpen={defaultOpen}
145
- onOpenChange={onOpenChange}
146
- onOpenChangeComplete={onOpenChangeComplete}
147
- modal={modal}
148
- swipeDirection={swipeDirection}
149
- snapPoints={snapPoints}
150
- disablePointerDismissal={disablePointerDismissal}
151
- >
152
- {children}
153
- </BaseDrawer.Root>
157
+ <DrawerContentSideContext.Provider value={setContentSide}>
158
+ <BaseDrawer.Root
159
+ open={open}
160
+ defaultOpen={defaultOpen}
161
+ onOpenChange={onOpenChange}
162
+ onOpenChangeComplete={onOpenChangeComplete}
163
+ modal={modal}
164
+ swipeDirection={resolvedSwipeDirection}
165
+ snapPoints={snapPoints}
166
+ disablePointerDismissal={disablePointerDismissal}
167
+ >
168
+ {children}
169
+ </BaseDrawer.Root>
170
+ </DrawerContentSideContext.Provider>
154
171
  );
155
172
  }
156
173
 
@@ -181,11 +198,20 @@ function DrawerContent({
181
198
  className,
182
199
  ...htmlProps
183
200
  }: DrawerContentProps) {
201
+ const registerContentSide = React.useContext(DrawerContentSideContext);
184
202
  const { className: viewportClassName, ...viewportHtmlProps } = viewportProps ?? {};
185
203
  const popupClasses = [styles.popup, styles[`side-${side}`], styles[`size-${size}`], className]
186
204
  .filter(Boolean)
187
205
  .join(" ");
188
206
 
207
+ React.useEffect(() => {
208
+ registerContentSide(side);
209
+
210
+ return () => {
211
+ registerContentSide("right");
212
+ };
213
+ }, [registerContentSide, side]);
214
+
189
215
  return (
190
216
  <BaseDrawer.Portal>
191
217
  {backdrop && <BaseDrawer.Backdrop className={styles.backdrop} />}
@@ -1,8 +1,12 @@
1
- 'use client';
1
+ "use client";
2
2
 
3
- import * as React from 'react';
4
- import { Field as BaseField, type FieldValidityState } from '@base-ui/react/field';
5
- import styles from './Field.module.scss';
3
+ import * as React from "react";
4
+ import {
5
+ Field as BaseField,
6
+ type FieldControlProps as BaseFieldControlProps,
7
+ type FieldValidityState,
8
+ } from "@base-ui/react/field";
9
+ import styles from "./Field.module.scss";
6
10
 
7
11
  // ============================================
8
12
  // Types
@@ -14,7 +18,7 @@ export interface FieldProps extends React.HTMLAttributes<HTMLDivElement> {
14
18
  disabled?: boolean;
15
19
  invalid?: boolean;
16
20
  validate?: (value: unknown) => string | string[] | null | Promise<string | string[] | null>;
17
- validationMode?: 'onSubmit' | 'onBlur' | 'onChange';
21
+ validationMode?: "onSubmit" | "onBlur" | "onChange";
18
22
  validationDebounceTime?: number;
19
23
  }
20
24
 
@@ -23,7 +27,10 @@ export interface FieldLabelProps {
23
27
  className?: string;
24
28
  }
25
29
 
26
- export interface FieldControlProps {
30
+ export interface FieldControlProps extends Omit<
31
+ BaseFieldControlProps,
32
+ "children" | "className" | "ref" | "render"
33
+ > {
27
34
  children: React.ReactElement;
28
35
  className?: string;
29
36
  }
@@ -35,7 +42,14 @@ export interface FieldDescriptionProps {
35
42
 
36
43
  export interface FieldErrorProps {
37
44
  children?: React.ReactNode;
38
- match?: 'valueMissing' | 'typeMismatch' | 'tooShort' | 'tooLong' | 'patternMismatch' | 'customError' | boolean;
45
+ match?:
46
+ | "valueMissing"
47
+ | "typeMismatch"
48
+ | "tooShort"
49
+ | "tooLong"
50
+ | "patternMismatch"
51
+ | "customError"
52
+ | boolean;
39
53
  className?: string;
40
54
  }
41
55
 
@@ -60,7 +74,7 @@ function FieldRoot({
60
74
  className,
61
75
  ...htmlProps
62
76
  }: FieldProps) {
63
- const classes = [styles.root, className].filter(Boolean).join(' ');
77
+ const classes = [styles.root, className].filter(Boolean).join(" ");
64
78
 
65
79
  return (
66
80
  <BaseField.Root
@@ -79,7 +93,7 @@ function FieldRoot({
79
93
  }
80
94
 
81
95
  function FieldLabel({ children, className }: FieldLabelProps) {
82
- const classes = [styles.label, className].filter(Boolean).join(' ');
96
+ const classes = [styles.label, className].filter(Boolean).join(" ");
83
97
  return <BaseField.Label className={classes}>{children}</BaseField.Label>;
84
98
  }
85
99
 
@@ -90,31 +104,24 @@ function FieldLabel({ children, className }: FieldLabelProps) {
90
104
  *
91
105
  * Works with Input, Textarea, Checkbox, Switch, Select, or any element.
92
106
  */
93
- function FieldControl({ children, className }: FieldControlProps) {
94
- const classes = [styles.control, className].filter(Boolean).join(' ');
95
- return (
96
- <BaseField.Control
97
- className={classes}
98
- render={children}
99
- />
100
- );
107
+ function FieldControl({ children, className, ...controlProps }: FieldControlProps) {
108
+ const classes = [styles.control, className].filter(Boolean).join(" ");
109
+ return <BaseField.Control {...controlProps} className={classes} render={children} />;
101
110
  }
102
111
 
103
112
  function FieldDescription({ children, className }: FieldDescriptionProps) {
104
- const classes = [styles.description, className].filter(Boolean).join(' ');
105
- return (
106
- <BaseField.Description className={classes}>
107
- {children}
108
- </BaseField.Description>
109
- );
113
+ const classes = [styles.description, className].filter(Boolean).join(" ");
114
+ return <BaseField.Description className={classes}>{children}</BaseField.Description>;
110
115
  }
111
116
 
112
117
  function FieldError({ children, match, className }: FieldErrorProps) {
113
- const classes = [styles.error, className].filter(Boolean).join(' ');
118
+ const classes = [styles.error, className].filter(Boolean).join(" ");
114
119
  return (
115
- <BaseField.Error match={match} className={classes}>
116
- {children}
117
- </BaseField.Error>
120
+ <BaseField.Error
121
+ match={match}
122
+ className={classes}
123
+ {...(children === undefined ? {} : { children })}
124
+ />
118
125
  );
119
126
  }
120
127
 
@@ -134,11 +141,4 @@ export const Field = Object.assign(FieldRoot, {
134
141
  Validity: FieldValidity,
135
142
  });
136
143
 
137
- export {
138
- FieldRoot,
139
- FieldLabel,
140
- FieldControl,
141
- FieldDescription,
142
- FieldError,
143
- FieldValidity,
144
- };
144
+ export { FieldRoot, FieldLabel, FieldControl, FieldDescription, FieldError, FieldValidity };
@@ -18,6 +18,9 @@
18
18
  "children: node (required)",
19
19
  "height: string (default: 56px)",
20
20
  "position: static|fixed|sticky (default: static)",
21
+ "elevatedOnScroll: boolean|{ threshold?: number }",
22
+ "navAlign: start|center (default: start)",
23
+ "container: full|page (default: full)",
21
24
  "icons: object",
22
25
  "style: object"
23
26
  ],
@@ -44,6 +47,26 @@
44
47
  "sticky"
45
48
  ]
46
49
  },
50
+ "elevatedOnScroll": {
51
+ "type": "boolean|object",
52
+ "description": "Apply the elevated header border after scrolling. Object form accepts { threshold?: number }.",
53
+ "default": false,
54
+ "required": false
55
+ },
56
+ "navAlign": {
57
+ "type": "enum",
58
+ "description": "Navigation alignment inside the header",
59
+ "default": "start",
60
+ "required": false,
61
+ "values": ["start", "center"]
62
+ },
63
+ "container": {
64
+ "type": "enum",
65
+ "description": "Header content width",
66
+ "default": "full",
67
+ "required": false,
68
+ "values": ["full", "page"]
69
+ },
47
70
  "icons": {
48
71
  "type": "object",
49
72
  "description": "Optional icon overrides for Header.Trigger (menu/close) and Header.NavMenu chevron",
@@ -79,7 +102,12 @@
79
102
  "Use Header.NavMenu to group related nav items under a dropdown",
80
103
  "Use Header.NavMenuItem inside Header.NavMenu for dropdown items",
81
104
  "Header sub-components forward DOM props (id, aria-*, data-*, handlers) to their rendered elements",
105
+ "Header.Brand asChild composes custom link components while preserving canonical brand styling",
82
106
  "Header.NavItem asChild composes click handlers instead of overwriting the child handler",
107
+ "Use elevatedOnScroll on sticky marketing headers that need a boundary after scrolling",
108
+ "Use navAlign=\"center\" when navigation must stay centered independently of brand and actions",
109
+ "Use container=\"page\" when the header should share a bounded page gutter",
110
+ "Use Header.MobileNavActions for the primary action row inside Header.MobileNav",
83
111
  "Use the Header icons prop to replace internal mobile trigger and dropdown chevron icons with any icon package",
84
112
  "For rich dropdown content (titles, descriptions, icons), use NavigationMenu instead of Header.Nav",
85
113
  "NavigationMenu also provides an automatic mobile drawer, replacing Header.Trigger + Sidebar for mobile nav"
@@ -98,6 +126,11 @@
98
126
  "description": "Header with brand, nav, and actions. Use with AppShell layout=\"default\".",
99
127
  "code": "<ThemeProvider defaultMode=\"light\">\n <Header>\n <Header.SkipLink />\n <Header.Trigger />\n <Header.Brand href=\"/\">MyApp</Header.Brand>\n <Header.Nav>\n <Header.NavItem href=\"/dashboard\" active>Dashboard</Header.NavItem>\n <Header.NavItem href=\"/projects\">Projects</Header.NavItem>\n <Header.NavItem href=\"/settings\">Settings</Header.NavItem>\n </Header.Nav>\n <Header.Spacer />\n <Header.Actions>\n <ThemeToggle size=\"md\" />\n <Button variant=\"secondary\" size=\"sm\">Sign In</Button>\n </Header.Actions>\n </Header>\n</ThemeProvider>"
100
128
  },
129
+ {
130
+ "name": "Marketing Header",
131
+ "description": "Sticky, page-width marketing header with centered navigation, scroll elevation, custom link composition, and mobile actions.",
132
+ "code": "<Header position=\"sticky\" elevatedOnScroll navAlign=\"center\" container=\"page\">\n <Header.SkipLink href=\"#main-content\" />\n <Header.Brand asChild>\n <a href=\"/\" aria-label=\"Home\">Logo</a>\n </Header.Brand>\n <Header.Nav aria-label=\"Main navigation\">\n <Header.NavItem href=\"/docs\">Docs</Header.NavItem>\n </Header.Nav>\n <Header.Actions>\n <Button size=\"sm\">Start free</Button>\n </Header.Actions>\n <Header.Trigger />\n <Header.MobileNav>\n <Header.MobileNavLink href=\"/docs\">Docs</Header.MobileNavLink>\n <Header.MobileNavActions>\n <Button size=\"sm\">Start free</Button>\n </Header.MobileNavActions>\n </Header.MobileNav>\n</Header>"
133
+ },
101
134
  {
102
135
  "name": "With Dropdown Nav",
103
136
  "description": "Header with a dropdown menu grouping related navigation links.",
@@ -155,9 +188,14 @@
155
188
  "propsSummary": [
156
189
  "height: string - header height (default: 56px)",
157
190
  "position: static|fixed|sticky - positioning behavior",
191
+ "elevatedOnScroll: boolean|{ threshold?: number } - scroll-elevated boundary",
192
+ "navAlign: start|center - nav placement inside the header",
193
+ "container: full|page - content width and gutter",
158
194
  "icons: { menu?, close?, navMenuChevron? } - custom internal control icons (ReactNode or render function)",
195
+ "Header.Brand asChild composes custom link components",
159
196
  "Header.Trigger composes click handler with Sidebar toggle behavior",
160
- "Header.NavMenu provides dropdown groups via Base UI Menu"
197
+ "Header.NavMenu provides dropdown groups via Base UI Menu",
198
+ "Header.MobileNavActions provides an action row inside the mobile drawer"
161
199
  ],
162
200
  "a11yRules": [
163
201
  "A11Y_HEADER_LANDMARK",
@@ -176,6 +214,7 @@
176
214
  "NavItem",
177
215
  "MobileNav",
178
216
  "MobileNavLink",
217
+ "MobileNavActions",
179
218
  "NavMenu",
180
219
  "NavMenuItem",
181
220
  "Search",
@@ -184,6 +223,7 @@
184
223
  ],
185
224
  "commonPatterns": [
186
225
  "<Header><Header.Brand href=\"/\">{appName}</Header.Brand><Header.Nav><Header.NavItem href=\"/home\" active>Home</Header.NavItem></Header.Nav><Header.Spacer /><Header.Actions>{actions}</Header.Actions></Header>",
226
+ "<Header position=\"sticky\" elevatedOnScroll navAlign=\"center\" container=\"page\"><Header.Brand asChild>{link}</Header.Brand><Header.Nav>{links}</Header.Nav><Header.Actions>{actions}</Header.Actions><Header.Trigger /><Header.MobileNav>{mobileLinks}<Header.MobileNavActions>{mobileActions}</Header.MobileNavActions></Header.MobileNav></Header>",
187
227
  "<Header><Header.Nav><Header.NavItem href=\"/home\">Home</Header.NavItem><Header.NavMenu label=\"Docs\" active><Header.NavMenuItem href=\"/cli\">CLI</Header.NavMenuItem><Header.NavMenuItem href=\"/mcp\">MCP</Header.NavMenuItem></Header.NavMenu></Header.Nav></Header>"
188
228
  ]
189
229
  },
@@ -30,6 +30,24 @@
30
30
  top: 0;
31
31
  }
32
32
 
33
+ .elevatedOnScroll {
34
+ border-bottom: var(--fui-space-px, $fui-space-px) solid transparent;
35
+ transition: border-color var(--fui-transition-fast, $fui-transition-fast);
36
+ }
37
+
38
+ .scrolled {
39
+ border-bottom-color: var(--fui-border, $fui-border);
40
+ }
41
+
42
+ .containerPage {
43
+ padding-inline: clamp(var(--fui-space-4, $fui-space-4), 4vw, var(--fui-space-12, $fui-space-12));
44
+
45
+ .container {
46
+ max-width: calc(var(--fui-space-12, $fui-space-12) * 31);
47
+ margin-inline: auto;
48
+ }
49
+ }
50
+
33
51
  .container {
34
52
  display: flex;
35
53
  align-items: center;
@@ -43,6 +61,21 @@
43
61
  }
44
62
  }
45
63
 
64
+ .navCentered {
65
+ .container {
66
+ position: relative;
67
+ }
68
+
69
+ .nav {
70
+ @include container-min($fui-breakpoint-md, fui-header) {
71
+ position: absolute;
72
+ inset-block: 0;
73
+ left: 50%;
74
+ transform: translateX(-50%);
75
+ }
76
+ }
77
+ }
78
+
46
79
  // ============================================
47
80
  // Brand
48
81
  // ============================================
@@ -381,6 +414,13 @@
381
414
  background-color: var(--fui-bg-secondary, $fui-bg-secondary);
382
415
  }
383
416
 
417
+ .mobileNavActions {
418
+ display: flex;
419
+ align-items: center;
420
+ gap: var(--fui-space-2, $fui-space-2);
421
+ padding: var(--fui-space-3, $fui-space-3) 0 var(--fui-space-2, $fui-space-2);
422
+ }
423
+
384
424
  @keyframes mobileNavFadeIn {
385
425
  from { opacity: 0; }
386
426
  to { opacity: 1; }