@d4gger/design-system 3.0.1 → 4.0.1

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 (502) hide show
  1. package/README.md +19 -0
  2. package/dist/brand-effects.css +5 -3
  3. package/dist/components/accordion.css +9 -2
  4. package/dist/components/alert/Alert.cjs +27 -9
  5. package/dist/components/alert/Alert.cjs.map +2 -2
  6. package/dist/components/alert/Alert.d.cts +6 -0
  7. package/dist/components/alert/Alert.d.cts.map +1 -1
  8. package/dist/components/alert/Alert.d.mts +6 -0
  9. package/dist/components/alert/Alert.d.mts.map +1 -1
  10. package/dist/components/alert/Alert.d.ts +6 -0
  11. package/dist/components/alert/Alert.d.ts.map +1 -1
  12. package/dist/components/alert/Alert.js +28 -10
  13. package/dist/components/alert/Alert.js.map +2 -2
  14. package/dist/components/alert.css +73 -3
  15. package/dist/components/article-nodes.css +16 -1
  16. package/dist/components/articleNodes/ArticleNodes.cjs +46 -5
  17. package/dist/components/articleNodes/ArticleNodes.cjs.map +2 -2
  18. package/dist/components/articleNodes/ArticleNodes.d.cts +7 -3
  19. package/dist/components/articleNodes/ArticleNodes.d.cts.map +1 -1
  20. package/dist/components/articleNodes/ArticleNodes.d.mts +7 -3
  21. package/dist/components/articleNodes/ArticleNodes.d.mts.map +1 -1
  22. package/dist/components/articleNodes/ArticleNodes.d.ts +7 -3
  23. package/dist/components/articleNodes/ArticleNodes.d.ts.map +1 -1
  24. package/dist/components/articleNodes/ArticleNodes.js +46 -5
  25. package/dist/components/articleNodes/ArticleNodes.js.map +2 -2
  26. package/dist/components/articleNodes/articleExtensions.cjs +21 -4
  27. package/dist/components/articleNodes/articleExtensions.cjs.map +2 -2
  28. package/dist/components/articleNodes/articleExtensions.d.cts +8 -2
  29. package/dist/components/articleNodes/articleExtensions.d.cts.map +1 -1
  30. package/dist/components/articleNodes/articleExtensions.d.mts +8 -2
  31. package/dist/components/articleNodes/articleExtensions.d.mts.map +1 -1
  32. package/dist/components/articleNodes/articleExtensions.d.ts +8 -2
  33. package/dist/components/articleNodes/articleExtensions.d.ts.map +1 -1
  34. package/dist/components/articleNodes/articleExtensions.js +21 -4
  35. package/dist/components/articleNodes/articleExtensions.js.map +2 -2
  36. package/dist/components/articleNodes/articleNodeViews.cjs +154 -0
  37. package/dist/components/articleNodes/articleNodeViews.cjs.map +7 -0
  38. package/dist/components/articleNodes/articleNodeViews.d.cts +3 -0
  39. package/dist/components/articleNodes/articleNodeViews.d.cts.map +1 -0
  40. package/dist/components/articleNodes/articleNodeViews.d.mts +3 -0
  41. package/dist/components/articleNodes/articleNodeViews.d.mts.map +1 -0
  42. package/dist/components/articleNodes/articleNodeViews.d.ts +3 -0
  43. package/dist/components/articleNodes/articleNodeViews.d.ts.map +1 -0
  44. package/dist/components/articleNodes/articleNodeViews.js +124 -0
  45. package/dist/components/articleNodes/articleNodeViews.js.map +7 -0
  46. package/dist/components/articleNodes/articleNodes.props.cjs.map +1 -1
  47. package/dist/components/articleNodes/articleNodes.props.d.cts +25 -2
  48. package/dist/components/articleNodes/articleNodes.props.d.cts.map +1 -1
  49. package/dist/components/articleNodes/articleNodes.props.d.mts +25 -2
  50. package/dist/components/articleNodes/articleNodes.props.d.mts.map +1 -1
  51. package/dist/components/articleNodes/articleNodes.props.d.ts +25 -2
  52. package/dist/components/articleNodes/articleNodes.props.d.ts.map +1 -1
  53. package/dist/components/banner.css +5 -4
  54. package/dist/components/blockquote.css +7 -4
  55. package/dist/components/bottom-dock.css +140 -0
  56. package/dist/components/bottomDock/BottomDock.cjs +140 -0
  57. package/dist/components/bottomDock/BottomDock.cjs.map +7 -0
  58. package/dist/components/bottomDock/BottomDock.d.cts +25 -0
  59. package/dist/components/bottomDock/BottomDock.d.cts.map +1 -0
  60. package/dist/components/bottomDock/BottomDock.d.mts +25 -0
  61. package/dist/components/bottomDock/BottomDock.d.mts.map +1 -0
  62. package/dist/components/bottomDock/BottomDock.d.ts +25 -0
  63. package/dist/components/bottomDock/BottomDock.d.ts.map +1 -0
  64. package/dist/components/bottomDock/BottomDock.js +110 -0
  65. package/dist/components/bottomDock/BottomDock.js.map +7 -0
  66. package/dist/components/bottomDock/bottomDock.props.cjs +49 -0
  67. package/dist/components/bottomDock/bottomDock.props.cjs.map +7 -0
  68. package/dist/components/bottomDock/bottomDock.props.d.cts +29 -0
  69. package/dist/components/bottomDock/bottomDock.props.d.cts.map +1 -0
  70. package/dist/components/bottomDock/bottomDock.props.d.mts +29 -0
  71. package/dist/components/bottomDock/bottomDock.props.d.mts.map +1 -0
  72. package/dist/components/bottomDock/bottomDock.props.d.ts +29 -0
  73. package/dist/components/bottomDock/bottomDock.props.d.ts.map +1 -0
  74. package/dist/components/bottomDock/bottomDock.props.js +29 -0
  75. package/dist/components/bottomDock/bottomDock.props.js.map +7 -0
  76. package/dist/components/breadcrumb.css +24 -3
  77. package/dist/components/callout.css +20 -7
  78. package/dist/components/card.css +9 -1
  79. package/dist/components/code.css +29 -13
  80. package/dist/components/collapsible/Collapsible.cjs +14 -0
  81. package/dist/components/collapsible/Collapsible.cjs.map +2 -2
  82. package/dist/components/collapsible/Collapsible.d.cts.map +1 -1
  83. package/dist/components/collapsible/Collapsible.d.mts.map +1 -1
  84. package/dist/components/collapsible/Collapsible.d.ts.map +1 -1
  85. package/dist/components/collapsible/Collapsible.js +14 -0
  86. package/dist/components/collapsible/Collapsible.js.map +2 -2
  87. package/dist/components/collapsible.css +10 -1
  88. package/dist/components/command.css +0 -2
  89. package/dist/components/comment-thread.css +15 -7
  90. package/dist/components/commentThread/CommentThread.cjs +45 -17
  91. package/dist/components/commentThread/CommentThread.cjs.map +2 -2
  92. package/dist/components/commentThread/CommentThread.d.cts +6 -6
  93. package/dist/components/commentThread/CommentThread.d.cts.map +1 -1
  94. package/dist/components/commentThread/CommentThread.d.mts +6 -6
  95. package/dist/components/commentThread/CommentThread.d.mts.map +1 -1
  96. package/dist/components/commentThread/CommentThread.d.ts +6 -6
  97. package/dist/components/commentThread/CommentThread.d.ts.map +1 -1
  98. package/dist/components/commentThread/CommentThread.js +45 -17
  99. package/dist/components/commentThread/CommentThread.js.map +2 -2
  100. package/dist/components/commentThread/commentThread.props.cjs.map +1 -1
  101. package/dist/components/commentThread/commentThread.props.d.cts +24 -0
  102. package/dist/components/commentThread/commentThread.props.d.cts.map +1 -1
  103. package/dist/components/commentThread/commentThread.props.d.mts +24 -0
  104. package/dist/components/commentThread/commentThread.props.d.mts.map +1 -1
  105. package/dist/components/commentThread/commentThread.props.d.ts +24 -0
  106. package/dist/components/commentThread/commentThread.props.d.ts.map +1 -1
  107. package/dist/components/config-drawer.css +7 -3
  108. package/dist/components/configDrawer/ConfigDrawer.cjs +1 -1
  109. package/dist/components/configDrawer/ConfigDrawer.cjs.map +2 -2
  110. package/dist/components/configDrawer/ConfigDrawer.js +1 -1
  111. package/dist/components/configDrawer/ConfigDrawer.js.map +2 -2
  112. package/dist/components/context-menu.css +3 -1
  113. package/dist/components/contextMenu/ContextMenu.cjs +37 -6
  114. package/dist/components/contextMenu/ContextMenu.cjs.map +2 -2
  115. package/dist/components/contextMenu/ContextMenu.d.cts +1 -1
  116. package/dist/components/contextMenu/ContextMenu.d.cts.map +1 -1
  117. package/dist/components/contextMenu/ContextMenu.d.mts +1 -1
  118. package/dist/components/contextMenu/ContextMenu.d.mts.map +1 -1
  119. package/dist/components/contextMenu/ContextMenu.d.ts +1 -1
  120. package/dist/components/contextMenu/ContextMenu.d.ts.map +1 -1
  121. package/dist/components/contextMenu/ContextMenu.js +37 -6
  122. package/dist/components/contextMenu/ContextMenu.js.map +2 -2
  123. package/dist/components/dialog.css +1 -1
  124. package/dist/components/drawer.css +23 -6
  125. package/dist/components/dropdownMenu/DropdownMenu.cjs +10 -5
  126. package/dist/components/dropdownMenu/DropdownMenu.cjs.map +2 -2
  127. package/dist/components/dropdownMenu/DropdownMenu.d.cts.map +1 -1
  128. package/dist/components/dropdownMenu/DropdownMenu.d.mts.map +1 -1
  129. package/dist/components/dropdownMenu/DropdownMenu.d.ts.map +1 -1
  130. package/dist/components/dropdownMenu/DropdownMenu.js +10 -5
  131. package/dist/components/dropdownMenu/DropdownMenu.js.map +2 -2
  132. package/dist/components/environment-ribbon.css +73 -0
  133. package/dist/components/environmentRibbon/EnvironmentRibbon.cjs +69 -0
  134. package/dist/components/environmentRibbon/EnvironmentRibbon.cjs.map +7 -0
  135. package/dist/components/environmentRibbon/EnvironmentRibbon.d.cts +15 -0
  136. package/dist/components/environmentRibbon/EnvironmentRibbon.d.cts.map +1 -0
  137. package/dist/components/environmentRibbon/EnvironmentRibbon.d.mts +15 -0
  138. package/dist/components/environmentRibbon/EnvironmentRibbon.d.mts.map +1 -0
  139. package/dist/components/environmentRibbon/EnvironmentRibbon.d.ts +15 -0
  140. package/dist/components/environmentRibbon/EnvironmentRibbon.d.ts.map +1 -0
  141. package/dist/components/environmentRibbon/EnvironmentRibbon.js +39 -0
  142. package/dist/components/environmentRibbon/EnvironmentRibbon.js.map +7 -0
  143. package/dist/components/environmentRibbon/environmentRibbon.props.cjs +39 -0
  144. package/dist/components/environmentRibbon/environmentRibbon.props.cjs.map +7 -0
  145. package/dist/components/environmentRibbon/environmentRibbon.props.d.cts +18 -0
  146. package/dist/components/environmentRibbon/environmentRibbon.props.d.cts.map +1 -0
  147. package/dist/components/environmentRibbon/environmentRibbon.props.d.mts +18 -0
  148. package/dist/components/environmentRibbon/environmentRibbon.props.d.mts.map +1 -0
  149. package/dist/components/environmentRibbon/environmentRibbon.props.d.ts +18 -0
  150. package/dist/components/environmentRibbon/environmentRibbon.props.d.ts.map +1 -0
  151. package/dist/components/environmentRibbon/environmentRibbon.props.js +19 -0
  152. package/dist/components/environmentRibbon/environmentRibbon.props.js.map +7 -0
  153. package/dist/components/field.css +5 -0
  154. package/dist/components/file-upload.css +36 -9
  155. package/dist/components/floating-panel.css +49 -18
  156. package/dist/components/floatingPanel/FloatingPanel.cjs +156 -58
  157. package/dist/components/floatingPanel/FloatingPanel.cjs.map +2 -2
  158. package/dist/components/floatingPanel/FloatingPanel.d.cts.map +1 -1
  159. package/dist/components/floatingPanel/FloatingPanel.d.mts.map +1 -1
  160. package/dist/components/floatingPanel/FloatingPanel.d.ts.map +1 -1
  161. package/dist/components/floatingPanel/FloatingPanel.js +156 -58
  162. package/dist/components/floatingPanel/FloatingPanel.js.map +2 -2
  163. package/dist/components/grid/Grid.cjs +24 -35
  164. package/dist/components/grid/Grid.cjs.map +2 -2
  165. package/dist/components/grid/Grid.d.cts.map +1 -1
  166. package/dist/components/grid/Grid.d.mts.map +1 -1
  167. package/dist/components/grid/Grid.d.ts.map +1 -1
  168. package/dist/components/grid/Grid.js +24 -35
  169. package/dist/components/grid/Grid.js.map +2 -2
  170. package/dist/components/heading/Heading.cjs +1 -8
  171. package/dist/components/heading/Heading.cjs.map +2 -2
  172. package/dist/components/heading/Heading.d.cts.map +1 -1
  173. package/dist/components/heading/Heading.d.mts.map +1 -1
  174. package/dist/components/heading/Heading.d.ts.map +1 -1
  175. package/dist/components/heading/Heading.js +1 -8
  176. package/dist/components/heading/Heading.js.map +2 -2
  177. package/dist/components/heading/heading.props.cjs +9 -9
  178. package/dist/components/heading/heading.props.cjs.map +2 -2
  179. package/dist/components/heading/heading.props.d.cts +42 -43
  180. package/dist/components/heading/heading.props.d.cts.map +1 -1
  181. package/dist/components/heading/heading.props.d.mts +42 -43
  182. package/dist/components/heading/heading.props.d.mts.map +1 -1
  183. package/dist/components/heading/heading.props.d.ts +42 -43
  184. package/dist/components/heading/heading.props.d.ts.map +1 -1
  185. package/dist/components/heading/heading.props.js +9 -9
  186. package/dist/components/heading/heading.props.js.map +2 -2
  187. package/dist/components/heading.css +127 -104
  188. package/dist/components/hover-card.css +5 -2
  189. package/dist/components/icon/Icon.cjs +19 -0
  190. package/dist/components/icon/Icon.cjs.map +2 -2
  191. package/dist/components/icon/Icon.d.cts +29 -1
  192. package/dist/components/icon/Icon.d.cts.map +1 -1
  193. package/dist/components/icon/Icon.d.mts +29 -1
  194. package/dist/components/icon/Icon.d.mts.map +1 -1
  195. package/dist/components/icon/Icon.d.ts +29 -1
  196. package/dist/components/icon/Icon.d.ts.map +1 -1
  197. package/dist/components/icon/Icon.js +25 -0
  198. package/dist/components/icon/Icon.js.map +2 -2
  199. package/dist/components/icon/icons.cjs +14 -0
  200. package/dist/components/icon/icons.cjs.map +2 -2
  201. package/dist/components/icon/icons.d.cts +35 -0
  202. package/dist/components/icon/icons.d.cts.map +1 -1
  203. package/dist/components/icon/icons.d.mts +35 -0
  204. package/dist/components/icon/icons.d.mts.map +1 -1
  205. package/dist/components/icon/icons.d.ts +35 -0
  206. package/dist/components/icon/icons.d.ts.map +1 -1
  207. package/dist/components/icon/icons.js +14 -0
  208. package/dist/components/icon/icons.js.map +2 -2
  209. package/dist/components/index.cjs +2 -0
  210. package/dist/components/index.cjs.map +2 -2
  211. package/dist/components/index.d.cts +2 -0
  212. package/dist/components/index.d.cts.map +1 -1
  213. package/dist/components/index.d.mts +2 -0
  214. package/dist/components/index.d.mts.map +1 -1
  215. package/dist/components/index.d.ts +2 -0
  216. package/dist/components/index.d.ts.map +1 -1
  217. package/dist/components/index.js +2 -0
  218. package/dist/components/index.js.map +2 -2
  219. package/dist/components/label.css +3 -0
  220. package/dist/components/link.css +33 -97
  221. package/dist/components/notification-center.css +58 -10
  222. package/dist/components/notificationCenter/NotificationCenter.cjs +27 -17
  223. package/dist/components/notificationCenter/NotificationCenter.cjs.map +2 -2
  224. package/dist/components/notificationCenter/NotificationCenter.d.cts +2 -0
  225. package/dist/components/notificationCenter/NotificationCenter.d.cts.map +1 -1
  226. package/dist/components/notificationCenter/NotificationCenter.d.mts +2 -0
  227. package/dist/components/notificationCenter/NotificationCenter.d.mts.map +1 -1
  228. package/dist/components/notificationCenter/NotificationCenter.d.ts +2 -0
  229. package/dist/components/notificationCenter/NotificationCenter.d.ts.map +1 -1
  230. package/dist/components/notificationCenter/NotificationCenter.js +28 -18
  231. package/dist/components/notificationCenter/NotificationCenter.js.map +2 -2
  232. package/dist/components/page-header.css +21 -0
  233. package/dist/components/pageHeader/PageHeader.cjs +10 -2
  234. package/dist/components/pageHeader/PageHeader.cjs.map +2 -2
  235. package/dist/components/pageHeader/PageHeader.d.cts.map +1 -1
  236. package/dist/components/pageHeader/PageHeader.d.mts.map +1 -1
  237. package/dist/components/pageHeader/PageHeader.d.ts.map +1 -1
  238. package/dist/components/pageHeader/PageHeader.js +10 -2
  239. package/dist/components/pageHeader/PageHeader.js.map +2 -2
  240. package/dist/components/pageHeader/pageHeader.props.cjs +7 -1
  241. package/dist/components/pageHeader/pageHeader.props.cjs.map +2 -2
  242. package/dist/components/pageHeader/pageHeader.props.d.cts +5 -0
  243. package/dist/components/pageHeader/pageHeader.props.d.cts.map +1 -1
  244. package/dist/components/pageHeader/pageHeader.props.d.mts +5 -0
  245. package/dist/components/pageHeader/pageHeader.props.d.mts.map +1 -1
  246. package/dist/components/pageHeader/pageHeader.props.d.ts +5 -0
  247. package/dist/components/pageHeader/pageHeader.props.d.ts.map +1 -1
  248. package/dist/components/pageHeader/pageHeader.props.js +7 -1
  249. package/dist/components/pageHeader/pageHeader.props.js.map +2 -2
  250. package/dist/components/pills/Pills.cjs +1 -1
  251. package/dist/components/pills/Pills.cjs.map +2 -2
  252. package/dist/components/pills/Pills.js +2 -2
  253. package/dist/components/pills/Pills.js.map +2 -2
  254. package/dist/components/pills.css +6 -0
  255. package/dist/components/popover.css +45 -6
  256. package/dist/components/prose.css +3 -3
  257. package/dist/components/qr-code.css +5 -2
  258. package/dist/components/qrCode/QrCode.cjs +14 -11
  259. package/dist/components/qrCode/QrCode.cjs.map +2 -2
  260. package/dist/components/qrCode/QrCode.d.cts.map +1 -1
  261. package/dist/components/qrCode/QrCode.d.mts.map +1 -1
  262. package/dist/components/qrCode/QrCode.d.ts.map +1 -1
  263. package/dist/components/qrCode/QrCode.js +14 -11
  264. package/dist/components/qrCode/QrCode.js.map +2 -2
  265. package/dist/components/resizable.css +20 -4
  266. package/dist/components/rich-text-editor.css +50 -14
  267. package/dist/components/richTextEditor/EditorTools.cjs +226 -0
  268. package/dist/components/richTextEditor/EditorTools.cjs.map +7 -0
  269. package/dist/components/richTextEditor/EditorTools.d.cts +22 -0
  270. package/dist/components/richTextEditor/EditorTools.d.cts.map +1 -0
  271. package/dist/components/richTextEditor/EditorTools.d.mts +22 -0
  272. package/dist/components/richTextEditor/EditorTools.d.mts.map +1 -0
  273. package/dist/components/richTextEditor/EditorTools.d.ts +22 -0
  274. package/dist/components/richTextEditor/EditorTools.d.ts.map +1 -0
  275. package/dist/components/richTextEditor/EditorTools.js +196 -0
  276. package/dist/components/richTextEditor/EditorTools.js.map +7 -0
  277. package/dist/components/richTextEditor/MentionSuggestions.cjs +96 -0
  278. package/dist/components/richTextEditor/MentionSuggestions.cjs.map +7 -0
  279. package/dist/components/richTextEditor/MentionSuggestions.d.cts +7 -0
  280. package/dist/components/richTextEditor/MentionSuggestions.d.cts.map +1 -0
  281. package/dist/components/richTextEditor/MentionSuggestions.d.mts +7 -0
  282. package/dist/components/richTextEditor/MentionSuggestions.d.mts.map +1 -0
  283. package/dist/components/richTextEditor/MentionSuggestions.d.ts +7 -0
  284. package/dist/components/richTextEditor/MentionSuggestions.d.ts.map +1 -0
  285. package/dist/components/richTextEditor/MentionSuggestions.js +66 -0
  286. package/dist/components/richTextEditor/MentionSuggestions.js.map +7 -0
  287. package/dist/components/richTextEditor/RichTextEditor.cjs +53 -206
  288. package/dist/components/richTextEditor/RichTextEditor.cjs.map +3 -3
  289. package/dist/components/richTextEditor/RichTextEditor.d.cts +17 -7
  290. package/dist/components/richTextEditor/RichTextEditor.d.cts.map +1 -1
  291. package/dist/components/richTextEditor/RichTextEditor.d.mts +17 -7
  292. package/dist/components/richTextEditor/RichTextEditor.d.mts.map +1 -1
  293. package/dist/components/richTextEditor/RichTextEditor.d.ts +17 -7
  294. package/dist/components/richTextEditor/RichTextEditor.d.ts.map +1 -1
  295. package/dist/components/richTextEditor/RichTextEditor.js +53 -206
  296. package/dist/components/richTextEditor/RichTextEditor.js.map +3 -3
  297. package/dist/components/richTextEditor/editorTokens.cjs +75 -0
  298. package/dist/components/richTextEditor/editorTokens.cjs.map +7 -0
  299. package/dist/components/richTextEditor/editorTokens.d.cts +21 -0
  300. package/dist/components/richTextEditor/editorTokens.d.cts.map +1 -0
  301. package/dist/components/richTextEditor/editorTokens.d.mts +21 -0
  302. package/dist/components/richTextEditor/editorTokens.d.mts.map +1 -0
  303. package/dist/components/richTextEditor/editorTokens.d.ts +21 -0
  304. package/dist/components/richTextEditor/editorTokens.d.ts.map +1 -0
  305. package/dist/components/richTextEditor/editorTokens.js +55 -0
  306. package/dist/components/richTextEditor/editorTokens.js.map +7 -0
  307. package/dist/components/scroll-area.css +12 -0
  308. package/dist/components/scrollArea/ScrollArea.cjs +12 -1
  309. package/dist/components/scrollArea/ScrollArea.cjs.map +2 -2
  310. package/dist/components/scrollArea/ScrollArea.d.cts.map +1 -1
  311. package/dist/components/scrollArea/ScrollArea.d.mts.map +1 -1
  312. package/dist/components/scrollArea/ScrollArea.d.ts.map +1 -1
  313. package/dist/components/scrollArea/ScrollArea.js +12 -1
  314. package/dist/components/scrollArea/ScrollArea.js.map +2 -2
  315. package/dist/components/segmentedControl/SegmentedControl.cjs +2 -2
  316. package/dist/components/segmentedControl/SegmentedControl.cjs.map +2 -2
  317. package/dist/components/segmentedControl/SegmentedControl.d.cts.map +1 -1
  318. package/dist/components/segmentedControl/SegmentedControl.d.mts.map +1 -1
  319. package/dist/components/segmentedControl/SegmentedControl.d.ts.map +1 -1
  320. package/dist/components/segmentedControl/SegmentedControl.js +2 -2
  321. package/dist/components/segmentedControl/SegmentedControl.js.map +2 -2
  322. package/dist/components/separator.css +3 -9
  323. package/dist/components/sidebar/Sidebar.cjs +17 -5
  324. package/dist/components/sidebar/Sidebar.cjs.map +2 -2
  325. package/dist/components/sidebar/Sidebar.d.cts +12 -1
  326. package/dist/components/sidebar/Sidebar.d.cts.map +1 -1
  327. package/dist/components/sidebar/Sidebar.d.mts +12 -1
  328. package/dist/components/sidebar/Sidebar.d.mts.map +1 -1
  329. package/dist/components/sidebar/Sidebar.d.ts +12 -1
  330. package/dist/components/sidebar/Sidebar.d.ts.map +1 -1
  331. package/dist/components/sidebar/Sidebar.js +17 -5
  332. package/dist/components/sidebar/Sidebar.js.map +2 -2
  333. package/dist/components/sidebar/sidebar.props.cjs +8 -1
  334. package/dist/components/sidebar/sidebar.props.cjs.map +2 -2
  335. package/dist/components/sidebar/sidebar.props.d.cts +9 -1
  336. package/dist/components/sidebar/sidebar.props.d.cts.map +1 -1
  337. package/dist/components/sidebar/sidebar.props.d.mts +9 -1
  338. package/dist/components/sidebar/sidebar.props.d.mts.map +1 -1
  339. package/dist/components/sidebar/sidebar.props.d.ts +9 -1
  340. package/dist/components/sidebar/sidebar.props.d.ts.map +1 -1
  341. package/dist/components/sidebar/sidebar.props.js +8 -1
  342. package/dist/components/sidebar/sidebar.props.js.map +2 -2
  343. package/dist/components/sidebar.css +86 -13
  344. package/dist/components/sonner.css +78 -16
  345. package/dist/components/stepper.css +23 -12
  346. package/dist/components/tab-nav.css +25 -13
  347. package/dist/components/tabNav/TabNav.cjs +1 -4
  348. package/dist/components/tabNav/TabNav.cjs.map +2 -2
  349. package/dist/components/tabNav/TabNav.d.cts.map +1 -1
  350. package/dist/components/tabNav/TabNav.d.mts.map +1 -1
  351. package/dist/components/tabNav/TabNav.d.ts.map +1 -1
  352. package/dist/components/tabNav/TabNav.js +1 -4
  353. package/dist/components/tabNav/TabNav.js.map +2 -2
  354. package/dist/components/table-of-contents.css +12 -2
  355. package/dist/components/tableOfContents/TableOfContents.cjs +11 -4
  356. package/dist/components/tableOfContents/TableOfContents.cjs.map +2 -2
  357. package/dist/components/tableOfContents/TableOfContents.d.cts.map +1 -1
  358. package/dist/components/tableOfContents/TableOfContents.d.mts.map +1 -1
  359. package/dist/components/tableOfContents/TableOfContents.d.ts.map +1 -1
  360. package/dist/components/tableOfContents/TableOfContents.js +11 -4
  361. package/dist/components/tableOfContents/TableOfContents.js.map +2 -2
  362. package/dist/components/tabs/Tabs.cjs +39 -54
  363. package/dist/components/tabs/Tabs.cjs.map +2 -2
  364. package/dist/components/tabs/Tabs.d.cts.map +1 -1
  365. package/dist/components/tabs/Tabs.d.mts.map +1 -1
  366. package/dist/components/tabs/Tabs.d.ts.map +1 -1
  367. package/dist/components/tabs/Tabs.js +39 -54
  368. package/dist/components/tabs/Tabs.js.map +2 -2
  369. package/dist/components/tabs.css +52 -7
  370. package/dist/components/text/text.props.cjs +9 -9
  371. package/dist/components/text/text.props.cjs.map +2 -2
  372. package/dist/components/text/text.props.d.cts +42 -43
  373. package/dist/components/text/text.props.d.cts.map +1 -1
  374. package/dist/components/text/text.props.d.mts +42 -43
  375. package/dist/components/text/text.props.d.mts.map +1 -1
  376. package/dist/components/text/text.props.d.ts +42 -43
  377. package/dist/components/text/text.props.d.ts.map +1 -1
  378. package/dist/components/text/text.props.js +9 -9
  379. package/dist/components/text/text.props.js.map +2 -2
  380. package/dist/components/text/typography.props.cjs +32 -0
  381. package/dist/components/text/typography.props.cjs.map +7 -0
  382. package/dist/components/text/typography.props.d.cts +3 -0
  383. package/dist/components/text/typography.props.d.cts.map +1 -0
  384. package/dist/components/text/typography.props.d.mts +3 -0
  385. package/dist/components/text/typography.props.d.mts.map +1 -0
  386. package/dist/components/text/typography.props.d.ts +3 -0
  387. package/dist/components/text/typography.props.d.ts.map +1 -0
  388. package/dist/components/text/typography.props.js +12 -0
  389. package/dist/components/text/typography.props.js.map +7 -0
  390. package/dist/components/text-field.css +1 -0
  391. package/dist/components/text.css +41 -6
  392. package/dist/components/theme-panel.css +6 -0
  393. package/dist/components/toast/Toast.cjs +3 -1
  394. package/dist/components/toast/Toast.cjs.map +2 -2
  395. package/dist/components/toast/Toast.d.cts.map +1 -1
  396. package/dist/components/toast/Toast.d.mts.map +1 -1
  397. package/dist/components/toast/Toast.d.ts.map +1 -1
  398. package/dist/components/toast/Toast.js +3 -1
  399. package/dist/components/toast/Toast.js.map +2 -2
  400. package/dist/components/toast.css +36 -36
  401. package/dist/components/toggle-tip.css +58 -9
  402. package/dist/components/toggleTip/ToggleTip.cjs +9 -5
  403. package/dist/components/toggleTip/ToggleTip.cjs.map +2 -2
  404. package/dist/components/toggleTip/ToggleTip.d.cts.map +1 -1
  405. package/dist/components/toggleTip/ToggleTip.d.mts.map +1 -1
  406. package/dist/components/toggleTip/ToggleTip.d.ts.map +1 -1
  407. package/dist/components/toggleTip/ToggleTip.js +9 -5
  408. package/dist/components/toggleTip/ToggleTip.js.map +2 -2
  409. package/dist/components/toolbar/Toolbar.cjs +10 -7
  410. package/dist/components/toolbar/Toolbar.cjs.map +2 -2
  411. package/dist/components/toolbar/Toolbar.js +10 -7
  412. package/dist/components/toolbar/Toolbar.js.map +2 -2
  413. package/dist/components/toolbar.css +58 -4
  414. package/dist/components/tooltip.css +9 -5
  415. package/dist/components/tree-view.css +17 -3
  416. package/dist/components/treeView/TreeView.cjs +76 -21
  417. package/dist/components/treeView/TreeView.cjs.map +2 -2
  418. package/dist/components/treeView/TreeView.d.cts.map +1 -1
  419. package/dist/components/treeView/TreeView.d.mts.map +1 -1
  420. package/dist/components/treeView/TreeView.d.ts.map +1 -1
  421. package/dist/components/treeView/TreeView.js +76 -21
  422. package/dist/components/treeView/TreeView.js.map +2 -2
  423. package/dist/components.css +2 -0
  424. package/dist/docs/README.md +2 -0
  425. package/dist/docs/component-contract.md +7 -4
  426. package/dist/docs/component-index.json +17 -1
  427. package/dist/docs/components/accordion.md +5 -36
  428. package/dist/docs/components/alert.md +44 -17
  429. package/dist/docs/components/article-nodes.md +59 -2
  430. package/dist/docs/components/aspect-ratio.md +3 -26
  431. package/dist/docs/components/banner.md +7 -7
  432. package/dist/docs/components/blockquote.md +15 -14
  433. package/dist/docs/components/bottom-dock.md +146 -0
  434. package/dist/docs/components/box.md +3 -34
  435. package/dist/docs/components/breadcrumb.md +13 -8
  436. package/dist/docs/components/callout.md +18 -7
  437. package/dist/docs/components/card.md +10 -3
  438. package/dist/docs/components/code.md +33 -220
  439. package/dist/docs/components/collapsible.md +16 -35
  440. package/dist/docs/components/command.md +2 -0
  441. package/dist/docs/components/comment-thread.md +51 -1
  442. package/dist/docs/components/config-drawer.md +72 -171
  443. package/dist/docs/components/container.md +2 -0
  444. package/dist/docs/components/context-menu.md +19 -5
  445. package/dist/docs/components/dialog.md +4 -2
  446. package/dist/docs/components/drawer.md +17 -6
  447. package/dist/docs/components/dropdown-menu.md +11 -2
  448. package/dist/docs/components/em.md +1 -1
  449. package/dist/docs/components/environment-ribbon.md +126 -0
  450. package/dist/docs/components/field.md +2 -0
  451. package/dist/docs/components/file-upload.md +13 -7
  452. package/dist/docs/components/floating-panel.md +79 -285
  453. package/dist/docs/components/form.md +4 -0
  454. package/dist/docs/components/grid.md +11 -60
  455. package/dist/docs/components/heading.md +35 -32
  456. package/dist/docs/components/hover-card.md +9 -1
  457. package/dist/docs/components/icon.md +1 -0
  458. package/dist/docs/components/kbd.md +2 -0
  459. package/dist/docs/components/label.md +11 -9
  460. package/dist/docs/components/link.md +31 -209
  461. package/dist/docs/components/notification-center.md +30 -15
  462. package/dist/docs/components/page-header.md +20 -6
  463. package/dist/docs/components/pagination.md +4 -0
  464. package/dist/docs/components/pills.md +13 -4
  465. package/dist/docs/components/popover.md +10 -3
  466. package/dist/docs/components/prose.md +9 -0
  467. package/dist/docs/components/qr-code.md +12 -12
  468. package/dist/docs/components/quote.md +9 -4
  469. package/dist/docs/components/resizable.md +26 -18
  470. package/dist/docs/components/rich-text-editor.md +68 -18
  471. package/dist/docs/components/scroll-area.md +17 -9
  472. package/dist/docs/components/section.md +3 -38
  473. package/dist/docs/components/segmented-control.md +1 -1
  474. package/dist/docs/components/segmented-meter.md +9 -0
  475. package/dist/docs/components/separator.md +10 -46
  476. package/dist/docs/components/sidebar.md +34 -9
  477. package/dist/docs/components/sonner.md +25 -16
  478. package/dist/docs/components/stepper.md +8 -33
  479. package/dist/docs/components/strong.md +1 -1
  480. package/dist/docs/components/tab-nav.md +33 -96
  481. package/dist/docs/components/table-of-contents.md +8 -2
  482. package/dist/docs/components/tabs.md +19 -50
  483. package/dist/docs/components/text-field.md +1 -0
  484. package/dist/docs/components/text.md +34 -28
  485. package/dist/docs/components/theme-panel.md +3 -28
  486. package/dist/docs/components/theme.md +7 -3
  487. package/dist/docs/components/toast.md +27 -13
  488. package/dist/docs/components/toggle-tip.md +58 -241
  489. package/dist/docs/components/toolbar.md +16 -39
  490. package/dist/docs/components/tooltip.md +13 -7
  491. package/dist/docs/components/tree-view.md +22 -55
  492. package/dist/docs/consumer-guide.md +11 -4
  493. package/dist/generated/tokens.cjs +1 -0
  494. package/dist/generated/tokens.cjs.map +2 -2
  495. package/dist/generated/tokens.d.cts.map +1 -1
  496. package/dist/generated/tokens.d.mts.map +1 -1
  497. package/dist/generated/tokens.d.ts.map +1 -1
  498. package/dist/generated/tokens.js +1 -0
  499. package/dist/generated/tokens.js.map +2 -2
  500. package/dist/styles.css +1921 -1349
  501. package/dist/tokens.css +346 -362
  502. package/package.json +1 -1
@@ -107,7 +107,7 @@ Rules:
107
107
 
108
108
  **Responsive behavior:**
109
109
 
110
- - The component does not write `@media` rules. The motion and layout are single-value only.
110
+ - The component does not use width breakpoints. The motion and layout are single-value only.
111
111
 
112
112
  **Reduced motion:**
113
113
 
@@ -132,7 +132,7 @@ Every CSS value the component paints is a `var(--dsx-*)` token.
132
132
  | Trigger color | `var(--dsx-color-on-surface)` | Closed trigger text |
133
133
  | Trigger padding | `var(--dsx-space-md)` | Internal gutter |
134
134
  | Trigger label type | `var(--dsx-typography-label-large-font-family)`, `var(--dsx-typography-label-large-font-size)` | Trigger text ramp |
135
- | Trigger open color | `var(--dsx-color-primary)` | Open trigger text |
135
+ | Trigger open color | `var(--dsx-color-accent-indicator)` | Open trigger text |
136
136
  | Trigger focus ring | `var(--dsx-shadow-focus-ring)` | Focus indicator |
137
137
  | Chevron size | `var(--dsx-space-lg)` | Chevron icon size |
138
138
  | Chevron transition | `var(--dsx-motion-duration-fast) var(--dsx-motion-easing-in-out)` | Rotate transition |
@@ -183,42 +183,11 @@ Every CSS value the component paints is a `var(--dsx-*)` token.
183
183
 
184
184
  - `Accordion.Trigger` is the interactive element; the consumer's `children` become the button's accessible name. `Accordion.Header` should be associated with its `Content` via Radix's pairing, not via consumer-supplied `aria-*` attributes.
185
185
 
186
- ## Playground demo spec
187
-
188
- **Default story:**
189
-
190
- - Renders `Accordion` with `type="single"`, `collapsible`, and two items. Asserts the root class is `dsx-accordion` and triggers render with the chevron icon.
191
-
192
- **State story:**
193
-
194
- - Renders with `type="single"`, `defaultValue="item-1"`. Asserts the open trigger carries `data-state="open"` and the open content is visible.
195
- - Renders with `type="multiple"`, `defaultValue={["item-1", "item-2"]}`. Asserts both items expand at once.
196
-
197
- **Disabled story:**
198
-
199
- - Renders the root with `disabled`. Asserts every trigger is disabled and `useAccordionStyles()` reports `disabled: true` to descendants.
200
-
201
- **Composition story:**
186
+ The live example groups project questions with single-open behavior, separate multiple-open disclosures and a disabled item. Warp and ray examples start expanded so accent-indicator text and chevrons are visible; no global alpha/token values change.
202
187
 
203
- - Renders the default trigger and asserts exactly one built-in indicator.
204
- - Renders `indicator={false}` and a custom indicator node to demonstrate the supported ownership choices.
205
- - Compatibility tests keep `Accordion.ItemBody` and `Accordion.ItemIndicator` available without presenting them as the canonical composition.
206
-
207
- **Token story:**
208
-
209
- - Renders inside a `Theme` wrapper with `accentColor="silver"` and `accentColor="bronze"`. Accordion does not track `data-accent-color`; the story asserts the open trigger color continues to resolve through `var(--dsx-color-primary)`.
210
-
211
- **A11y story:**
212
-
213
- - Uses `vitest-axe` against the rendered default story. Asserts no axe violations.
214
-
215
- **Props exposed in the playground controls:**
188
+ ## Playground demo spec
216
189
 
217
- | Prop | Control | Default |
218
- |---|---|---|
219
- | `type` | select | `single` |
220
- | `collapsible` | boolean | `true` |
221
- | `disabled` | boolean | `false` |
190
+ The matrix presents a working two-item single-open accordion. The live example has a project-question accordion (one initially open, one closed, one disabled), a multiple-open example with a no-indicator trigger, and warp/ray disclosures initialized open. Open labels and chevrons consume accent-indicator. Keyboard and pointer actions change aria-expanded and reveal the corresponding content.
222
191
 
223
192
  ## Wiring notes
224
193
 
@@ -4,7 +4,6 @@ status: canonical
4
4
  category: Components
5
5
  archetype: composite
6
6
  depends_on:
7
- - Card
8
7
  - Icon
9
8
  - Button
10
9
  ---
@@ -19,26 +18,29 @@ An inline status, warning, or info banner that lives in the page flow. Use Alert
19
18
 
20
19
  ## Anatomy & slots
21
20
 
22
- **Parent:** `Alert` (alias of `AlertRoot`). The root is a thin wrapper around `CardRoot`; it composes the card surface and adds the alert-specific layout, icon, and content slots.
21
+ **Parent:** `Alert` (alias of `AlertRoot`). The root owns a static status surface, using the existing shared card surface tokens without a clickable Card host. Icon, content and actions retain their named slots. With `asChild`, one consumer element becomes the host and its children are wrapped in the content slot; icon and forwarded ref remain on that same host.
23
22
 
24
23
  **Slots:**
25
24
 
26
25
  | Slot | Element | Renders | Notes |
27
26
  |---|---|---|---|
28
- | `Alert` (root) | `<div>` (or `Slot` host) | `CardRoot` + class | Renders the surface as a Card and overlays the alert-specific class. Writes `dsx-alert`, `data-variant`, `data-size`, `data-high-contrast`, `data-accent-color`. Defaults `role` to `"alert"`; consumers can override with a custom `role` prop. |
27
+ | `Alert` (root) | `<div>` (or `Slot` host) | Static surface + class | Writes `dsx-alert`, `data-variant`, `data-size`, `data-high-contrast`, `data-accent-color`. Defaults `role` to `"alert"`; consumers can override with a custom `role` prop. Hovering the status surface does not change its semantic color or elevation. |
29
28
  | `Alert.Title` | `<h5>` (or `Slot` host) | Slot class | Title text. Writes `dsx-alert__title`. |
30
29
  | `Alert.Description` | `<p>` (or `Slot` host) | Slot class | Description text. Writes `dsx-alert__description`. |
31
- | `Alert.Action` | `<div>` | Slot class | Trailing action container (typically a Button or IconButton). Writes `dsx-alert__action`. |
30
+ | `Alert.Action` | `<div>` | Slot class | Trailing action container (typically a Button or IconButton). Writes `dsx-alert__action`. A direct child of `Alert` is hoisted out of the content container into one `dsx-alert__actions` group: the group trails the row, and wraps below the text as a whole, under the text, when the alert is narrow. |
32
31
 
33
32
  **Internal layout:**
34
33
 
35
- The root renders a flex row with three regions, in this order:
34
+ The root renders a flex row of two columns, in this order:
36
35
 
37
36
  1. An icon container (`<span aria-hidden="true" class="dsx-alert__icon">`) that holds the resolved icon. The icon is hidden when `icon === null` and replaced wholesale when `icon` is a `ReactNode`.
38
- 2. A content container (`<div class="dsx-alert__content">`) that wraps whatever the consumer passes as children (typically `Alert.Title` and `Alert.Description`).
39
- 3. The optional `Alert.Action` slot, if the consumer composes it as a child.
37
+ 2. A main column (`<div class="dsx-alert__main">`), a wrapping flex row, that holds:
38
+ 1. a content container (`<div class="dsx-alert__content">`) that wraps whatever the consumer passes as children (typically `Alert.Title` and `Alert.Description`);
39
+ 2. when there is at least one direct-child `Alert.Action`, one actions group (`<div class="dsx-alert__actions">`) that holds each of them, in order.
40
40
 
41
- The `Alert.Action` slot is independent of the rest of the layout; the consumer can place it inside the content area or as a sibling of `Alert.Title` / `Alert.Description` to control alignment.
41
+ A direct-child `Alert.Action` is hoisted out of the content container (`Alert.Title` and `Alert.Description` stay inside it), also when the root is an `asChild` host. The group trails the row (the content grows to push it to the end). Only the main column wraps (`flex-wrap`), so when the text would fall under its readable width the group drops below it as a whole and starts at the text column, under the text and not under the icon; the actions never split across rows. The group has no auto margin, because that would push a wrapped group to the far edge. An action the consumer nests in their own wrapper is not hoisted and stays in the content container. (G-15, 2026-10-05.)
42
+
43
+ With a trailing action, the icon, the first line of text and the action share one centre at any width: all three get a control-height row (`var(--dsx-size-lg)`), and the first line's box is that tall (`::first-line`). An alert without an action is laid out as before.
42
44
 
43
45
  ## Props contract
44
46
 
@@ -46,7 +48,7 @@ The `Alert.Action` slot is independent of the rest of the layout; the consumer c
46
48
 
47
49
  | Prop | Type | Default | Required | Description | Responsive |
48
50
  |---|---|---|---|---|---|
49
- | `variant` | `'default' \| 'destructive' \| 'success' \| 'warning'` | `'default'` | no | Visual tone; writes `data-variant`. The base CSS sets a color per variant; `default` and `warning` use the primary palette, `destructive` uses the error palette, and `success` uses the success palette. | no |
51
+ | `variant` | `'default' \| 'destructive' \| 'success' \| 'warning'` | `'default'` | no | Visual tone; writes `data-variant`. The base CSS sets a color per variant; `default` uses the primary palette and `warning` uses the warning palette, `destructive` uses the error palette, and `success` uses the success palette. | no |
50
52
  | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | no | Padding scale; writes `data-size`. | no |
51
53
  | `color` | `string` | `undefined` | no | Free-form accent override; writes `data-accent-color` when provided. | no |
52
54
  | `highContrast` | `boolean` | `false` | no | When `true`, swaps the surface and border to `var(--dsx-color-high-contrast-container)` and `var(--dsx-color-high-contrast-border)`; writes `data-high-contrast="true"`. | no |
@@ -64,6 +66,12 @@ The `Alert.Action` slot is independent of the rest of the layout; the consumer c
64
66
 
65
67
  `Alert.Title` and `Alert.Description` also accept the standard HTML attributes for their host elements (`<h5>` and `<p>` respectively). `Alert.Action` accepts standard `<div>` attributes.
66
68
 
69
+ **`Alert.Description` own prop:**
70
+
71
+ | Prop | Type | Default | Required | Description | Responsive |
72
+ |---|---|---|---|---|---|
73
+ | `lineClamp` | `number` | `undefined` | no | Clamp the text to this many lines; the rest is clipped with an ellipsis. Only a whole number of 1 or more clamps; anything else (0, a negative, a fraction, `NaN`) leaves the text unclamped. Writes `data-line-clamp` and the custom property `--dsx-alert-line-clamp` on the description (a consumer `style` is kept); the prop name itself is not written to the DOM. Whether the text is clipped, and how to reveal it, is the consumer's: measure the element (`scrollHeight > clientHeight`) and drop the prop to show everything. | no |
74
+
67
75
  **Variant default icons (when `icon` is `undefined`):**
68
76
 
69
77
  | `variant` | Icon `name` |
@@ -77,16 +85,17 @@ The icon is rendered with `size="md"` and `strokeWidth="var(--dsx-icon-stroke-wi
77
85
 
78
86
  ## CSS class contract
79
87
 
80
- **Root class:** `dsx-alert` (composed on top of the Card root class)
88
+ **Root class:** `dsx-alert` (static native or Slot host; no interactive Card class)
81
89
 
82
90
  **Modifier classes** (driven by `data-*` attributes written by the component):
83
91
 
84
92
  | Attribute | Allowed values | Class | CSS file |
85
93
  |---|---|---|---|
86
94
  | `data-variant` | `default`, `destructive`, `success`, `warning` | `.dsx-alert[data-variant='destructive']`, `.dsx-alert[data-variant='error']`, `.dsx-alert[data-variant='success']`, `.dsx-alert[data-variant='warning']` | `baseCard.css` |
87
- | `data-size` | `sm`, `md`, `lg` | (inherits Card size) | `baseCard.css` |
95
+ | `data-size` | `sm`, `md`, `lg` | `.dsx-alert[data-size=…]` | `alert.css` |
88
96
  | `data-accent-color` | any string | (no rule in `alert.css`; attribute is forwarded) | n/a |
89
97
  | `data-high-contrast` | `true` | `.dsx-alert[data-high-contrast='true']` | `baseCard.css` |
98
+ | `data-line-clamp` (on `Alert.Description`) | a whole number of 1 or more | `.dsx-alert__description[data-line-clamp]` | `alert.css` |
90
99
 
91
100
  **Slot classes:**
92
101
 
@@ -94,14 +103,16 @@ The icon is rendered with `size="md"` and `strokeWidth="var(--dsx-icon-stroke-wi
94
103
  |---|---|---|
95
104
  | `Alert` (root) | `dsx-alert` | `alert.css` |
96
105
  | Root icon container | `dsx-alert__icon` | `alert.css` |
106
+ | Root main column (content and actions) | `dsx-alert__main` | `alert.css` |
97
107
  | Root content container | `dsx-alert__content` | `alert.css` |
108
+ | Root actions group | `dsx-alert__actions` | `alert.css` |
98
109
  | `Alert.Action` | `dsx-alert__action` | `alert.css` |
99
110
  | `Alert.Title` | `dsx-alert__title` | `alert.css` |
100
111
  | `Alert.Description` | `dsx-alert__description` | `alert.css` |
101
112
 
102
113
  **Responsive behavior:**
103
114
 
104
- - The component does not write `@media` rules. `size`, `variant`, `color`, and `highContrast` are single-value only.
115
+ - The component does not write `@media` rules. `size`, `variant`, `color`, and `highContrast` are single-value only. The action wrap is intrinsic (`flex-wrap` on the main column), not a breakpoint, so it follows the alert's own width, not the window's.
105
116
 
106
117
  **Reduced motion:**
107
118
 
@@ -121,12 +132,16 @@ Every CSS value the component paints is a `var(--dsx-*)` token.
121
132
  | Root text color | `var(--dsx-color-on-surface)` | Default text color |
122
133
  | Icon / action minimum size | `var(--dsx-size-md)` | Icon and action slot dimensions |
123
134
  | Icon / action color | `currentColor` | Inherits the alert surface color |
135
+ | Content basis | `min(calc(var(--dsx-size-xl) * 5), calc(100% - var(--dsx-size-md) - var(--dsx-space-md)))` | The readable width the text keeps before a trailing action wraps below it; the `min()` stops it forcing the text under the icon in a very narrow alert |
136
+ | Control row (with an action) | `var(--dsx-size-lg)` | Min height of the icon and action, and the line box of the first line, so the three share a centre |
137
+ | Clamped first line (with an action) | `padding-block-start: calc((var(--dsx-size-lg) - 1lh) / 2)` | `::first-line` cannot reach into the `-webkit-box` a clamped description is, so the first line is centred on the control row with padding instead |
138
+ | Line clamp | `--dsx-alert-line-clamp` (written by the component from `lineClamp`) | The number of lines the description keeps; read by `-webkit-line-clamp` |
124
139
  | Title type ramp | `var(--dsx-typography-label-large-*)` | Title text scale |
125
140
  | Description type ramp | `var(--dsx-typography-body-medium-*)` | Description text scale |
126
141
  | Description opacity | `var(--dsx-opacity-subtle, 0.85)` | Subtle fade for description text |
127
142
  | Destructive surface | `var(--dsx-color-error-container)`, `var(--dsx-color-on-error-container)`, `var(--dsx-color-error)` (border) | Destructive palette |
128
143
  | Success surface | `var(--dsx-color-success-container)`, `var(--dsx-color-on-success-container)`, `var(--dsx-color-success)` (border) | Success palette |
129
- | Warning surface | `var(--dsx-color-primary-container)`, `var(--dsx-color-on-primary-container)`, `var(--dsx-color-primary)` (border) | Warning palette (primary palette) |
144
+ | Warning surface | `var(--dsx-color-warning-container)`, `var(--dsx-color-on-warning-container)`, `var(--dsx-color-warning)` (border) | Warning palette |
130
145
  | High-contrast surface | `var(--dsx-color-high-contrast-container)`, `var(--dsx-color-high-contrast-border)`, `var(--dsx-color-high-contrast)` (text) | High-contrast palette |
131
146
 
132
147
  ## Motion contract
@@ -159,7 +174,7 @@ The component has no motion. It is a static inline surface.
159
174
 
160
175
  **Color and meaning:**
161
176
 
162
- - Variant tone is communicated by both color and icon: `success` uses the success palette and a `check-circle` icon, `destructive` uses the error palette and an `alert-triangle` icon, `warning` uses the primary palette and an `alert-triangle` icon, and `default` uses the base palette and an `info` icon.
177
+ - Variant tone is communicated by both color and icon: `success` uses the success palette and a `check-circle` icon, `destructive` uses the error palette and an `alert-triangle` icon, `warning` uses the warning palette and an `alert-triangle` icon, and `default` uses the base palette and an `info` icon.
163
178
 
164
179
  **Naming:**
165
180
 
@@ -187,11 +202,15 @@ The component has no motion. It is a static inline surface.
187
202
 
188
203
  **Composition story:**
189
204
 
190
- - Renders an alert with `Alert.Title`, `Alert.Description`, and `Alert.Action` populated. Asserts the `dsx-alert__title`, `dsx-alert__description`, and `dsx-alert__action` classes are present.
205
+ - Renders an alert with `Alert.Title`, `Alert.Description`, and `Alert.Action` populated. Asserts the `dsx-alert__title`, `dsx-alert__description`, and `dsx-alert__action` classes are present, and that the action sits in the one `dsx-alert__actions` group after the content container inside `dsx-alert__main`, not inside the content (several actions share the one group). `src/test/styles/alert-wrap-layout.test.ts` guards the rules that make the group wrap as a whole under the text column. A second composition nests the action in the consumer's own wrapper and asserts it stays in the content.
206
+
207
+ **Clamp story:**
208
+
209
+ - Renders an alert whose `Alert.Description` has `lineClamp={2}` and a long text, with a trailing action. Asserts `data-line-clamp="2"` and the `--dsx-alert-line-clamp` property; the registry row shows the text clipped to two lines with an ellipsis and the icon, first line and action on one centre. A value that is not a whole number of 1 or more leaves the text unclamped (tested).
191
210
 
192
211
  **Token story:**
193
212
 
194
- - Renders inside a `Theme` wrapper with `accentColor="silver"` and `accentColor="bronze"`. Asserts the destructive and success surfaces are unchanged because they read from the error and success palettes, not the accent palette.
213
+ - Renders inside a `Theme` wrapper with `accentColor="astral"` and `accentColor="spark"`. Asserts the destructive and success surfaces are unchanged because they read from the error and success palettes, not the accent palette.
195
214
 
196
215
  **A11y story:**
197
216
 
@@ -210,7 +229,7 @@ The component has no motion. It is a static inline surface.
210
229
 
211
230
  **Composes from:**
212
231
 
213
- - `Card` (`CardRoot`): the alert root is a `CardRoot asChild` wrapper. The alert inherits the card surface treatment and the Card size, variant, and high-contrast data attributes.
232
+ - `baseCard.css`: supplies the existing static Alert surface, semantic status palettes and high-contrast treatment. The root does not participate in interactive Card hover styling.
214
233
  - `Icon`: renders the variant default icon and any consumer-supplied icon node.
215
234
  - `@radix-ui/react-slot`: enables `asChild` on the root and on `Alert.Title` / `Alert.Description`.
216
235
 
@@ -227,3 +246,11 @@ The component has no motion. It is a static inline surface.
227
246
 
228
247
  - App-owned data: the alert message text, the action, the dismiss/timeout behavior, and the analytics events.
229
248
  - DS-owned visuals: token bindings, slot classes, icon name resolution, and the surface palette per variant.
249
+
250
+ ## Overlay review composition
251
+
252
+ Content has min-width=0 and wraps long copy; the optional icon does not shrink.
253
+ A trailing action shares the row with the text and wraps below it, at the alert's start edge, when the text would drop under its readable width. Light-mode semantic borders retain
254
+ warning/success/error roles after the shared card base rules. Default accent
255
+ styling and highContrast remain token-driven. `/docs/alert` demonstrates all
256
+ four tones, reconnect feedback and dismiss/restore through real actions.
@@ -3,7 +3,7 @@ title: ArticleNodes
3
3
  status: canonical
4
4
  category: Components
5
5
  archetype: adapter-backed
6
- depends_on: ["@tiptap/core", "@tiptap/extension-image", "@tiptap/extension-table", "@tiptap/extension-code-block-lowlight", "lowlight"]
6
+ depends_on: ["@tiptap/core", "@tiptap/react", "@tiptap/extension-image", "@tiptap/extension-table", "@tiptap/extension-code-block-lowlight", "lowlight"]
7
7
  ---
8
8
 
9
9
  # ArticleNodes
@@ -22,6 +22,63 @@ The package exports `ArticleImage`, `ArticleEmbed`, `BeforeAfterComparison`, and
22
22
 
23
23
  Read-side renderers are available from the root and `components` barrels and from the dedicated `@d4gger/design-system/article-nodes` subpath. Tiptap-backed authoring extensions are isolated at `@d4gger/design-system/article-extensions`, so importing the root package never requires the optional Tiptap peers.
24
24
 
25
+ ## Read renderer contracts
26
+
27
+ - `ArticleImage` accepts native image attributes and optional React-node `caption`.
28
+ Its root is a figure; `className` and native attributes belong to the image.
29
+ Alt defaults to an empty string. A supplied caption renders as figcaption.
30
+ - `ArticleEmbed` accepts `url`, optional `isAllowed(canonicalUrl)` and optional
31
+ `render(canonicalUrl)`, plus native div attributes. Only absolute HTTP(S) URLs
32
+ survive canonicalization. Rejected URLs render `Embed unavailable` with role
33
+ alert; no render callback or link is emitted. Without a render callback an
34
+ allowed URL is a native anchor. The allowed root carries `data-dsx-url`.
35
+ - `BeforeAfterComparison` accepts both sources and alt values, optional React-node
36
+ labels (defaults `Before`/`After`) and native figure attributes. It is a two-column
37
+ comparison, not an interactive slider. Images scale within zero-minimum tracks;
38
+ the minimum child width and scroll container preserve reachability in very tight hosts.
39
+ - `ArticlePoll` accepts a persistent `pollId`, optional question/options and
40
+ controlled `state` (`loading`, `ready`, `error`, `voted`, `closed`; default `ready`).
41
+ `onLoad(pollId)` runs on mount and when the ID or callback changes.
42
+ `onVote(pollId, optionId)` runs only through enabled ready-state options.
43
+ Vote totals are optional display metadata, not package-owned tally state.
44
+ Loading sets `aria-busy`; error renders an alert; loading/closed options are disabled; legacy voted options are disabled. Controlled selection permits vote changes.
45
+
46
+ ## Paint and accessibility
47
+
48
+ Media retain figure/caption semantics and consumer-supplied alt text. Embed/poll
49
+ shells use raised surface, semantic outline, medium radius/padding and small gaps.
50
+ Long labels and URLs wrap. Poll options compose the existing outline Button at
51
+ large size through `dsx-article-poll__option`; Button owns keyboard activation,
52
+ focus, disabled paint and target dimensions (44px at comfortable density).
53
+ No renderer introduces component breakpoints, portal behavior or motion.
54
+
25
55
  ## Playground demo spec
26
56
 
27
- Show each renderer, missing media, invalid embed, comparison at mobile width, and poll loading, error, ready, and voted states.
57
+ `/docs/article-nodes` composes `blocks-examples.tsx` through the display registry:
58
+ local loaded image/caption, distinct extra-relay/direct-route comparison, a
59
+ consumer-rendered link preview, invalid/disallowed embeds, an app-owned unavailable
60
+ media Callout and poll loading/error/ready/voted states. The ready poll updates its
61
+ results and can reset. The app fallback example does not add a package image-error API.
62
+
63
+ ## Authoring enhancement — approved 2026-10-04
64
+
65
+ The optional article extension bundle supplies editable React node views for
66
+ image/caption, embed, comparison, callout and poll, plus video, material reference
67
+ and platform tabs. Block controls are visible on touch: edit, move up/down and
68
+ remove; inline fields update node attributes. Block mutation controls track editor editability, and mutation callbacks guard
69
+ read-only state. Node-view UI is absent from saved HTML. `createArticleExtensions({ editable: false })` disables authoring node views.
70
+ Inline variables/mentions remain opt-in editor extensions, outside article policy.
71
+
72
+ Media retain optional `mediaId` alongside consumer-resolved `src`. Apps own URL
73
+ refresh, uploads, allowlists and conversion into versioned backend documents.
74
+ Poll nodes retain `pollId`, `question`, stable option `id`/`label` records and
75
+ `multiple`. Apps supply IDs at insertion. Platform tabs contain editable block
76
+ content and a `platform` key, and preserve that structure in HTML/JSON.
77
+
78
+ Read exports add `ArticleVideo`, `ArticlePlatformTabs` and `ArticleMaterialLink`.
79
+ Video uses native controls and optional caption; tabs accept keyed content and
80
+ controlled selection; references expose an explicit unavailable state without a
81
+ resolved href. `ArticlePoll` adds controlled `selection`, `multiple`,
82
+ `onSelectionChange`, `onSubmit`, `onRetract`, optional `totalVotes` and closed state.
83
+ It displays supplied results before/after voting and supports change/retract. The
84
+ existing `onVote` immediate single-choice path remains the default.
@@ -103,34 +103,11 @@ Rules:
103
103
 
104
104
  - No accessible name is required by default. Consumers that constrain focusable media (video, iframe) should supply an `aria-label` on the inner element or a labelled wrapper.
105
105
 
106
- ## Playground demo spec
107
-
108
- **Default story:**
109
-
110
- - Renders `AspectRatio` with `ratio={16 / 9}` and a fixed width, so the height is computed automatically. Asserts the root class is `dsx-aspect-ratio`.
111
-
112
- **Composition story** (for `asChild`):
113
-
114
- - Renders AspectRatio with `asChild` wrapping a `<div>` element. Asserts the host element is `DIV` and the `dsx-aspect-ratio` class is preserved.
115
-
116
- **State story:**
117
-
118
- - Renders AspectRatio with `ratio={1}`, `ratio={4 / 3}`, and `ratio={16 / 9}`. Asserts the rendered height matches the width divided by the supplied ratio.
106
+ The live example shows the same inline SVG landscape cropped at 16:9, 1:1 and 4:3. All three frames have equal widths within the same row; the gallery stacks on narrow screens.
119
107
 
120
- **Token story:**
121
-
122
- - N/A. AspectRatio does not consume `data-accent-color`; the story documents that the rounded corner is token-driven and visually unchanged across accents.
123
-
124
- **A11y story:**
125
-
126
- - Uses `vitest-axe` against the rendered default aspect ratio. Asserts there are no axe violations.
127
-
128
- **Props exposed in the playground controls:**
108
+ ## Playground demo spec
129
109
 
130
- | Prop | Control | Default |
131
- |---|---|---|
132
- | `asChild` | boolean | `false` |
133
- | `ratio` | number | `1` |
110
+ The ratio matrix and live example use the same SVG landscape with cover cropping. The live gallery uses equal track widths for 16:9, 1:1 and 4:3, stacks at narrow widths, and labels each media use. Width is owned by the parent frame, never the inner Radix height box.
134
111
 
135
112
  ## Wiring notes
136
113
 
@@ -26,9 +26,9 @@ A hero mass: one label, one headline value, and an optional footnote over an acc
26
26
  | Slot | Element | Renders | Notes |
27
27
  |---|---|---|---|
28
28
  | `Banner.Root` | `<section>` | Hero surface + class | `role="group"`, consumer `aria-label`. Writes `dsx-banner`. Supports `asChild`. |
29
- | `Banner.Label` | `<span>` | Uppercase muted label + class | Renders `Text` label-small. Writes `dsx-banner__label`. |
29
+ | `Banner.Label` | `<span>` | Compact normal-case label + class | Renders `Text` label-small; the Banner slot owns the paired container ink. Writes `dsx-banner__label`. |
30
30
  | `Banner.Value` | `<span>` | Headline value + class | Uses a span with the display-medium token ramp. Writes `dsx-banner__value`. |
31
- | `Banner.Footnote` | `<span>` | Muted footnote + class | Renders `Text` body-small. Writes `dsx-banner__footnote`. Optional. |
31
+ | `Banner.Footnote` | `<span>` | Compact footnote + class | Renders `Text` body-small with paired container ink. Writes `dsx-banner__footnote`. Optional. |
32
32
 
33
33
  ## Props contract
34
34
 
@@ -69,18 +69,18 @@ Every CSS value the component paints is a `var(--dsx-*)` token.
69
69
 
70
70
  | Property | Token | Role |
71
71
  |---|---|---|
72
- | Root background | `var(--dsx-color-accent-surface)` | Hero wash (wash variant) |
72
+ | Root background | `var(--dsx-color-primary-container)` | Opaque soft accent container (wash variant); no additional alpha dilution. |
73
73
  | Fill background | `var(--dsx-color-accent-track)` | Solid accent mass (fill variant) |
74
74
  | Fill text | `var(--dsx-color-accent-contrast)` | Compliant text on fill (near-black on spark, white elsewhere) |
75
75
  | Root radius | `var(--dsx-rounded-lg)` | Hero corner roundness |
76
76
  | Root padding | `var(--dsx-space-lg)` | Hero internal spacing |
77
77
  | Root gap | `var(--dsx-space-xs)` | Stack rhythm label/value/footnote |
78
78
  | Label typography | `var(--dsx-typography-label-small-*)` | Label type scale |
79
- | Label color | `var(--dsx-color-on-surface-variant)` | Muted label on wash |
79
+ | Label color | `var(--dsx-color-on-primary-container)` | Paired label ink on wash |
80
80
  | Value typography | `var(--dsx-typography-display-medium-*)` | Headline value type scale |
81
- | Value color | `var(--dsx-color-on-surface)` | Value ink on wash |
81
+ | Value color | `var(--dsx-color-on-primary-container)` | Paired value ink on wash |
82
82
  | Footnote typography | `var(--dsx-typography-body-small-*)` | Footnote type scale |
83
- | Footnote color | `var(--dsx-color-on-surface-variant)` | Muted footnote on wash |
83
+ | Footnote color | `var(--dsx-color-on-primary-container)` | Paired footnote ink on wash |
84
84
 
85
85
  ## Motion contract
86
86
 
@@ -98,7 +98,7 @@ None — no transitions, no animation. Pressed/`focus-visible` states do not app
98
98
 
99
99
  **Color and meaning:**
100
100
 
101
- - The wash is decorative; label/value text carries all meaning with `on-surface` contrast.
101
+ - The wash is decorative; label/value text carries all meaning with the paired `on-primary-container` contrast. Typography distinguishes label, value and footnote without reducing their color contrast.
102
102
 
103
103
  ## Playground demo spec
104
104
 
@@ -12,7 +12,7 @@ depends_on: []
12
12
 
13
13
  ## Purpose
14
14
 
15
- A styled block quotation surface that renders a `<blockquote>` element with token-aligned typography, a left accent rule, and three tone variants for default, muted, and inverse contexts.
15
+ A styled block quotation surface that renders a `<blockquote>` element with token-aligned typography, a 1px logical-start accent rule, and three tone variants for default, muted, and inverse contexts.
16
16
 
17
17
  ## Anatomy & slots
18
18
 
@@ -65,10 +65,10 @@ Every CSS value the component paints is a `var(--dsx-*)` token.
65
65
 
66
66
  | Property | Token | Role |
67
67
  |---|---|---|
68
- | Padding (left) | `var(--dsx-space-lg)` | Inset gutter for the accent rule. |
69
- | Border (left, default) | `var(--dsx-border-width-xl)` + `var(--dsx-color-primary)` | Default accent rule. |
70
- | Border (left, muted) | `var(--dsx-color-outline-variant)` | Muted accent rule. |
71
- | Border (left, inverse) | `var(--dsx-color-on-inverse-background)` | Inverse-context accent rule. |
68
+ | Padding (inline start) | `var(--dsx-space-lg)` | Inset gutter for the accent rule. |
69
+ | Border (inline start, default) | `var(--dsx-boundary-divider-width)` + `var(--dsx-color-accent-border)` | Default accent rule. |
70
+ | Border (inline start, muted) | `var(--dsx-color-outline-variant)` | Muted accent rule. |
71
+ | Border (inline start, inverse) | `var(--dsx-color-on-inverse-background)` | Inverse-context accent rule. |
72
72
  | Font family | `var(--dsx-typography-body-large-font-family)`, sans-serif fallback | Body type ramp. |
73
73
  | Font size | `var(--dsx-typography-body-large-font-size)` | Body type ramp. |
74
74
  | Line height | `var(--dsx-typography-body-large-line-height)` | Body type ramp. |
@@ -79,6 +79,7 @@ Every CSS value the component paints is a `var(--dsx-*)` token.
79
79
  Rules:
80
80
 
81
81
  - The accent rule and the text color are the only painted values; both come from tokens.
82
+ - The default rule consumes the decorative accent-border role: step 8 in light appearance and step 11 in dark appearance. It is a 1px border on Blockquote itself, not a nested Separator. The muted rule remains a neutral outline-variant.
82
83
  - Tokens come from `DESIGN.md` and the generated `tokens.css`. The `body-large` typography token set is the only ramp Blockquote consumes.
83
84
  - Font style is hard-coded to `italic` in CSS; this is a visual convention, not a token, and is not overridable through a prop.
84
85
 
@@ -142,7 +143,7 @@ Rules:
142
143
 
143
144
  **Token story:**
144
145
 
145
- - Renders inside a `Theme` wrapper with `accentColor="rift"`, `accentColor="warp"`, and `accentColor="ray"`. Asserts the default accent rule color tracks `data-accent-color` (it should resolve to the current `primary` token at runtime).
146
+ - Renders inside a `Theme` wrapper with all five accents (rift, warp, ray, astral and spark). Asserts the default accent rule color tracks `data-accent-color` (it should resolve to the current `accent-border` token at runtime).
146
147
 
147
148
  **A11y story:**
148
149
 
@@ -169,13 +170,13 @@ Rules:
169
170
 
170
171
  **State boundaries:**
171
172
 
172
- - Owned by Blockquote: the root class, the tone modifier class, the typography and color tokens, and the left accent rule.
173
+ - Owned by Blockquote: the root class, the tone modifier class, the typography and color tokens, and the 1px logical-start accent rule.
173
174
  - Owned by the consumer: the quotation body, the optional `cite` URL, and the host element when `asChild` is set.
174
175
 
175
176
  **Boundary rules:**
176
177
 
177
178
  - App-owned data: the source attribution, the optional author display name, the surrounding prose context, and the host element when `asChild` is set.
178
- - DS-owned visuals: token bindings (`--dsx-space-lg`, `--dsx-border-width-xl`, `--dsx-color-primary`, `--dsx-color-outline-variant`, `--dsx-color-on-inverse-background`, `--dsx-color-on-surface-variant`, `--dsx-typography-body-large-*`), the `dsx-blockquote` root class, and the `dsx-blockquote--{tone}` modifier classes.
179
+ - DS-owned visuals: token bindings (`--dsx-space-lg`, `--dsx-boundary-divider-width`, `--dsx-color-accent-border`, `--dsx-color-outline-variant`, `--dsx-color-on-inverse-background`, `--dsx-color-on-surface-variant`, `--dsx-typography-body-large-*`), the `dsx-blockquote` root class, and the `dsx-blockquote--{tone}` modifier classes.
179
180
 
180
181
  ## Penpot build recipe
181
182
 
@@ -201,20 +202,20 @@ The package does not yet publish a Penpot asset for Blockquote. Recipe is visual
201
202
 
202
203
  | Shape | Property | Token | Token type | Penpot property name |
203
204
  |---|---|---|---|---|
204
- | Root | stroke (left) | `--dsx-color-primary` | Color | `strokes` |
205
+ | Root | stroke (logical start) | `--dsx-color-accent-border` | Color | `strokes` |
205
206
  | Root | padding (start) | `--dsx-space-lg` | Spacing | `padding` |
206
207
  | Root | typography | `--dsx-typography-body-large-*` | Typography | `typography` |
207
- | Root (muted) | stroke (left) | `--dsx-color-outline-variant` | Color | `strokes` (state) |
208
- | Root (inverse) | stroke (left) | `--dsx-color-on-inverse-background` | Color | `strokes` (state) |
208
+ | Root (muted) | stroke (logical start) | `--dsx-color-outline-variant` | Color | `strokes` (state) |
209
+ | Root (inverse) | stroke (logical start) | `--dsx-color-on-inverse-background` | Color | `strokes` (state) |
209
210
  | Root (inverse) | text fill | `--dsx-color-on-inverse-background` | Color | `fills` (state) |
210
211
 
211
212
  ### State transformations
212
213
 
213
214
  | State | Root stroke | Text fill | Border width |
214
215
  |---|---|---|---|
215
- | `default` | `--dsx-color-primary` | `--dsx-color-on-surface-variant` | `--dsx-border-width-xl` |
216
- | `muted` | `--dsx-color-outline-variant` | `--dsx-color-on-surface-variant` | `--dsx-border-width-xl` |
217
- | `inverse` | `--dsx-color-on-inverse-background` | `--dsx-color-on-inverse-background` | `--dsx-border-width-xl` |
216
+ | `default` | `--dsx-color-accent-border` | `--dsx-color-on-surface-variant` | `--dsx-boundary-divider-width` |
217
+ | `muted` | `--dsx-color-outline-variant` | `--dsx-color-on-surface-variant` | `--dsx-boundary-divider-width` |
218
+ | `inverse` | `--dsx-color-on-inverse-background` | `--dsx-color-on-inverse-background` | `--dsx-boundary-divider-width` |
218
219
 
219
220
  ### Variant model
220
221
 
@@ -0,0 +1,146 @@
1
+ ---
2
+ title: BottomDock
3
+ status: canonical
4
+ category: Components
5
+ archetype: composite
6
+ depends_on:
7
+ - "@radix-ui/react-slot (powers `asChild` on `BottomDock` and `BottomDock.Item`)"
8
+ - VisuallyHidden (keeps an inactive item's label in the accessible name while it is not drawn)
9
+ ---
10
+
11
+ # BottomDock
12
+
13
+ > Consumer note: this document describes public intent and contracts; the package TypeScript declarations are the exact API.
14
+
15
+ ## Purpose
16
+
17
+ A floating pill of primary destinations for phone widths — the phone counterpart of the `Sidebar`
18
+ panel. It holds a handful of navigation items (four destinations plus a "More" item is the norm), marks
19
+ the current one, and sits above the page bottom edge with the safe-area inset respected. It is
20
+ navigation-agnostic: the app owns the routes, the active-page detection and what "More" does (usually
21
+ opening the mobile `Sidebar` drawer through `useSidebar().setMobileSheetOpen(true)`).
22
+
23
+ It is **not** a full-width tab bar (`TabNav`, `Tabs`) and not a toolbar. Use it only for primary
24
+ navigation at phone widths; render it conditionally (the component writes no breakpoints).
25
+
26
+ Wild references (decisions in `docs/feature/design-system/shell-chrome-c/decisions.md`): Material 3
27
+ navigation bar (2–5 destinations; the selected destination always shows its label), Apple HIG tab bar
28
+ (at most five tabs; labels recommended; badges), MUI `BottomNavigation` (`showLabels`).
29
+
30
+ ## Anatomy & slots
31
+
32
+ **Parent:** `BottomDock`. The root is `<nav aria-label="Bottom navigation">`. Items are direct children.
33
+
34
+ | Slot | Element | Renders | Notes |
35
+ |---|---|---|---|
36
+ | `BottomDock` | `<nav>` (or `Slot` child when `asChild`) | `dsx-bottom-dock` + `data-slot="bottom-dock"` + `data-placement` + `data-labels` | The floating pill and landmark. |
37
+ | `BottomDock.Item` | `<button type="button">` (or `Slot` child when `asChild`, e.g. a router link) | `dsx-bottom-dock__item` + `data-slot="bottom-dock-item"` + `data-active` + `data-label` + `aria-current="page"` when active | One destination or action. |
38
+ | `BottomDock.Icon` | `<span aria-hidden="true">` | `dsx-bottom-dock__icon` + `data-slot="bottom-dock-icon"` | Wraps the glyph (an `Icon`); decorative. |
39
+ | `BottomDock.Label` | `<span>` | `dsx-bottom-dock__label` + `data-slot="bottom-dock-label"` | The destination name. When the item's label is hidden by the `labels` mode it renders through `VisuallyHidden`, so it stays in the accessible name. |
40
+ | `BottomDock.Badge` | `<span>` | `dsx-bottom-dock__badge` + `data-slot="bottom-dock-badge"` | A count; with no children it renders as a dot. Position-only — the badge text, if any, is the consumer's. |
41
+
42
+ ## Props contract
43
+
44
+ ### `BottomDock`
45
+
46
+ | Prop | Type | Default | Required | Description | Responsive |
47
+ |---|---|---|---|---|---|
48
+ | `placement` | `'fixed' \| 'contained'` | `'fixed'` | no | `fixed` pins the dock to the viewport bottom and adds `--dsx-safe-area-inset-bottom`; `contained` positions it absolutely inside the nearest positioned ancestor (demos, framed compositions). | no |
49
+ | `labels` | `'active' \| 'always' \| 'none'` | `'active'` | no | `active`: only the current item draws its label (Material 3); `always`: every item draws its label (HIG-style); `none`: no label is drawn and the items are icon-only, for widths where five labels do not fit (about 340px and below), picked by the app by width. Hidden labels stay in the accessible name in every mode. | no |
50
+ | `asChild` | `boolean` | `false` | no | Renders the host through `Slot`. | no |
51
+ | `aria-label` | `string` | `'Bottom navigation'` | no | The landmark name; override with product copy. | no |
52
+ | `className` | `string` | `undefined` | no | Extra classes appended to `dsx-bottom-dock`. | no |
53
+ | `children` | `React.ReactNode` | `undefined` | no | `BottomDock.Item` rows. | no |
54
+
55
+ ### `BottomDock.Item`
56
+
57
+ | Prop | Type | Default | Required | Description | Responsive |
58
+ |---|---|---|---|---|---|
59
+ | `isActive` | `boolean` | `false` | no | Marks the current destination. Writes `aria-current="page"` and `data-active="true"`. | no |
60
+ | `asChild` | `boolean` | `false` | no | Renders the host through `Slot`. When set, `type` is omitted. | no |
61
+ | `type` | `'button' \| 'submit' \| 'reset'` | `'button'` | no | Forwarded to the host `<button>`. Omitted when `asChild` is set. | no |
62
+ | `className` | `string` | `undefined` | no | Extra classes appended to `dsx-bottom-dock__item`. | no |
63
+ | `children` | `React.ReactNode` | (required) | yes | `BottomDock.Icon`, `BottomDock.Label`, optionally `BottomDock.Badge`. | no |
64
+
65
+ `BottomDock.Icon`, `BottomDock.Label` and `BottomDock.Badge` accept standard `<span>` attributes plus `className` and `children`.
66
+
67
+ Rules:
68
+
69
+ - Guidance, not enforcement: up to five items; in practice four destinations plus "More".
70
+ - An item without a `BottomDock.Label` must carry its own `aria-label`.
71
+ - `BottomDock.Item` reads the dock's `labels` mode and its own `isActive` to write `data-label="visible" | "hidden"`; `BottomDock.Label` reads that to decide whether to render through `VisuallyHidden`.
72
+
73
+ ## CSS class contract
74
+
75
+ **Root class:** `dsx-bottom-dock`
76
+
77
+ | Attribute | Allowed values | Hook | CSS file |
78
+ |---|---|---|---|
79
+ | `data-placement` | `fixed`, `contained` | `.dsx-bottom-dock:where([data-placement='contained'])` switches to absolute positioning | `bottom-dock.css` |
80
+ | `data-labels` | `active`, `always`, `none` | `none` shares the width between icon-only items (`.dsx-bottom-dock:where([data-labels='none']) .dsx-bottom-dock__item`); the visible/hidden decision is per item through `data-label` | `bottom-dock.css` |
81
+ | `data-active` | `true` | `.dsx-bottom-dock__item:where([data-active='true'])` — the opaque accent container | `bottom-dock.css` |
82
+ | `data-label` | `visible`, `hidden` | recorded on the item for consumers and tests; the hidden label is removed from the layout through `VisuallyHidden` | `bottom-dock.css` |
83
+ | `data-slot` | `bottom-dock-*` | hooks | `bottom-dock.css` |
84
+
85
+ **Slot classes:** `dsx-bottom-dock`, `dsx-bottom-dock__item`, `dsx-bottom-dock__icon`,
86
+ `dsx-bottom-dock__label`, `dsx-bottom-dock__badge`.
87
+
88
+ No `data-variant`, `data-size`, `data-accent-color`, `data-radius` or `data-high-contrast` is written
89
+ (contract profile: none). `data-radius` in particular is never used as a local attribute name (see
90
+ `component-contract.md`).
91
+
92
+ **Responsive behavior:** none in CSS — the app renders the dock only at phone widths.
93
+
94
+ **Reduced motion:** the item's colour/background transition is removed under `prefers-reduced-motion: reduce`.
95
+
96
+ ## Token mapping
97
+
98
+ | Property | Token | Role |
99
+ |---|---|---|
100
+ | Position (fixed) | `inset-inline: var(--dsx-space-3)`; `inset-block-end: calc(var(--dsx-space-3) + var(--dsx-safe-area-inset-bottom, 0px))` | floating gap + safe area |
101
+ | Stacking | `var(--dsx-z-index-fixed)` | above sticky chrome, below overlays and modals |
102
+ | Surface | `var(--dsx-color-panel-translucent)` + `var(--dsx-effect-panel-glass-backdrop-filter)` | the glass panel precedent (dropdown-menu, command) |
103
+ | Border | `var(--dsx-border-width-sm) solid var(--dsx-panel-border-color)` | structural edge |
104
+ | Shadow | `var(--dsx-panel-shadow)` | floating elevation |
105
+ | Radius | `var(--dsx-rounded-xl)` | pill |
106
+ | Padding / gap | `var(--dsx-space-xs)` | inner rhythm |
107
+ | Item min size | `calc(var(--dsx-size-xl) + var(--dsx-space-xs))` (44px at default density) | touch target |
108
+ | Item radius | `var(--dsx-rounded-lg)` | follows the global radius setting |
109
+ | Item colour | `var(--dsx-color-on-surface-variant)` | inactive |
110
+ | Item hover | `var(--dsx-effect-hover-ghost)` | hover surface |
111
+ | Item active | `var(--dsx-color-primary-container)` / `var(--dsx-color-on-primary-container)` | opaque accent container (DESIGN.md) |
112
+ | Label type | `var(--dsx-typography-label-small-*)` | compact label; a label wider than its item truncates with an ellipsis (the full text stays in the accessible name) rather than overflowing the pill |
113
+ | Badge | `var(--dsx-color-primary)` / `var(--dsx-color-on-primary)` | count or dot |
114
+ | Focus ring | `var(--dsx-shadow-focus-ring)` | `:focus-visible` |
115
+ | Motion | `var(--dsx-motion-duration-fast) var(--dsx-motion-easing-standard)` | colour transition |
116
+
117
+ Rules: no raw colour, spacing, radius or motion values in `bottom-dock.css`.
118
+
119
+ ## Accessibility
120
+
121
+ - `BottomDock` is a named `nav` landmark.
122
+ - The current item has `aria-current="page"`; the active state is also carried by the container fill and the visible label (not colour alone). With `labels="none"` no label is visible, so the container fill (the opaque primary container, not the accent colour alone) and `aria-current` carry it, and every label stays in the accessible name.
123
+ - Every item has an accessible name: its `BottomDock.Label` (kept in the DOM through `VisuallyHidden` when not drawn) or its own `aria-label`.
124
+ - Touch targets are at least 44px; focus is a visible ring; the whole dock is reachable in normal tab order.
125
+ - A badge with text is part of the item's accessible name ("Devices 3"); an empty dot badge adds nothing. Place the badge inside `BottomDock.Icon` to sit on the glyph (the icon wrapper is `aria-hidden`, so a count placed there is not announced).
126
+
127
+ ## Playground demo spec
128
+
129
+ **Default story:** four `BottomDock.Item`s (icon + label) in a `contained` dock, the first active.
130
+ **Variant stories:** `labels="always"` and `labels="none"` beside the default `active`; `placement="contained"` is the demo default. The `none` fixture sits in a 320px-wide frame with five items.
131
+ **State stories:** an active item; an item with a count badge; an item with a dot badge; keyboard focus.
132
+ **Composition story:** the dock with a "More" item that opens a `Sidebar` drawer (mobile) — documented, driven by `useSidebar()`.
133
+ **Token story:** inside `Theme` with each of the five accents (the active container and the badge vary by accent).
134
+ **A11y story:** `BottomDock.test.tsx` runs `vitest-axe`.
135
+
136
+ | Prop | Control | Default |
137
+ |---|---|---|
138
+ | `placement` | select | `contained` (demo) |
139
+ | `labels` | select | `active` |
140
+
141
+ ## Wiring notes
142
+
143
+ **Composes from:** `@radix-ui/react-slot`, `VisuallyHidden`.
144
+
145
+ **State boundaries:** owned by `BottomDock`: nothing persistent — only the derived `data-label`.
146
+ Owned by the consumer: routes, the active item, the badge counts, the "More" action, when the dock is shown.