@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
@@ -15,6 +15,56 @@ Controlled one-reply-level discussion UI. Data, relative-time localization, mode
15
15
 
16
16
  `CommentThread.Root`, `Comment`, `Replies`, `Tombstone`, `Composer`, and `Locked`. Comment renders avatar initials or image, author badge content, semantic `time`, body, and report/reply actions. Composer owns no remote state and exposes value, character limit, locked, and submission state. Tombstones remain visibly present to preserve thread structure.
17
17
 
18
+ - Root forwards native div attributes/ref. Comment forwards article attributes/ref;
19
+ `author` and `dateTime` are strings, `timeLabel`, `badge`, `actions` and body accept
20
+ React nodes, and `avatarSrc` optionally replaces initials with a decorative image.
21
+ - Replies forwards native div attributes/ref and defaults to role group. One nested
22
+ reply level is supported; a second Replies inside Replies throws explicitly.
23
+ - Tombstone defaults to `Comment removed`, role status and `data-removed="true"`.
24
+ Locked defaults to `Comments are locked` and role status. Both accept custom children.
25
+ - Composer forwards form attributes/ref while managing submission. `value` and
26
+ `onValueChange` are required; `onSubmit`, `maxLength` (default 2000), `locked` and
27
+ `submitting` are optional. It prevents native navigation and calls onSubmit only
28
+ for nonblank, within-limit, valid, unlocked, non-submitting content. The app owns asynchronous work.
29
+ - Its controlled native textarea has the default accessible name `Comment` and an
30
+ associated polite character counter. Locked/submitting disables editing; submitting
31
+ sets form `aria-busy`. Default submit composes the large DS Button, disabled for
32
+ empty/locked/submitting content. Custom children replace that default action.
33
+
34
+ ## Paint and containment
35
+
36
+ Comment uses an avatar column and a zero-minimum content track. Author metadata and
37
+ actions and action labels wrap intrinsically; long body words wrap. Body/actions remain in the content
38
+ column and Replies retains its logical-start indent. No component breakpoint is used.
39
+
40
+ Composer textarea explicitly fits its parent, uses body-medium typography, keeps
41
+ native vertical resize, and consumes the existing focus ring and disabled roles.
42
+ The `dsx-comment-thread__count` and `dsx-comment-thread__submit` classes identify
43
+ the counter and default action. Button owns focus/pressed/disabled treatment and
44
+ target dimensions (44px at comfortable density). The component adds no motion.
45
+
18
46
  ## Playground demo spec
19
47
 
20
- Show initials and image avatars, badge and time, one reply level, report/reply actions, character count, submitting/locked composers, and a removed tombstone.
48
+ `/docs/comment-thread` composes `blocks-examples.tsx` through the display registry.
49
+ It shows initial/image avatars, author badge/time, one reply level, report/reply
50
+ actions and a removed tombstone. The controlled composer updates its count, shows
51
+ submitting, adds a local comment, and can be locked/unlocked. Separate submitting
52
+ and locked examples remain visible. All demo persistence and action feedback is
53
+ playground-owned; no network or moderation service is implied.
54
+
55
+ ## Discussion enhancement — approved 2026-10-04
56
+
57
+ `Composer` adds `input(context)` to replace the textarea without duplication,
58
+ `label`, `error`, `status` and `actions`. Context supplies `id`, `value`,
59
+ `onValueChange`, `maxLength`, `disabled`, `describedBy` and `invalid` for accessible
60
+ custom controls. Children retain their existing submit-action override. Count,
61
+ error and status are associated with the input. Blank, over-limit, submitting,
62
+ locked or invalid drafts cannot submit. Consumers own rich-text plain count and
63
+ validation. `Comment.metadata` supports edited state.
64
+
65
+ `Replies` adds optional `limit`, controlled/uncontrolled `expanded`,
66
+ `onExpandedChange` and `moreLabel`; defaults still show all children. Exactly one
67
+ reply level remains supported. `Tombstone.state` distinguishes `hidden`,
68
+ `removed` and `deleted`, with localized children. Legacy `data-removed` persists.
69
+ Support is demonstrated as a linear composition with a restricted rich editor,
70
+ separate FileUpload/attachments, visibility and failed-send retry, not nested replies.
@@ -4,7 +4,7 @@ status: canonical
4
4
  category: Foundations
5
5
  archetype: composite
6
6
  depends_on:
7
- - Sheet
7
+ - Drawer
8
8
  - IconButton
9
9
  - Icon
10
10
  - SegmentedControl
@@ -18,205 +18,106 @@ depends_on:
18
18
 
19
19
  # ConfigDrawer
20
20
 
21
- > Consumer note: this document describes public intent and contracts; the package TypeScript declarations are the exact API.
21
+ > Source of truth: package source; this spec mirrors its public contract.
22
22
 
23
23
  ## Purpose
24
24
 
25
- A right-anchored preferences drawer that exposes the live theme controls: appearance mode, accent color, gray palette, radius, density, and scaling. `ConfigDrawer` is the editor half of the theme configuration surface; `ThemePanel` is the read-only inspector. The two share a design language but solve different problems. `ConfigDrawer` reads and writes the active `ThemeProvider` context, so it must be rendered inside a `ThemeProvider` tree.
25
+ One preferences drawer inside ThemeProvider, exposing Theme, Accent, Gray,
26
+ Radius, Density, Scaling and Panel BG. Values and persistence belong to
27
+ ThemeProvider; the drawer supplies their controls. Default side is right.
26
28
 
27
29
  ## Anatomy & slots
28
30
 
29
- **Parent:** `ConfigDrawer`. The root is a `Sheet` (`Sheet.Root` + `Sheet.Trigger` + `Sheet.Content side="right"`). The drawer is a single function component, not a compound; the consumers do not import any `ConfigDrawer.<Slot>` parts. The internal layout is a vertical `Flex` of `SettingRow` instances separated by `Separator`s.
30
-
31
- **Internal regions:**
32
-
33
- | Region | Element | Renders | Notes |
34
- |---|---|---|---|
35
- | Trigger | `Sheet.Trigger` rendered as `IconButton` (default) or consumer-supplied `trigger` | `dsx-config-drawer__trigger` (class is added when the default trigger renders) | Default trigger is an `IconButton variant="ghost" size="md"` with `aria-label="Open preferences"` and a `settings` `Icon` (size `md`). Consumers can pass a `trigger` prop to replace the default. |
36
- | Header | `Sheet.Header` + `Sheet.Title` | (inherits `Sheet` styles) | "Preferences" title. |
37
- | Body | `Flex direction="column" gap="lg"` | `dsx-config-drawer__body` | Scrollable column of `SettingRow` + `Separator` regions. |
38
- | SettingRow | `Flex direction="row" justify="between" align="center" gap="md"` | `dsx-config-drawer__row` | A label / description / control triplet. The label is a `Label` element; the description (when present) is a `Text variant="label-small" tone="muted"`; the control is whatever the consumer passes as `children`. |
39
- | SettingRow info | `Flex direction="column" gap="1"` | `dsx-config-drawer__row-info` | The left column of the row, containing the `Label` and the description. |
40
- | SettingRow control wrapper | `<div>` | `dsx-config-drawer__row-control` | The right column of the row, wrapping the control. |
41
- | Accent preview swatch | `<span aria-hidden="true">` | `dsx-config-drawer__accent-swatch` + `data-tier` | Non-interactive preview of each accent tier. It does not write `data-accent-color`, because the swatch represents a color value rather than consuming theme scope. |
42
- | Scaling input (specific) | `NumberInput` | `dsx-config-drawer__scaling-input` | The scaling control. Sized to `7ch` so the percentage fits without breaking the row rhythm. |
43
-
44
- **Internal layout:**
45
-
46
- - The default trigger is a ghost `IconButton` with a `settings` icon. Passing the `trigger` prop replaces it entirely.
47
- - The body is a single scrollable column. Each `SettingRow` is a `flex-direction: row` with `justify-content: space-between`, so the label and control sit on opposite ends of the row.
48
- - The six default rows (Theme, Accent, Gray, Radius, Density, Scaling) are separated by `Separator` components from the package. The order is fixed and reflects the dependency direction: appearance first, then accent, then gray, then radius, then density, then scaling.
49
- - Each row's control is a `SegmentedControl` (for the categorical tokens) or a `NumberInput` (for the scaling percentage). The control is wrapped in a `<div class="dsx-config-drawer__row-control">` so it stays right-aligned without leaking the `gap` into the control itself.
31
+ Flat export composing lazily loaded Drawer, Trigger, Content, Header, Title and
32
+ Description. No ConfigDrawer compound slots. Default trigger is an inline ghost
33
+ IconButton size md, named “Open preferences”, with settings Icon. The host owns
34
+ positioning. Title is “Preferences”; VisuallyHidden wraps the DrawerDescription.
35
+ Body composes Flex, Label, Text, SegmentedControl, NumberInput and Separator.
50
36
 
51
37
  ## Props contract
52
38
 
53
- **Root props (`ConfigDrawer`):**
54
-
55
- | Prop | Type | Default | Required | Description | Responsive |
56
- |---|---|---|---|---|---|
57
- | `open` | `boolean` | `undefined` | no | Controlled open state. Pass alongside `onOpenChange` to own the open flag. | no |
58
- | `defaultOpen` | `boolean` | `false` | no | Uncontrolled initial open state. | no |
59
- | `onOpenChange` | `(open: boolean) => void` | `undefined` | no | Callback fired when the underlying `Sheet` open state changes. | no |
60
- | `trigger` | `ReactNode` | default `IconButton` (see above) | no | Custom trigger element. Rendered through `Sheet.Trigger asChild`. | no |
61
-
62
- The root does not accept `asChild` directly; consumers can swap the host element by passing a `trigger` or by wrapping the rendered output themselves. The internal `Sheet.Content` is locked to `side="right"`; left-side drawers are out of scope for this component.
63
-
64
- **SettingRow props (internal, not exported):**
65
-
66
- | Prop | Type | Default | Required | Description | Responsive |
67
- |---|---|---|---|---|---|
68
- | `label` | `string` | (none) | **yes** | The label rendered as a `Label` element on the left. | no |
69
- | `description` | `string` | `undefined` | no | Optional helper text rendered under the label as a muted `Text`. | no |
70
- | `children` | `ReactNode` | (none) | **yes** | The control rendered on the right (typically a `SegmentedControl` or `NumberInput`). | no |
71
-
72
- `SettingRow` is an internal helper; consumers do not compose their own rows. The six default rows are wired inside the component.
73
-
74
- ## CSS class contract
75
-
76
- **Root class:** none at the component level. The component composes `Sheet` (which owns the panel chrome) and the `dsx-config-drawer__*` classes below.
39
+ | Prop | Type | Default | Description | Responsive |
40
+ |---|---|---|---|---|
41
+ | open | boolean | undefined | Controlled open state. | no |
42
+ | onOpenChange | (open: boolean) => void | undefined | Open-state callback. | no |
43
+ | defaultOpen | boolean | false | Uncontrolled initial state. | no |
44
+ | trigger | ReactNode | inline IconButton | Custom trigger via DrawerTrigger asChild. | no |
45
+ | side | top / right / bottom / left | right | Passed to Drawer direction. | no |
46
+ | children | ReactNode | undefined | Host content after built-in rows. | no |
77
47
 
78
- **Slot classes:**
48
+ Categorical controls are SegmentedControl type single, size sm:
79
49
 
80
- | Slot / region | Class | CSS file |
50
+ | Row | Accessible name | Choices |
81
51
  |---|---|---|
82
- | Body | `dsx-config-drawer__body` | `config-drawer.css` |
83
- | Default trigger | `dsx-config-drawer__trigger` | (added at the className level on the default `IconButton`; no rule in the CSS file currently) |
84
- | Setting row | `dsx-config-drawer__row` | `config-drawer.css` |
85
- | Setting row info column | `dsx-config-drawer__row-info` | `config-drawer.css` |
86
- | Setting row control wrapper | `dsx-config-drawer__row-control` | `config-drawer.css` |
87
- | Accent preview swatch | `dsx-config-drawer__accent-swatch` | `config-drawer.css` |
88
- | Scaling `NumberInput` | `dsx-config-drawer__scaling-input` | `config-drawer.css` |
52
+ | Theme | Theme mode | Light / Dark / System |
53
+ | Accent | Accent color | Rift / Warp / Ray / Astral / Spark |
54
+ | Gray | Gray color | Auto / Neutral |
55
+ | Radius | Border radius | None / Small / Medium / Large / Full |
56
+ | Density | Density | Comfortable / Compact |
57
+ | Scaling | Scaling percentage | NumberInput, 90–110%, rounded to steps of 5 |
58
+ | Panel BG | Panel background | Translucent / Solid |
89
59
 
90
- **Responsive behavior:**
60
+ SettingRow is internal: label, optional description, children. Visible labels
61
+ are visual cues; each control has its own programmatic name.
91
62
 
92
- - The component does not write `@media` rules. On narrow viewports the consumer can swap in a different sheet side or a full-screen `Sheet`; `ConfigDrawer` is fixed to a right-anchored panel.
93
-
94
- **Reduced motion:**
63
+ ## CSS class contract
95
64
 
96
- - The component itself does not animate. Open / close transitions on the wrapping `Sheet` are owned by the `Sheet` component and respect `prefers-reduced-motion` through the standard `MOTION_TRANSITIONS.sheet` preset.
65
+ | Region | Class |
66
+ |---|---|
67
+ | Body | dsx-config-drawer__body |
68
+ | Row | dsx-config-drawer__row |
69
+ | Information | dsx-config-drawer__row-info |
70
+ | Control | dsx-config-drawer__row-control |
71
+ | Swatch | dsx-config-drawer__accent-swatch |
72
+ | Scaling | dsx-config-drawer__scaling-input |
73
+
74
+ Rows always wrap. Information has min-width 0; controls have min-width 0 and
75
+ max-width 100%. Long categorical groups retain SegmentedControl's own horizontal
76
+ scrolling, including keyboard reveal. Drawer bounds and vertical scrolling use
77
+ the shared Drawer contract. No package width breakpoints.
97
78
 
98
79
  ## Token mapping
99
80
 
100
- Every CSS value the component paints is a `var(--dsx-*)` token.
81
+ | Property | Token |
82
+ |---|---|
83
+ | Body gap / padding | --dsx-space-lg / --dsx-space-md |
84
+ | Row gap / minimum height | --dsx-space-md / --dsx-size-lg |
85
+ | Information gap | --dsx-space-2xs |
86
+ | Swatch size / gap / radius | --dsx-space-sm / --dsx-space-xs / --dsx-radius-full |
87
+ | Swatch fill | --dsx-color-accent-{rift,warp,ray,astral,spark}-9 |
88
+ | Scaling width | 7ch |
101
89
 
102
- | Property | Token | Role |
103
- |---|---|---|
104
- | Body gap | `var(--dsx-space-lg)` | Vertical gap between rows |
105
- | Body padding | `var(--dsx-space-md) 0` | Vertical padding around the body |
106
- | Body overflow | `auto` | Vertical scroll when content overflows |
107
- | Row min-height | `var(--dsx-size-lg)` | Min hit target |
108
- | Row gap | `var(--dsx-space-md)` | Horizontal gap between info and control |
109
- | Row info gap | `var(--dsx-space-2xs)` | Vertical gap inside the info column |
110
- | Accent preview size | `var(--dsx-space-sm)` | Square preview swatch dimensions |
111
- | Accent preview spacing | `var(--dsx-space-xs)` | Gap between the preview and tier label |
112
- | Accent preview radius | `var(--dsx-radius-full)` | Circular preview shape |
113
- | Accent preview fill | `var(--dsx-runtime-accent-{rift,warp,ray}-9)` | Exact value represented by each theme choice |
114
- | Scaling input width | `7ch` | Fixed width for the percentage `NumberInput` |
115
-
116
- The default trigger is an `IconButton`; its visual contract is owned by `IconButton`. The row labels use the `Label` component; their visual contract is owned by `Label`. The segmented controls use the `SegmentedControl` component; their visual contract is owned by `SegmentedControl`.
90
+ Controls, separators and panel chrome retain their own component token contracts.
117
91
 
118
92
  ## Motion contract
119
93
 
120
- | Region | Token | Default | Reduced |
121
- |---|---|---|---|
122
- | Sheet open / close | inherited from `Sheet` (`MOTION_TRANSITIONS.sheet`) | sheet preset | reduced |
94
+ Inherited Drawer motion uses MOTION_TRANSITIONS.drawer and reduced fallback.
95
+ ConfigDrawer adds no animation.
123
96
 
124
- The component itself has no motion. The wrapping `Sheet` handles open / close transitions through the standard sheet preset and the `reduced` fallback.
97
+ Rows explicitly compose Flex with wrap="wrap". Row descriptions use a
98
+ max-content flex basis so they retain readable width when the controls wrap. Controls keep their natural width
99
+ within a 100% cap, move below the row description when needed and retain the
100
+ existing SegmentedControl scroll behavior for long choice rails.
125
101
 
126
102
  ## Accessibility
127
103
 
128
- **Roles:**
129
-
130
- - The panel is a `Sheet`, which renders with the standard `role="dialog"` plus `aria-modal` and a labelled-by pointer to the `Sheet.Title`. The title is "Preferences".
131
- - Each `SegmentedControl` is a `radiogroup` (for `type="single"`) or a `group` of toggles (for `type="multiple"`). The ConfigDrawer uses `type="single"` for all categorical tokens. The `NumberInput` for scaling is a `textbox` with an `aria-label="Scaling percentage"`.
132
- - The `SettingRow` `Label` is a `<label>` element. Because the controls sit inside the same row rather than as direct label children of the controls, the `aria-label` on each control is the source of truth for the accessible name. The visible `Label` is a visual cue, not a programmatic association.
133
-
134
- **Keyboard:**
135
-
136
- | Key | Action |
137
- |---|---|
138
- | `Tab` | Moves focus through the trigger, the segmented controls, the scaling input, and the sheet close affordance. |
139
- | `ArrowLeft` / `ArrowRight` | Navigates within a `SegmentedControl` (radiogroup semantics). |
140
- | `Enter` / `Space` | Activates the focused segmented option or input. |
141
- | `Escape` | Closes the `Sheet` and returns focus to the trigger. |
142
-
143
- **Focus:**
144
-
145
- - The `Sheet` is a modal: focus is trapped inside the drawer while it is open and returned to the trigger on close.
146
- - Each `SegmentedControl` is a roving-focus radiogroup: arrow keys move between options; the focused option gets a visible ring.
147
- - The `NumberInput` exposes the standard textbox focus ring.
148
-
149
- **Reduced motion:**
150
-
151
- - Open / close transitions respect `prefers-reduced-motion` through the standard `Sheet` motion contract.
152
-
153
- **Color and meaning:**
154
-
155
- - The selected `SegmentedControl` option tracks `--dsx-color-primary`. The control itself does not impose additional color cues.
156
- - The scaling `NumberInput` is a standard numeric entry; no color meaning.
157
-
158
- **Naming:**
159
-
160
- - Each `SegmentedControl` and the `NumberInput` carry an `aria-label` ("Theme mode", "Accent color", "Gray color", "Border radius", "Density", "Scaling percentage"). The visual `Label` repeats the same string so sighted and screen-reader users get the same word.
161
- - The drawer title is "Preferences".
104
+ Drawer supplies modal dialog semantics, title/description, focus trapping and
105
+ Escape dismissal with focus return. SegmentedControl supplies single selection
106
+ and roving keyboard navigation; NumberInput supplies numeric entry. Enter/Space
107
+ activate the trigger. The playground's draggable trigger separately preserves
108
+ keyboard activation and suppresses clicks after pointer dragging.
162
109
 
163
110
  ## Playground demo spec
164
111
 
165
- **Default story:**
166
-
167
- - The playground registry does not render `ConfigDrawer` inline because the drawer is already mounted at the app root and a second instance would conflict with the active one. The registry render shows a description of the usage and the canonical placement (alongside `ThemeProvider` at the app root).
168
-
169
- **Variant story:** N/A. The component has no variants; the layout is fixed.
170
-
171
- **State story:**
172
-
173
- - Renders the drawer with `defaultOpen` and confirms the six rows appear with the correct default selections (`System`, `Rift`, `Auto`, `Medium`, `Comfortable`, `100`).
174
- - Renders the drawer with `open` (controlled) and confirms the same.
175
- - Renders a custom `trigger` and confirms the custom trigger is rendered when the drawer is closed.
176
-
177
- **Composition story:**
178
-
179
- - The component owns its own composition. The composition story is the default render: header + six rows + separators.
180
-
181
- **Token story:**
182
-
183
- - Renders the default drawer inside a `Theme` wrapper with `accentColor="warp"` and `accentColor="ray"`. Asserts the active segmented option tracks `--dsx-color-primary` while each accent preview continues to show the exact tier it represents.
184
-
185
- **A11y story:**
186
-
187
- - Uses `vitest-axe` against the rendered default story with the `aria-allowed-attr` rule disabled (the `SegmentedControl` ships a non-standard `variant` attribute on `role="group"`). Asserts no other axe violations.
188
-
189
- **Props exposed in the playground controls:**
190
-
191
- The playground registry for `config-drawer` does not expose prop controls. The component is mounted live at the app root; the registry render explains that placement and notes the `trigger` prop.
112
+ The registry explains usage and lists all seven rows. The live example is the
113
+ single app-root drawer opened with the bottom-right gear; that host uses side
114
+ bottom. Test Light/Dark, every accent, gray palettes, radius, density, scaling
115
+ and panel background at 1280/390/320, including the last row after scrolling.
116
+ No duplicate drawer is mounted just to obtain a screenshot.
192
117
 
193
118
  ## Wiring notes
194
119
 
195
- **Composes from:**
196
-
197
- - `Sheet` (`src/components/sheet/Sheet`): the entire panel chrome. The drawer uses `Sheet.Trigger asChild` for the trigger, `Sheet.Content side="right"` for the panel, and `Sheet.Header` + `Sheet.Title` for the title row.
198
- - `IconButton` (`src/components/iconButton/IconButton`): the default trigger.
199
- - `Icon` (`src/components/icon/Icon`): the default `settings` icon.
200
- - `Label` (`src/components/label/Label`): the row label.
201
- - `Text` (`src/components/text/Text`): the row description.
202
- - `Flex` (`src/layout/Flex`): the row layout and the body layout.
203
- - `SegmentedControl` (`src/components/segmentedControl/SegmentedControl`): the categorical token pickers. The drawer uses `type="single"` and `size="sm"`.
204
- - `Separator` (`src/components/separator/Separator`): the row separators.
205
- - `NumberInput` (`src/components/numberInput/NumberInput`): the scaling percentage input, clamped to the 90 to 110 range in 5% steps.
206
- - `ThemeProvider` (`src/components/themeProvider/ThemeProvider`): the drawer reads and writes the active theme through `useTheme()`. The drawer must be rendered inside a `ThemeProvider` tree.
207
-
208
- **Used by:**
209
-
210
- - The playground's app shell mounts a single `ConfigDrawer` alongside `ThemeProvider` so every page can toggle the theme without a dedicated settings route.
211
- - App-level settings surfaces and onboarding flows.
212
-
213
- **State boundaries:**
214
-
215
- - Owned by ConfigDrawer: the six default rows, their order, the accent previews, and the `SettingRow` layout.
216
- - Owned by the consumer: the placement of the drawer, the custom `trigger` (if any), the controlled `open` / `onOpenChange` (if any), and the surrounding `ThemeProvider`.
217
- - Owned by `useTheme()`: every categorical selection (`theme`, `accentColor`, `grayColor`, `radius`, `density`, `scaling`) is read from and written to the active `ThemeProvider` context. The drawer does not own the value; it surfaces the control.
218
-
219
- **Boundary rules:**
220
-
221
- - App-owned data: the placement of the drawer, the controlled open state, the custom trigger, and the surrounding `ThemeProvider`.
222
- - DS-owned visuals: token bindings, slot classes, the `Sheet` panel chrome, the segmented control semantics, the `NumberInput` clamping, and the row layout.
120
+ Drawer owns the portal, bounds and focus. ThemeProvider owns selections,
121
+ persistence and system mode. The host owns placement, custom trigger, side,
122
+ controlled open state and optional children. ConfigDrawer owns fixed row order,
123
+ swatches and the numeric scaling clamp. ThemePanel remains the read-only inspector.
@@ -153,6 +153,8 @@ Container has no motion. The motion section is intentionally empty.
153
153
 
154
154
  ## Playground demo spec
155
155
 
156
+ The default container retains its 1080px cap; size 1 and wide show 420px and 1200px caps respectively.
157
+
156
158
  **Default story:**
157
159
 
158
160
  - Renders `Container` with no extra props and a child node. Asserts the root classes are `dsx-container` and `dsx-box` (the `dsx-flex` class is conditional — it is only written when a flex layout prop such as `direction`, `align`, `justify`, `gap`, or `wrap` is set), the host element is a `div`, and `--dsx-container-max-width` resolves to `1080px`.
@@ -33,13 +33,13 @@ An object-scoped right-click action menu. The DS `ContextMenu` wraps `@radix-ui/
33
33
  | `ContextMenu.Label` | Radix `ContextMenu.Label` | `dsx-context-menu__label` | Non-interactive section label. |
34
34
  | `ContextMenu.Separator` | Radix `ContextMenu.Separator` (via `MenuSeparator`) | `dsx-context-menu__separator` | Visual divider. |
35
35
  | `ContextMenu.Group` | Radix `ContextMenu.Group` | (no class) | Groups items semantically. |
36
- | `ContextMenu.Sub` | Radix `ContextMenu.Sub` | (no class) | Submenu owner. |
36
+ | `ContextMenu.Sub` | Radix `ContextMenu.Sub` + `ContextMenuSubOpenContext` | (no class) | Submenu owner; mirrors controlled/uncontrolled state into SubContent. |
37
37
  | `ContextMenu.RadioGroup` | Radix `ContextMenu.RadioGroup` | (no class) | Radio selection owner. |
38
38
  | `ContextMenu.Portal` | Radix `ContextMenu.Portal` (via `MenuPortal`) | (no class) | Portal wrapper. |
39
39
  | `ContextMenu.CheckboxItem` | Radix `ContextMenu.CheckboxItem` | `dsx-context-menu__item` + `dsx-context-menu__item-indicator` | Checkbox row. Renders `check` or `minus` indicator. |
40
40
  | `ContextMenu.RadioItem` | Radix `ContextMenu.RadioItem` | `dsx-context-menu__item` + `dsx-context-menu__item-indicator` + `dsx-context-menu__radio-dot` | Radio row. |
41
41
  | `ContextMenu.SubTrigger` | Radix `ContextMenu.SubTrigger` | `dsx-context-menu__item` + `dsx-context-menu__sub-trigger` + optional `data-inset` + `chevron-right` | Row that opens the sub-content. |
42
- | `ContextMenu.SubContent` | Radix `ContextMenu.SubContent` inside `MenuContent` (no portal) | `dsx-context-menu__content` | The submenu panel. `MenuContent` is invoked with `forceMount`, `open`, and `portal === null` so the sub-content renders inline. |
42
+ | `ContextMenu.SubContent` | Radix `ContextMenu.SubContent` inside portalled `MenuContent` | `dsx-context-menu__content` | The submenu panel follows Sub's open state outside the parent's clip box. Explicit `forceMount` is preserved. |
43
43
  | `ContextMenu.Shortcut` | `<span>` (or `Slot` child when `asChild`) | `dsx-context-menu__shortcut` | Keyboard hint rendered on the right. |
44
44
 
45
45
  The roster's `Parent / Slots` column lists `ContextMenu.Root`, `ContextMenu.Trigger`, `ContextMenu.Content`, `ContextMenu.Label`, `ContextMenu.Separator`, `ContextMenu.Item`, `ContextMenu.Group`. The source exports the full Radix part set through `Object.assign`, including `Sub`, `RadioGroup`, `Portal`, `CheckboxItem`, `RadioItem`, `SubTrigger`, `SubContent`, and `Shortcut`. The spec records the full set so the public surface is unambiguous.
@@ -69,7 +69,7 @@ The roster's `Parent / Slots` column lists `ContextMenu.Root`, `ContextMenu.Trig
69
69
 
70
70
  ### `ContextMenu.Trigger`, `ContextMenu.Label`, `ContextMenu.Separator`, `ContextMenu.Group`, `ContextMenu.Sub`, `ContextMenu.RadioGroup`, `ContextMenu.Portal`, `ContextMenu.CheckboxItem`, `ContextMenu.RadioItem`, `ContextMenu.SubTrigger`, `ContextMenu.SubContent`
71
71
 
72
- These proxy the corresponding Radix props. `ContextMenu.Trigger` accepts the standard Radix trigger props (no class). `ContextMenu.Label` and `ContextMenu.Group` accept the standard Radix props. `ContextMenu.SubContent` accepts the same `align`, `side`, and `sideOffset` props as `Content`; the portal is forced to `null` so the sub-content renders inline.
72
+ These preserve the corresponding Radix props. `ContextMenu.Trigger` accepts standard Radix trigger props and adds the keyboard opening path below. `ContextMenu.Label` and `ContextMenu.Group` accept standard Radix props. `ContextMenu.Sub` preserves controlled `open`, uncontrolled `defaultOpen` and `onOpenChange`. `ContextMenu.SubContent` preserves Radix positioning and `forceMount` props and renders through a theme-preserving portal.
73
73
 
74
74
  ### `ContextMenu.Item`
75
75
 
@@ -194,13 +194,13 @@ Rules:
194
194
  - `ContextMenu.Item` is `role="menuitem"`. `ContextMenu.CheckboxItem` is `role="menuitemcheckbox"`; `ContextMenu.RadioItem` is `role="menuitemradio"`. `ContextMenu.SubTrigger` is `role="menuitem"` with `aria-haspopup="menu"`.
195
195
  - `ContextMenu.Label` is `role="presentation"` for non-interactive section labels (Radix default).
196
196
  - `ContextMenu.Separator` is `role="separator"`.
197
- - `ContextMenu.Trigger` is the right-click target; it is typically a non-semantic element that owns the context-menu event.
197
+ - `ContextMenu.Trigger` captures right-click and touch long-press. A custom non-interactive host must supply `tabIndex={0}` for keyboard opening. The wrapper forwards the Radix trigger props and ref. Essential touch actions should also have an explicit button/menu composition; long-press alone is not discoverable.
198
198
 
199
199
  **Keyboard:**
200
200
 
201
201
  | Key | Action |
202
202
  |---|---|
203
- | `Shift+F10`, context-menu key | Opens the context menu (browser-default). |
203
+ | `Shift+F10`, context-menu key | Opens the menu at the focused trigger's center. The wrapper supplies the context event consistently across browsers; a consumer-cancelled key handler is respected. |
204
204
  | `ArrowDown`, `ArrowUp` | Moves through items. |
205
205
  | `Enter`, `Space` | Activates the focused item. |
206
206
  | `Escape` | Closes the menu. |
@@ -282,3 +282,17 @@ Rules:
282
282
 
283
283
  - App-owned data: the command set, the disabled reasons, the right-click target, and the keyboard shortcut strings.
284
284
  - DS-owned visuals: the `dsx-context-menu__*` slot classes, the token bindings, the data-attribute contract, and the open / close animation.
285
+
286
+ ## Reconciliation stories
287
+
288
+ `Sub` preserves Radix's controlled `open`, uncontrolled `defaultOpen`, and
289
+ `onOpenChange` contract. `SubContent` follows that state and renders in its own
290
+ theme-preserving portal, outside the root's scroll/clip box. Closed submenus
291
+ are unmounted unless the consumer explicitly requests `forceMount`; they do not
292
+ leave inaccessible menu items behind the parent surface.
293
+
294
+ The panel's usual minimum width is capped by Radix's available width. A submenu
295
+ can become narrower when neither side has room for the usual menu width; labels
296
+ wrap rather than painting off the viewport. No viewport breakpoint is involved.
297
+
298
+ The live example uses a real Project actions button for explicit activation, right-click and keyboard opening. It demonstrates selection feedback, a disabled item, a controlled checkbox and radio group, a submenu and a destructive action. Shortcut hints are labels; item callbacks own the action.
@@ -180,7 +180,7 @@ Rules:
180
180
  | Close button size | `var(--dsx-size-lg)` | Square tap target. |
181
181
  | Close button radius | `var(--dsx-rounded-full)` | Round close. |
182
182
  | Close button offset | `var(--dsx-space-md)` | Distance from the corner. |
183
- | Backdrop blur | `var(--dsx-blur-md, 8px)` | Optional blur. |
183
+ | Backdrop blur | `var(--dsx-blur-md, 8px)` | Optional blur. `-webkit-backdrop-filter` is declared before `backdrop-filter` so the bundler keeps the standard line (see `card.md`, B-1). |
184
184
  | Title typography | `var(--dsx-typography-headline-medium-*)` | Title. |
185
185
  | Description typography | `var(--dsx-typography-body-medium-*)` | Description. |
186
186
  | Description color | `var(--dsx-color-on-surface-variant)` | Body copy. |
@@ -239,6 +239,8 @@ Rules:
239
239
 
240
240
  ## Playground demo spec
241
241
 
242
+ The live connection-settings example uses the package Select for Region and a nested Popover for display density. Apply closes only the child popover; Save region reports the selected value and returns focus to the dialog launcher. Long-content mode verifies reachable body and footer controls.
243
+
242
244
  **Default story:**
243
245
 
244
246
  - Renders `DialogRoot` with a `Trigger` and `Content` containing `Header`, `Body`. Asserts the content has `dsx-dialog__content` and `data-size="md"`.
@@ -274,7 +276,7 @@ Rules:
274
276
 
275
277
  **Token story:**
276
278
 
277
- - Renders inside a `Theme` wrapper with `accentColor="silver"` and one with `accentColor="bronze"`. Asserts the `data-accent-color` attribute on the content wrapper.
279
+ - Renders inside a `Theme` wrapper with `accentColor="rift"` and one with `accentColor="warp"`. Asserts the `data-accent-color` attribute on the content wrapper.
278
280
 
279
281
  **Props exposed in the playground controls:**
280
282
 
@@ -51,8 +51,6 @@ A mobile or edge-attached modal overlay that slides in from any edge of the view
51
51
  | Prop | Type | Default | Required | Description | Responsive |
52
52
  |---|---|---|---|---|---|
53
53
  | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | no | Drawer content size; writes `data-size` attribute. | no |
54
- | `height` | `string` (responsive) | `undefined` | no | Responsive height override via CSS variable. | yes |
55
- | `width` | `string` (responsive) | `undefined` | no | Responsive width override via CSS variable. | yes |
56
54
  | `className` | `string` | `undefined` | no | Extra classes appended to `dsx-drawer__content`. | no |
57
55
 
58
56
  **Header props:**
@@ -76,7 +74,7 @@ Standard Radix `Title` and `Description` props plus `className`.
76
74
  Rules:
77
75
 
78
76
  - `direction` on Root is wired through `extractProps`.
79
- - `size`, `height`, and `width` on Content are wired through `extractProps`.
77
+ - `size` on Content are wired through `extractProps`.
80
78
  - `asChild` on Header and Footer is wired through `extractProps`.
81
79
  - The Root manages open state through a controllable hook (`useControllableDrawerOpenState`) that supports both controlled and uncontrolled modes.
82
80
  - The Root provides `DrawerOpenContext` and `DrawerDirectionContext` so Content can access the open state and direction for motion calculations.
@@ -102,12 +100,12 @@ Rules:
102
100
  | Attribute | Allowed values | Class | CSS file |
103
101
  |---|---|---|---|
104
102
  | `data-direction` (on content) | `top`, `right`, `bottom`, `left` | `.dsx-drawer__content[data-direction='...']` | `drawer.css` |
105
- | `data-size` (on content) | `sm`, `md`, `lg` | (no CSS rules in source; reserved for consumer extension) | n/a |
103
+ | `data-size` (on content) | `sm`, `md`, `lg` | Top/bottom minimum-height and side-panel width bands | n/a |
106
104
  | `data-slot` | `drawer-overlay`, `drawer-content`, `drawer-handle`, `drawer-header`, `drawer-footer`, `drawer-title`, `drawer-description` | (CSS hook only) | n/a |
107
105
 
108
106
  **Responsive behavior:**
109
107
 
110
- - Content `height` and `width` props are responsive via CSS variables (`--dsx-r-height`, `--dsx-r-width`).
108
+ - Content size is single-valued. It does not expose responsive height/width props. Viewport caps and scrolling are intrinsic.
111
109
 
112
110
  **Reduced motion:**
113
111
 
@@ -208,7 +206,7 @@ Rules:
208
206
 
209
207
  **Token story:**
210
208
 
211
- - Renders inside a `Theme` wrapper with `accentColor="silver"` and `accentColor="bronze"`. Drawer does not track `data-accent-color` directly; the story asserts the overlay and content surfaces are visually unchanged.
209
+ - Renders inside a `Theme` wrapper with `accentColor="astral"` and `accentColor="spark"`. Drawer does not track `data-accent-color` directly; the story asserts the overlay and content surfaces are visually unchanged.
212
210
 
213
211
  **A11y story:**
214
212
 
@@ -243,3 +241,16 @@ Rules:
243
241
 
244
242
  - App-owned data: the drawer content, the trigger label, the action handlers, and the open state when controlled.
245
243
  - DS-owned visuals: token bindings, the slot CSS classes, the motion presets, and the portal theme mirroring.
244
+
245
+ ## Overlay review containment
246
+
247
+ Content caps at 100dvh and its containing viewport width, wraps long words,
248
+ and scrolls vertically. Direct content regions do not shrink into each other.
249
+ Left/right content uses height=100dvh with min-height=0 and width bands capped
250
+ at 100%; top/bottom content retains its minimum-height size bands. No width
251
+ media query is required. `/docs/drawer` opens all four directions and offers
252
+ short/long content to verify both the first row and the footer after scrolling.
253
+
254
+ The package disables Vaul’s offscreen ::after filler on its scrolling shell.
255
+ That pseudo-element otherwise adds blank scroll range and covers bottom-drawer
256
+ footer controls after scrolling; it is unnecessary for the bounded surface.
@@ -39,7 +39,7 @@ A button-triggered secondary action menu. The DS `DropdownMenu` wraps `@radix-ui
39
39
  | `DropdownMenu.CheckboxItem` | Radix `DropdownMenu.CheckboxItem` | `dsx-dropdown-menu__item` + `dsx-dropdown-menu__item-indicator` | Checkbox row. Renders `check` or `minus` indicator. |
40
40
  | `DropdownMenu.RadioItem` | Radix `DropdownMenu.RadioItem` | `dsx-dropdown-menu__item` + `dsx-dropdown-menu__item-indicator` + `dsx-dropdown-menu__radio-dot` | Radio row. |
41
41
  | `DropdownMenu.SubTrigger` | Radix `DropdownMenu.SubTrigger` | `dsx-dropdown-menu__item` + `dsx-dropdown-menu__sub-trigger` + optional `data-inset` + `chevron-right` | Row that opens the sub-content. |
42
- | `DropdownMenu.SubContent` | Radix `DropdownMenu.SubContent` inside `MenuContent` (no portal) | `dsx-dropdown-menu__content` | The submenu panel. `MenuContent` is invoked with `forceMount`, `open`, and `portal === null` so the sub-content renders inline. |
42
+ | `DropdownMenu.SubContent` | Radix `DropdownMenu.SubContent` inside portal-mounted `MenuContent` | `dsx-dropdown-menu__content` | The submenu panel tracks its own Sub open state and uses a portal so the parent scroll frame does not clip it. forceMount remains consumer-controlled. |
43
43
  | `DropdownMenu.Shortcut` | `<span>` (or `Slot` child when `asChild`) | `dsx-dropdown-menu__shortcut` | Keyboard hint rendered on the right. |
44
44
 
45
45
  The roster's `Parent / Slots` column lists `DropdownMenu.Root`, `DropdownMenu.Trigger`, `DropdownMenu.Content`, `DropdownMenu.Label`, `DropdownMenu.Separator`, `DropdownMenu.Item`, `DropdownMenu.Group`. The source exports the full Radix part set through `Object.assign`, including `Sub`, `RadioGroup`, `Portal`, `CheckboxItem`, `RadioItem`, `SubTrigger`, `SubContent`, and `Shortcut`. The spec records the full set so the public surface is unambiguous.
@@ -71,7 +71,7 @@ The roster's `Parent / Slots` column lists `DropdownMenu.Root`, `DropdownMenu.Tr
71
71
 
72
72
  ### `DropdownMenu.Trigger`, `DropdownMenu.Label`, `DropdownMenu.Separator`, `DropdownMenu.Group`, `DropdownMenu.Sub`, `DropdownMenu.RadioGroup`, `DropdownMenu.Portal`, `DropdownMenu.CheckboxItem`, `DropdownMenu.RadioItem`, `DropdownMenu.SubTrigger`, `DropdownMenu.SubContent`
73
73
 
74
- These proxy the corresponding Radix props. `DropdownMenu.Trigger` accepts the standard Radix trigger props (no class). `DropdownMenu.Label` and `DropdownMenu.Group` accept the standard Radix props. `DropdownMenu.SubContent` accepts the same `align` and `side` props as `Content`; the portal is forced to `null` so the sub-content renders inline.
74
+ These proxy the corresponding Radix props. `DropdownMenu.Trigger` accepts the standard Radix trigger props (no class). `DropdownMenu.Label` and `DropdownMenu.Group` accept the standard Radix props. `DropdownMenu.SubContent` accepts the same `align` and `side` props as `Content`; Sub preserves controlled/uncontrolled open props; SubContent uses the Radix portal and its owning Sub state.
75
75
 
76
76
  ### `DropdownMenu.Item`
77
77
 
@@ -288,3 +288,12 @@ Rules:
288
288
 
289
289
  - App-owned data: the command set, the disabled reasons, the trigger element, and the keyboard shortcut strings.
290
290
  - DS-owned visuals: the `dsx-dropdown-menu__*` slot classes, the token bindings, the data-attribute contract, and the open / close animation.
291
+
292
+ ## Overlay review interaction
293
+
294
+ Submenus are absent while closed unless forceMount is requested. Sub owns
295
+ controlled/uncontrolled state and SubContent receives that state through a
296
+ private context; it is no longer forced open. Portalling matches the
297
+ [Radix submenu anatomy](https://www.radix-ui.com/primitives/docs/components/dropdown-menu)
298
+ and keeps the submenu outside the parent’s overflow frame. The live example
299
+ demonstrates working Profile/Settings, Autosave and Share project actions.
@@ -105,7 +105,7 @@ Rules:
105
105
 
106
106
  ## Playground demo spec
107
107
 
108
- `Em` is registered in `apps/playground/lib/registry/typography.tsx` under the `em` key. The registry entry imports `emPropDefs` and renders the component with a sample emphasis span. Per-component route: `/docs/em`.
108
+ `Em` is registered in `apps/playground/lib/registry/typography.tsx` under the `em` key. The registry entry imports `emPropDefs` and renders the component with a sample emphasis span. Per-component route: `/docs/em`. The live example uses English and Russian sentence context plus a slotted span.
109
109
 
110
110
  **Default story:**
111
111