@ds-mo/ui 12.5.0 → 12.6.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 (289) hide show
  1. package/dist/.build-stamp +1 -1
  2. package/dist/agent-patterns.json +21 -12
  3. package/dist/agent.json +1540 -1427
  4. package/dist/angular/ds-bar-workflow.d.ts +1 -1
  5. package/dist/angular/ds-bar-workflow.js +3 -3
  6. package/dist/angular/ds-mobile-bar-nav.d.ts +18 -0
  7. package/dist/angular/{ds-shell-mobile-bar.js → ds-mobile-bar-nav.js} +15 -15
  8. package/dist/angular/ds-mobile-header.d.ts +23 -0
  9. package/dist/angular/ds-mobile-header.js +45 -0
  10. package/dist/angular/ds-mobile-section-switcher.d.ts +18 -0
  11. package/dist/angular/{ds-shell-mobile-section-nav.js → ds-mobile-section-switcher.js} +15 -15
  12. package/dist/angular/ds-mobile-sheet-nav.d.ts +20 -0
  13. package/dist/angular/{ds-shell-mobile-nav.js → ds-mobile-sheet-nav.js} +13 -16
  14. package/dist/angular/ds-shell-app.d.ts +1 -1
  15. package/dist/angular/ds-shell-app.js +3 -3
  16. package/dist/angular/ds-shell-page.d.ts +1 -1
  17. package/dist/angular/ds-shell-page.js +3 -3
  18. package/dist/angular/index.d.ts +1 -1
  19. package/dist/angular/index.js +4 -3
  20. package/dist/angular/proxies.d.ts +4 -3
  21. package/dist/angular/proxies.js +4 -3
  22. package/dist/components/ds-agent-activity.js +1 -1
  23. package/dist/components/ds-agent-response.js +1 -1
  24. package/dist/components/ds-agent-tool-call.js +1 -1
  25. package/dist/components/ds-avatar.js +1 -1
  26. package/dist/components/ds-avatar.js.map +1 -1
  27. package/dist/components/ds-badge.js +1 -1
  28. package/dist/components/ds-bar-nav.js +1 -1
  29. package/dist/components/ds-bar-nav.js.map +1 -1
  30. package/dist/components/ds-bar-title.js +1 -1
  31. package/dist/components/ds-bar-title.js.map +1 -1
  32. package/dist/components/ds-bar-workflow.js +1 -1
  33. package/dist/components/ds-bar-workflow.js.map +1 -1
  34. package/dist/components/ds-breadcrumb.js +1 -1
  35. package/dist/components/ds-button-filled.js +1 -1
  36. package/dist/components/ds-button-unfilled.js +1 -1
  37. package/dist/components/ds-card-data-viz-bar.js +1 -1
  38. package/dist/components/ds-card-data-viz-donut.js +1 -1
  39. package/dist/components/ds-card-data-viz-line.js +1 -1
  40. package/dist/components/ds-card-setting.js +1 -1
  41. package/dist/components/ds-chart-bar.js +1 -1
  42. package/dist/components/ds-chart-donut.js +1 -1
  43. package/dist/components/ds-chart-legend.js +1 -1
  44. package/dist/components/ds-chart-legend.js.map +1 -1
  45. package/dist/components/ds-chart-line.js +1 -1
  46. package/dist/components/ds-checkbox.js +1 -1
  47. package/dist/components/ds-chip.js +1 -1
  48. package/dist/components/ds-chip.js.map +1 -1
  49. package/dist/components/ds-code-block.js +1 -1
  50. package/dist/components/ds-conversation-list-item.js +1 -1
  51. package/dist/components/ds-conversation-list-item.js.map +1 -1
  52. package/dist/components/ds-conversation-list-section.js +1 -1
  53. package/dist/components/ds-empty-state.js +1 -1
  54. package/dist/components/ds-field.js +1 -1
  55. package/dist/components/ds-input.js +1 -1
  56. package/dist/components/ds-input.js.map +1 -1
  57. package/dist/components/ds-loader.js +1 -1
  58. package/dist/components/ds-markdown.js +1 -1
  59. package/dist/components/ds-menu.js +1 -1
  60. package/dist/components/ds-message-composer.js +1 -1
  61. package/dist/components/ds-message-composer.js.map +1 -1
  62. package/dist/components/ds-message-scroller.js +1 -1
  63. package/dist/components/ds-message.js +1 -1
  64. package/dist/components/{ds-shell-mobile-nav.d.ts → ds-mobile-bar-nav.d.ts} +4 -4
  65. package/dist/components/ds-mobile-bar-nav.js +2 -0
  66. package/dist/components/ds-mobile-bar-nav.js.map +1 -0
  67. package/dist/components/ds-mobile-header.d.ts +11 -0
  68. package/dist/components/ds-mobile-header.js +2 -0
  69. package/dist/components/ds-mobile-header.js.map +1 -0
  70. package/dist/components/ds-mobile-section-switcher.d.ts +11 -0
  71. package/dist/components/ds-mobile-section-switcher.js +2 -0
  72. package/dist/components/ds-mobile-section-switcher.js.map +1 -0
  73. package/dist/components/{ds-shell-mobile-bar.d.ts → ds-mobile-sheet-nav.d.ts} +4 -4
  74. package/dist/components/ds-mobile-sheet-nav.js +2 -0
  75. package/dist/components/ds-mobile-sheet-nav.js.map +1 -0
  76. package/dist/components/ds-modal.js +1 -1
  77. package/dist/components/ds-modal.js.map +1 -1
  78. package/dist/components/ds-panel-nav.js +1 -1
  79. package/dist/components/ds-panel-nav.js.map +1 -1
  80. package/dist/components/ds-panel-sub-nav.js +1 -1
  81. package/dist/components/ds-panel-sub-nav.js.map +1 -1
  82. package/dist/components/ds-panel-tool-header.js +1 -1
  83. package/dist/components/ds-panel-tool-search.js +1 -1
  84. package/dist/components/ds-panel-tool-search.js.map +1 -1
  85. package/dist/components/ds-panel-tools.js +1 -1
  86. package/dist/components/ds-radio.js +1 -1
  87. package/dist/components/ds-radio.js.map +1 -1
  88. package/dist/components/ds-select-multi.js +1 -1
  89. package/dist/components/ds-select-multi.js.map +1 -1
  90. package/dist/components/ds-select.js +1 -1
  91. package/dist/components/ds-select.js.map +1 -1
  92. package/dist/components/ds-shell-app.js +1 -1
  93. package/dist/components/ds-shell-app.js.map +1 -1
  94. package/dist/components/ds-shell-gradient-picker.js +1 -1
  95. package/dist/components/ds-shell-gradient-picker.js.map +1 -1
  96. package/dist/components/ds-shell-gradient-swatch.js +1 -1
  97. package/dist/components/ds-shell-gradient-swatch.js.map +1 -1
  98. package/dist/components/ds-shell-page.js +1 -1
  99. package/dist/components/ds-shell-page.js.map +1 -1
  100. package/dist/components/ds-shell-tools.js +1 -1
  101. package/dist/components/ds-shell-tools.js.map +1 -1
  102. package/dist/components/ds-skeleton.js +1 -1
  103. package/dist/components/ds-skeleton.js.map +1 -1
  104. package/dist/components/ds-swatch-picker.js +1 -1
  105. package/dist/components/ds-switch.js +1 -1
  106. package/dist/components/ds-tab-group.js +1 -1
  107. package/dist/components/ds-tag.js +1 -1
  108. package/dist/components/ds-tag.js.map +1 -1
  109. package/dist/components/ds-toast.js +1 -1
  110. package/dist/components/ds-toast.js.map +1 -1
  111. package/dist/components/ds-tooltip-data-viz.js +1 -1
  112. package/dist/components/ds-tooltip.js +1 -1
  113. package/dist/components/ds-typing-indicator.js +1 -1
  114. package/dist/components/p-4h7vAqyJ.js +2 -0
  115. package/dist/components/p-4h7vAqyJ.js.map +1 -0
  116. package/dist/components/p-6WdUnsGC.js +2 -0
  117. package/dist/components/p-6WdUnsGC.js.map +1 -0
  118. package/dist/components/{p-9dQQSgwT.js → p-BHYrsGBw.js} +2 -2
  119. package/dist/components/p-BY0PzkUp.js +2 -0
  120. package/dist/components/p-BdPaDhDe.js +2 -0
  121. package/dist/components/p-BdPaDhDe.js.map +1 -0
  122. package/dist/components/p-BgGP65Nn.js +2 -0
  123. package/dist/components/p-BgGP65Nn.js.map +1 -0
  124. package/dist/components/p-BkAMkjIR.js +2 -0
  125. package/dist/components/{p-Co8hD3P-.js.map → p-BkAMkjIR.js.map} +1 -1
  126. package/dist/components/p-BqPLwCrR.js +2 -0
  127. package/dist/components/{p-CtD24EyI.js.map → p-BqPLwCrR.js.map} +1 -1
  128. package/dist/components/p-BrusnEYP.js.map +1 -1
  129. package/dist/components/p-C2ym_Ich.js +2 -0
  130. package/dist/components/p-CKGlB6Ow.js +2 -0
  131. package/dist/components/p-CKGlB6Ow.js.map +1 -0
  132. package/dist/components/p-CLzlL3G4.js +2 -0
  133. package/dist/components/p-CLzlL3G4.js.map +1 -0
  134. package/dist/components/p-CPK5Tgae.js +2 -0
  135. package/dist/components/p-CPK5Tgae.js.map +1 -0
  136. package/dist/components/p-CUWxI1u0.js +2 -0
  137. package/dist/components/{p-BhxwpOH8.js.map → p-CUWxI1u0.js.map} +1 -1
  138. package/dist/components/p-Ca-I2UnB.js +2 -0
  139. package/dist/components/p-Ca-I2UnB.js.map +1 -0
  140. package/dist/components/p-CaRyxTMz.js +2 -0
  141. package/dist/components/p-CaRyxTMz.js.map +1 -0
  142. package/dist/components/p-D65itwnc.js +2 -0
  143. package/dist/components/p-D65itwnc.js.map +1 -0
  144. package/dist/components/{p-DjPZxzIG.js → p-DQDpDYyF.js} +2 -2
  145. package/dist/components/p-DWdRSOBV.js +2 -0
  146. package/dist/components/{p-BPS9VExm.js.map → p-DWdRSOBV.js.map} +1 -1
  147. package/dist/components/p-Dg3xLna0.js +2 -0
  148. package/dist/components/{p-C_0Q8Cnp.js.map → p-Dg3xLna0.js.map} +1 -1
  149. package/dist/components/p-DikRzG5f.js +2 -0
  150. package/dist/components/{p-PZ6R_nGI.js.map → p-DikRzG5f.js.map} +1 -1
  151. package/dist/components/p-Dq1vMuJb.js +2 -0
  152. package/dist/components/p-Dq1vMuJb.js.map +1 -0
  153. package/dist/components/{p-g40DTeV8.js → p-DzRBKJ2L.js} +2 -2
  154. package/dist/components/p-P5BMmQAc.js +2 -0
  155. package/dist/components/{p-Biz6xo-z.js.map → p-P5BMmQAc.js.map} +1 -1
  156. package/dist/components/{p-DXnFhmZF.js → p-hLPTSGdo.js} +2 -2
  157. package/dist/components/p-rsIOpkzV.js +2 -0
  158. package/dist/components/p-rsIOpkzV.js.map +1 -0
  159. package/dist/docs/components.json +3587 -3065
  160. package/dist/lib/shell/index.d.ts +1 -1
  161. package/dist/lib/shell/index.js +2 -1
  162. package/dist/lib/shell/index.js.map +2 -2
  163. package/dist/lib/shell/shell-responsive.d.ts +3 -3
  164. package/dist/lib/utils/index.d.ts +1 -0
  165. package/dist/lib/utils/index.js +8 -0
  166. package/dist/lib/utils/index.js.map +3 -3
  167. package/dist/lib/utils/required-validity.d.ts +14 -0
  168. package/dist/mcp-data/registry/agent-activity.json +2 -2
  169. package/dist/mcp-data/registry/badge.json +2 -2
  170. package/dist/mcp-data/registry/bar-nav.json +2 -2
  171. package/dist/mcp-data/registry/bar-title.json +2 -2
  172. package/dist/mcp-data/registry/bar-workflow.json +25 -4
  173. package/dist/mcp-data/registry/breadcrumb.json +2 -2
  174. package/dist/mcp-data/registry/button-unfilled.json +3 -3
  175. package/dist/mcp-data/registry/chart-legend.json +1 -1
  176. package/dist/mcp-data/registry/checkbox.json +1 -1
  177. package/dist/mcp-data/registry/conversation-list-item.json +2 -2
  178. package/dist/mcp-data/registry/input.json +1 -1
  179. package/dist/mcp-data/registry/loader.json +2 -2
  180. package/dist/mcp-data/registry/menu.json +7 -7
  181. package/dist/mcp-data/registry/mobile-bar-nav.json +333 -0
  182. package/dist/mcp-data/registry/mobile-header.json +351 -0
  183. package/dist/mcp-data/registry/mobile-section-switcher.json +211 -0
  184. package/dist/mcp-data/registry/mobile-sheet-nav.json +317 -0
  185. package/dist/mcp-data/registry/panel-nav.json +2 -2
  186. package/dist/mcp-data/registry/panel-tools.json +2 -2
  187. package/dist/mcp-data/registry/radio.json +1 -1
  188. package/dist/mcp-data/registry/registry.json +1548 -1432
  189. package/dist/mcp-data/registry/select-multi.json +1 -1
  190. package/dist/mcp-data/registry/select.json +2 -2
  191. package/dist/mcp-data/registry/shell-app.json +17 -17
  192. package/dist/mcp-data/registry/shell-page.json +26 -7
  193. package/dist/mcp-data/registry/shell-tools.json +10 -7
  194. package/dist/mcp-data/registry/switch.json +1 -1
  195. package/dist/mcp-data/registry/toast.json +2 -2
  196. package/dist/react/components.d.ts +4 -3
  197. package/dist/react/components.js +4 -3
  198. package/dist/react/ds-mobile-bar-nav.d.ts +13 -0
  199. package/dist/react/ds-mobile-bar-nav.js +15 -0
  200. package/dist/react/ds-mobile-header.d.ts +13 -0
  201. package/dist/react/ds-mobile-header.js +15 -0
  202. package/dist/react/ds-mobile-section-switcher.d.ts +12 -0
  203. package/dist/react/ds-mobile-section-switcher.js +12 -0
  204. package/dist/react/ds-mobile-sheet-nav.d.ts +14 -0
  205. package/dist/react/ds-mobile-sheet-nav.js +16 -0
  206. package/dist/types/components/BarWorkflow/BarWorkflow.d.ts +6 -0
  207. package/dist/types/components/ButtonUnfilled/ButtonUnfilled.d.ts +1 -1
  208. package/dist/types/components/Menu/Menu.d.ts +1 -1
  209. package/dist/types/components/MobileBarNav/MobileBarNav.d.ts +26 -0
  210. package/dist/types/components/MobileBarNav/index.d.ts +4 -0
  211. package/dist/types/components/MobileBarNav/mobile-bar-nav-types.d.ts +5 -0
  212. package/dist/types/components/MobileHeader/MobileHeader.d.ts +39 -0
  213. package/dist/types/components/MobileHeader/index.d.ts +2 -0
  214. package/dist/types/components/MobileHeader/mobile-header-types.d.ts +5 -0
  215. package/dist/types/components/MobileSectionSwitcher/MobileSectionSwitcher.d.ts +35 -0
  216. package/dist/types/components/MobileSectionSwitcher/index.d.ts +3 -0
  217. package/dist/types/components/MobileSectionSwitcher/mobile-section-switcher-types.d.ts +4 -0
  218. package/dist/types/components/MobileSectionSwitcher/mobile-section-switcher-utils.d.ts +10 -0
  219. package/dist/types/components/{ShellMobileNav/ShellMobileNav.d.ts → MobileSheetNav/MobileSheetNav.d.ts} +5 -7
  220. package/dist/types/components/MobileSheetNav/index.d.ts +1 -0
  221. package/dist/types/components/ShellApp/ShellApp.d.ts +4 -4
  222. package/dist/types/components/ShellPage/ShellPage.d.ts +4 -0
  223. package/dist/types/components.d.ts +532 -383
  224. package/dist/types/shell/index.d.ts +1 -1
  225. package/dist/types/shell/shell-responsive.d.ts +3 -3
  226. package/dist/types/utils/index.d.ts +1 -0
  227. package/dist/types/utils/required-validity.d.ts +15 -0
  228. package/package.json +1 -1
  229. package/dist/angular/ds-shell-mobile-bar.d.ts +0 -18
  230. package/dist/angular/ds-shell-mobile-nav.d.ts +0 -23
  231. package/dist/angular/ds-shell-mobile-section-nav.d.ts +0 -18
  232. package/dist/components/ds-shell-mobile-bar.js +0 -2
  233. package/dist/components/ds-shell-mobile-bar.js.map +0 -1
  234. package/dist/components/ds-shell-mobile-nav.js +0 -2
  235. package/dist/components/ds-shell-mobile-nav.js.map +0 -1
  236. package/dist/components/ds-shell-mobile-section-nav.d.ts +0 -11
  237. package/dist/components/ds-shell-mobile-section-nav.js +0 -2
  238. package/dist/components/ds-shell-mobile-section-nav.js.map +0 -1
  239. package/dist/components/p-B6Vuayt6.js +0 -2
  240. package/dist/components/p-B6Vuayt6.js.map +0 -1
  241. package/dist/components/p-BPS9VExm.js +0 -2
  242. package/dist/components/p-BVV_rlIP.js +0 -2
  243. package/dist/components/p-BVV_rlIP.js.map +0 -1
  244. package/dist/components/p-BhxwpOH8.js +0 -2
  245. package/dist/components/p-Biz6xo-z.js +0 -2
  246. package/dist/components/p-BtEjlcB9.js +0 -2
  247. package/dist/components/p-BtEjlcB9.js.map +0 -1
  248. package/dist/components/p-CH6cNXXF.js +0 -2
  249. package/dist/components/p-CH6cNXXF.js.map +0 -1
  250. package/dist/components/p-C_0Q8Cnp.js +0 -2
  251. package/dist/components/p-Ce52yVXF.js +0 -2
  252. package/dist/components/p-Ce52yVXF.js.map +0 -1
  253. package/dist/components/p-CgHTNfC1.js +0 -2
  254. package/dist/components/p-CgHTNfC1.js.map +0 -1
  255. package/dist/components/p-Co8hD3P-.js +0 -2
  256. package/dist/components/p-CoYFJD-w.js +0 -2
  257. package/dist/components/p-CoYFJD-w.js.map +0 -1
  258. package/dist/components/p-Cpr3K41-.js +0 -2
  259. package/dist/components/p-Cpr3K41-.js.map +0 -1
  260. package/dist/components/p-CtD24EyI.js +0 -2
  261. package/dist/components/p-DYqReipj.js +0 -2
  262. package/dist/components/p-DYqReipj.js.map +0 -1
  263. package/dist/components/p-NUNsefU1.js +0 -2
  264. package/dist/components/p-NUNsefU1.js.map +0 -1
  265. package/dist/components/p-PZ6R_nGI.js +0 -2
  266. package/dist/components/p-jCWtxthA.js +0 -2
  267. package/dist/components/p-yhj1lIPx.js +0 -2
  268. package/dist/mcp-data/registry/shell-mobile-bar.json +0 -314
  269. package/dist/mcp-data/registry/shell-mobile-nav.json +0 -348
  270. package/dist/mcp-data/registry/shell-mobile-section-nav.json +0 -267
  271. package/dist/react/ds-shell-mobile-bar.d.ts +0 -13
  272. package/dist/react/ds-shell-mobile-bar.js +0 -15
  273. package/dist/react/ds-shell-mobile-nav.d.ts +0 -15
  274. package/dist/react/ds-shell-mobile-nav.js +0 -17
  275. package/dist/react/ds-shell-mobile-section-nav.d.ts +0 -12
  276. package/dist/react/ds-shell-mobile-section-nav.js +0 -12
  277. package/dist/types/components/ShellMobileBar/ShellMobileBar.d.ts +0 -25
  278. package/dist/types/components/ShellMobileBar/index.d.ts +0 -4
  279. package/dist/types/components/ShellMobileBar/shell-mobile-bar-types.d.ts +0 -5
  280. package/dist/types/components/ShellMobileNav/index.d.ts +0 -2
  281. package/dist/types/components/ShellMobileNav/shell-mobile-nav-types.d.ts +0 -6
  282. package/dist/types/components/ShellMobileSectionNav/ShellMobileSectionNav.d.ts +0 -30
  283. package/dist/types/components/ShellMobileSectionNav/index.d.ts +0 -2
  284. /package/dist/components/{p-9dQQSgwT.js.map → p-BHYrsGBw.js.map} +0 -0
  285. /package/dist/components/{p-jCWtxthA.js.map → p-BY0PzkUp.js.map} +0 -0
  286. /package/dist/components/{p-yhj1lIPx.js.map → p-C2ym_Ich.js.map} +0 -0
  287. /package/dist/components/{p-DjPZxzIG.js.map → p-DQDpDYyF.js.map} +0 -0
  288. /package/dist/components/{p-g40DTeV8.js.map → p-DzRBKJ2L.js.map} +0 -0
  289. /package/dist/components/{p-DXnFhmZF.js.map → p-hLPTSGdo.js.map} +0 -0
package/dist/agent.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
3
  "package": "@ds-mo/ui",
4
- "packageVersion": "12.5.0",
4
+ "packageVersion": "12.6.1",
5
5
  "kind": "components",
6
6
  "entries": [
7
7
  {
@@ -1010,6 +1010,7 @@
1010
1010
  ],
1011
1011
  "commonlyComposedWith": [
1012
1012
  "component:ds-shell-page",
1013
+ "component:ds-mobile-header",
1013
1014
  "component:ds-button-filled",
1014
1015
  "component:ds-button-unfilled",
1015
1016
  "component:ds-text",
@@ -1024,7 +1025,7 @@
1024
1025
  "Use submitAction.type=submit inside a form so the final action preserves native submission semantics."
1025
1026
  ],
1026
1027
  "states": [
1027
- "BarWorkflow always renders compact 48px bold-brand chrome and has no expanded, constrained, or responsive variant.",
1028
+ "BarWorkflow always renders compact 48px bold-brand chrome; responsiveMode changes only the action geometry, never workflow state or hierarchy.",
1028
1029
  "An unrecognized value resolves navigation from the first step without mutating the controlled value.",
1029
1030
  "The first step omits Previous. Intermediate steps show Previous and Next. The last step replaces Next with the Check Save or Submit action.",
1030
1031
  "The default empty steps array is a single-step flow with the plain heading, no Previous control, and the final action visible. An explicit one-step array behaves the same way.",
@@ -1032,7 +1033,8 @@
1032
1033
  "submitAction owns the final label, native button type, inactive state, and loading state."
1033
1034
  ],
1034
1035
  "responsiveBehavior": [
1035
- "BarWorkflow does not expose a presentation variant and never collapses its navigation actions.",
1036
+ "Desktop and tablet keep the established left-aligned identity and trailing actions.",
1037
+ "Mobile uses symmetric MobileHeader geometry with Exit leading, the title and step count centered, and Previous plus Next or Submit trailing.",
1036
1038
  "The heading truncates before Exit, Previous, and Next or Submit lose their complete hit targets.",
1037
1039
  "When slotted into ShellPage, BarWorkflow remains compact while ShellPage continues to provide sticky placement."
1038
1040
  ],
@@ -1087,6 +1089,10 @@
1087
1089
  "type": "string",
1088
1090
  "required": false
1089
1091
  },
1092
+ "responsiveMode": {
1093
+ "type": "ShellResponsiveMode",
1094
+ "required": false
1095
+ },
1090
1096
  "steps": {
1091
1097
  "type": "BarWorkflowStep[]",
1092
1098
  "required": false
@@ -1128,6 +1134,7 @@
1128
1134
  "componentDependencies": [
1129
1135
  "button-filled",
1130
1136
  "button-unfilled",
1137
+ "mobile-header",
1131
1138
  "text",
1132
1139
  "tooltip"
1133
1140
  ]
@@ -4266,12 +4273,12 @@
4266
4273
  "tag": "ds-menu",
4267
4274
  "name": "menu",
4268
4275
  "title": "Menu",
4269
- "summary": "Anchored action menu with flat commands, grouped sections, single-selection radio choices, supplemental notification dots, switches, and destructive actions.",
4276
+ "summary": "Anchored action menu with flat commands, grouped sections, single-selection choices, supplemental notification dots, switches, and destructive actions.",
4270
4277
  "intentStatus": "complete",
4271
4278
  "intent": {
4272
4279
  "audience": "general",
4273
4280
  "status": "stable",
4274
- "summary": "Anchored action menu with flat commands, grouped sections, single-selection radio choices, supplemental notification dots, switches, and destructive actions.",
4281
+ "summary": "Anchored action menu with flat commands, grouped sections, single-selection choices, supplemental notification dots, switches, and destructive actions.",
4275
4282
  "useWhen": [
4276
4283
  "A trigger reveals a short contextual list of commands or state-changing actions.",
4277
4284
  "Actions need grouping, mutually exclusive selected state, supplemental notification dots, switch rows, or destructive treatment."
@@ -4312,7 +4319,7 @@
4312
4319
  "Open with visible initial focus only when the trigger was activated from the keyboard.",
4313
4320
  "Keep disabled items discoverable only when their unavailable state is meaningful.",
4314
4321
  "Switch rows use menuitemcheckbox semantics on the row; the nested ds-switch is an aria-hidden md presentation indicator.",
4315
- "Single-selection menus use menuitemradio semantics and aria-checked on each row; the leading radio mark is presentation-only.",
4322
+ "Single-selection menus use menuitemradio semantics and aria-checked on each row, but render no nested radio control; selected interaction fill and primary foreground provide the visual state.",
4316
4323
  "A swatch-picker section changes the popup to a non-modal dialog so its radio group and ordinary preference buttons keep valid nested semantics; Tab moves between its controls, then leaves and closes at the popup boundary.",
4317
4324
  "Use notification dots only as supplemental status and not as the sole indication of important information."
4318
4325
  ],
@@ -4818,488 +4825,304 @@
4818
4825
  ]
4819
4826
  },
4820
4827
  {
4821
- "id": "component:ds-modal",
4822
- "tag": "ds-modal",
4823
- "name": "modal",
4824
- "title": "Modal",
4825
- "summary": "Dismissible native top-layer dialog for a focused confirmation or short blocking task, with a fixed title-and-close header, composable content, and an optional two-action footer.",
4828
+ "id": "component:ds-mobile-bar-nav",
4829
+ "tag": "ds-mobile-bar-nav",
4830
+ "name": "mobile-bar-nav",
4831
+ "title": "MobileBarNav",
4832
+ "summary": "Persistent mobile shell navigation for Menu, the router-derived current area, Search, Agents, and Inbox.",
4826
4833
  "intentStatus": "complete",
4827
4834
  "intent": {
4828
- "audience": "general",
4829
- "status": "stable",
4830
- "summary": "Dismissible native top-layer dialog for a focused confirmation or short blocking task, with a fixed title-and-close header, composable content, and an optional two-action footer.",
4835
+ "audience": "specialized",
4836
+ "status": "experimental",
4837
+ "summary": "Persistent mobile shell navigation for Menu, the router-derived current area, Search, Agents, and Inbox.",
4831
4838
  "useWhen": [
4832
- "The user must confirm or cancel one focused decision before returning to the underlying interface.",
4833
- "A short blocking task or compact form needs dialog semantics, focus containment, and explicit completion actions.",
4834
- "The content can be safely dismissed through Close, Escape, or the backdrop."
4839
+ "ShellApp is rendering its dedicated below-768px application composition."
4835
4840
  ],
4836
4841
  "avoidWhen": [
4837
- "The message is non-blocking feedback or a transient status update.",
4838
- "The interaction is a contextual list of commands anchored to a trigger.",
4839
- "The workflow is multi-step, long-form, or requires substantial navigation.",
4840
- "Dismissal would lose work or leave an irreversible operation in an unsafe state.",
4841
- "A second modal would be opened over an existing modal."
4842
- ],
4843
- "alternatives": [
4844
- {
4845
- "when": "The user needs non-blocking feedback or a transient status message.",
4846
- "component": "component:ds-toast",
4847
- "reason": "Toast communicates transient status without trapping focus or blocking the page."
4848
- },
4849
- {
4850
- "when": "A trigger reveals a short contextual list of commands.",
4851
- "component": "component:ds-menu",
4852
- "reason": "Menu provides anchored command semantics without creating a blocking dialog."
4853
- },
4854
- {
4855
- "when": "Editable settings should remain visible without blocking the rest of the interface.",
4856
- "component": "component:ds-card-setting",
4857
- "reason": "CardSetting provides a persistent controlled settings workflow without modal focus containment."
4858
- }
4842
+ "Rendering desktop or tablet shell chrome.",
4843
+ "An arbitrary set of product tabs is required."
4859
4844
  ],
4860
4845
  "commonlyComposedWith": [
4861
- "component:ds-button-filled",
4862
- "component:ds-button-unfilled",
4863
- "component:ds-field",
4864
- "component:ds-text"
4846
+ "component:ds-shell-app"
4847
+ ],
4848
+ "patterns": [
4849
+ "pattern:application-shell"
4865
4850
  ],
4866
4851
  "accessibility": [
4867
- "Provide a concise visible heading; the component uses it as the dialog's accessible name.",
4868
- "Give the primary explanatory copy a stable id and pass it through aria-describedby so assistive technology receives the decision context.",
4869
- "Opening the native modal dialog moves focus to the header Close action, whose visible tooltip matches its accessible name, traps Tab navigation inside the top layer, and makes outside content inert.",
4870
- "Close, Escape, and backdrop activation emit dsClose with close-button, escape, or backdrop reason before beginning dismissal; use the component only when every dismissal path is safe.",
4871
- "After exit motion completes, the native dialog leaves the top layer, focus returns to the previously focused element, and dsAfterClose emits.",
4872
- "Use visible label-only footer buttons. Keep at most two actions: one bold filled primary action followed by one bordered unfilled action, or two bordered unfilled actions.",
4873
- "Use negative intent for a filled destructive action and state the irreversible consequence in the content.",
4874
- "Do not open a modal from another modal; keep one blocking decision in focus at a time."
4852
+ "Every icon-only item keeps a localized accessible name.",
4853
+ "Only the active destination exposes aria-current; Menu exposes its controlled pane through aria-expanded."
4875
4854
  ],
4876
4855
  "states": [
4877
- "The owner opens the modal through the open property and responds to the typed dsClose detail for application state synchronization or dismissal analytics.",
4878
- "The component mutates open to false for Close, Escape, and backdrop dismissal while retaining its rendered surface through exit motion.",
4879
- "The default slot owns task content; the named footer slot is optional and is hidden when no actions are assigned.",
4880
- "Primary actions use a bold filled button with semantic intent. Secondary and cancel actions use bordered label-only unfilled buttons.",
4881
- "The owner performs save, delete, cancel, and other product consequences before or while closing the modal."
4856
+ "The fixed groups are Menu plus current area, followed by Search, Inbox, and Agents.",
4857
+ "Selection promotes foreground to primary without painting a selected fill; unselected destinations use tertiary foreground.",
4858
+ "Opening Mobile Sheet Nav replaces the Menu glyph with Cross while preserving its accessible name.",
4859
+ "Reselecting an active destination does not reset its nested state."
4882
4860
  ],
4883
4861
  "responsiveBehavior": [
4884
- "Choose the smallest sm, md, or lg width that fits the focused task; the top-layer dialog clamps to the viewport with token-based outer space.",
4885
- "Content scrolls independently when needed while the 64px header and optional 64px footer remain fixed.",
4886
- "Avoid layouts whose minimum content width exceeds the narrow viewport clamp.",
4887
- "The native top layer escapes transformed ancestors, clipping containers, and application stacking contexts without moving slotted content."
4862
+ "Render only below the mobile breakpoint and preserve safe-area clearance.",
4863
+ "The secondary-background bar keeps an 8px outer inset; its two icon-only groups anchor to opposite edges while retaining fixed 40px targets and a divider between Menu and current area."
4888
4864
  ],
4889
- "frameworkCaveats": {
4890
- "customElements": [
4891
- "Set open as a JavaScript property when controlling the modal; inspect dsClose.detail.reason and use dsAfterClose for cleanup that must wait for exit motion and focus restoration.",
4892
- "Connect the most relevant slotted explanatory text through aria-describedby.",
4893
- "Footer actions are slotted application-owned controls and must implement their own product consequence."
4894
- ],
4895
- "react": [
4896
- "Pass open to DsModal, inspect onDsClose event detail, and use onDsAfterClose only for cleanup after exit motion and focus restoration.",
4897
- "Connect the most relevant slotted explanatory text through aria-describedby.",
4898
- "Assign footer controls with slot=\"footer\" and handle each action before updating open."
4899
- ],
4900
- "angular": [
4901
- "Bind [open], inspect $event.detail from (dsClose), and use (dsAfterClose) only for cleanup after exit motion and focus restoration.",
4902
- "Connect the most relevant slotted explanatory text through aria-describedby.",
4903
- "Assign footer controls with slot=\"footer\" and handle each action before updating open."
4904
- ]
4905
- },
4906
4865
  "references": [
4907
4866
  {
4908
- "label": "Storybook confirmation and footer examples",
4909
- "path": "src/wc/components/Modal/Modal.stories.ts"
4910
- },
4911
- {
4912
- "label": "Cross-browser focus, dismissal, geometry, and accessibility coverage",
4913
- "path": "tests/e2e/accessibility-overlays.spec.ts"
4914
- },
4915
- {
4916
- "label": "Reduced-motion overlay coverage",
4917
- "path": "tests/e2e/reduced-motion.spec.ts"
4867
+ "label": "Storybook",
4868
+ "path": "src/wc/components/MobileBarNav/MobileBarNav.stories.ts"
4918
4869
  }
4919
4870
  ]
4920
4871
  },
4921
4872
  "api": {
4922
4873
  "props": {
4923
- "ariaDescribedby": {
4924
- "type": "string | undefined",
4874
+ "activeDestination": {
4875
+ "type": "MobileDestination",
4925
4876
  "required": false
4926
4877
  },
4927
- "closeAriaLabel": {
4878
+ "agentsDot": {
4879
+ "type": "boolean",
4880
+ "required": false
4881
+ },
4882
+ "agentsLabel": {
4928
4883
  "type": "string",
4929
4884
  "required": false
4930
4885
  },
4931
- "heading": {
4886
+ "currentArea": {
4887
+ "type": "PanelNavItem",
4888
+ "required": false
4889
+ },
4890
+ "helpLabel": {
4932
4891
  "type": "string",
4933
- "required": true
4892
+ "required": false
4934
4893
  },
4935
- "modalWidth": {
4936
- "type": "ModalWidth | string",
4894
+ "inboxDot": {
4895
+ "type": "boolean",
4937
4896
  "required": false
4938
4897
  },
4939
- "open": {
4898
+ "inboxLabel": {
4899
+ "type": "string",
4900
+ "required": false
4901
+ },
4902
+ "menuLabel": {
4903
+ "type": "string",
4904
+ "required": false
4905
+ },
4906
+ "searchDot": {
4907
+ "type": "boolean",
4908
+ "required": false
4909
+ },
4910
+ "searchLabel": {
4911
+ "type": "string",
4912
+ "required": false
4913
+ },
4914
+ "sheetNavExpanded": {
4940
4915
  "type": "boolean",
4941
4916
  "required": false
4942
4917
  }
4943
4918
  },
4944
4919
  "events": [
4945
4920
  {
4946
- "name": "dsAfterClose",
4947
- "detail": "void"
4921
+ "name": "dsDestinationChange",
4922
+ "detail": "MobileBarNavDestinationDetail"
4948
4923
  },
4949
4924
  {
4950
- "name": "dsClose",
4951
- "detail": "ModalCloseDetail"
4925
+ "name": "dsSheetNavToggle",
4926
+ "detail": "boolean"
4952
4927
  }
4953
4928
  ],
4954
4929
  "slots": []
4955
4930
  },
4956
4931
  "exports": {
4957
- "customElement": "ds-modal",
4958
- "react": "DsModal",
4959
- "angular": "DsModal"
4932
+ "customElement": "ds-mobile-bar-nav",
4933
+ "react": "DsMobileBarNav",
4934
+ "angular": "DsMobileBarNav"
4960
4935
  },
4961
4936
  "dependencies": [
4962
4937
  "@ds-mo/ui",
4963
- "@ds-mo/tokens"
4938
+ "@ds-mo/tokens",
4939
+ "@ds-mo/icons"
4964
4940
  ],
4965
4941
  "componentDependencies": [
4966
- "button-unfilled",
4967
- "text",
4968
- "tooltip"
4942
+ "badge",
4943
+ "icon"
4969
4944
  ]
4970
4945
  },
4971
4946
  {
4972
- "id": "component:ds-panel-nav",
4973
- "tag": "ds-panel-nav",
4974
- "name": "panel-nav",
4975
- "title": "PanelNav",
4976
- "summary": "The single persistent primary navigation for an application, providing grouped top-level destinations, active-route state, standard dashboard/settings switching, user access, and collapsible desktop and tablet presentation.",
4947
+ "id": "component:ds-mobile-header",
4948
+ "tag": "ds-mobile-header",
4949
+ "name": "mobile-header",
4950
+ "title": "MobileHeader",
4951
+ "summary": "Consistent mobile top chrome with symmetric action lanes, a centered page identity or peer-section chooser, and an optional subordinate page-section row.",
4977
4952
  "intentStatus": "complete",
4978
4953
  "intent": {
4979
4954
  "audience": "specialized",
4980
- "status": "stable",
4981
- "summary": "The single persistent primary navigation for an application, providing grouped top-level destinations, active-route state, standard dashboard/settings switching, user access, and collapsible desktop and tablet presentation.",
4955
+ "status": "experimental",
4956
+ "summary": "Consistent mobile top chrome with symmetric action lanes, a centered page identity or peer-section chooser, and an optional subordinate page-section row.",
4982
4957
  "useWhen": [
4983
- "Building the one primary navigation surface for an application that uses the CompoMo system.",
4984
- "Top-level destinations must remain consistently available while the application's page content changes.",
4985
- "Primary destinations need visual grouping, icons, notification indicators, active-route state, and expanded or collapsed presentation."
4958
+ "A routed page, persistent tool, account surface, or workflow needs the canonical mobile header presentation."
4986
4959
  ],
4987
4960
  "avoidWhen": [
4988
- "A second navigation surface is needed within the same application; an application must have only one PanelNav.",
4989
- "The choices represent sections within the active primary destination; use BarNav instead.",
4990
- "The choices switch local content without changing the application's primary destination; use TabGroup instead.",
4991
- "The interaction performs a command or presents temporary contextual choices; use a button or Menu instead.",
4992
- "Building navigation below the mobile breakpoint; use the application's dedicated mobile navigation component instead."
4993
- ],
4994
- "alternatives": [
4995
- {
4996
- "when": "The choices represent route sections within the active primary destination.",
4997
- "component": "component:ds-bar-nav",
4998
- "reason": "BarNav owns secondary section navigation within the destination selected by PanelNav."
4999
- },
5000
- {
5001
- "when": "The choices switch local content without changing the application's primary destination.",
5002
- "component": "component:ds-tab-group",
5003
- "reason": "TabGroup owns local view selection and tab semantics."
5004
- },
5005
- {
5006
- "when": "The choices are commands or temporary contextual actions.",
5007
- "component": "component:ds-menu",
5008
- "reason": "Menu owns transient action and option collections rather than persistent destinations."
5009
- }
4961
+ "Rendering desktop BarTitle, BarNav, or PanelToolHeader.",
4962
+ "Rendering the Mobile Sheet Nav utility lane."
5010
4963
  ],
5011
4964
  "commonlyComposedWith": [
5012
- "component:ds-shell-app",
5013
- "component:ds-bar-nav",
5014
- "component:ds-panel-tools",
5015
- "component:ds-menu"
4965
+ "component:ds-mobile-section-switcher",
4966
+ "component:ds-shell-page",
4967
+ "component:ds-shell-tools"
5016
4968
  ],
5017
4969
  "patterns": [
5018
4970
  "pattern:application-shell"
5019
4971
  ],
5020
4972
  "accessibility": [
5021
- "Give every primary destination a concise visible label and an icon that supports rather than replaces that label.",
5022
- "Provide localized dashboard, settings, account, navigation, collapse, and expand labels.",
5023
- "Preserve accessible destination names when the panel is collapsed to icon-only presentation.",
5024
- "Use notification dots as supplemental status and never as the only indication of important information.",
5025
- "When the destination body overflows, it becomes a localized keyboard-focusable scroll region in addition to the roving destination controls.",
5026
- "Keep the standard dashboard/settings switch and user/account entry available in the footer."
4973
+ "Static screens render a real h1 or h2 according to headingLevel.",
4974
+ "Section-switching screens expose an equivalent semantic heading alongside the accessible popup trigger.",
4975
+ "Subsections use a separately named navigation landmark and never replace the semantic page identity.",
4976
+ "Leading and trailing slotted icon actions retain their own accessible names and tooltips."
5027
4977
  ],
5028
4978
  "states": [
5029
- "Render exactly one PanelNav per application; it owns primary application destinations and no other navigation role.",
5030
- "The host router owns the current route; prefer currentUrl for active destination matching and use activeId only when route matching is unavailable.",
5031
- "Use anchor mode for native links or routers that intercept anchors; use event mode when the host performs navigation from dsNavSelect.",
5032
- "Groups visually organize top-level destinations only and must not be interpreted as nested or expandable navigation.",
5033
- "Dashboard presents day-to-day operational destinations; Settings presents administrative and configuration destinations.",
5034
- "The standard footer switches the entire destination collection and navStyle between Dashboard and Settings and exposes the user/account entry.",
5035
- "The host owns the external user menu opened from dsNavUserAction.",
5036
- "Item and header controls inherit the shared md control radius while local shell geometry continues to own collapsed layout and footer animation positioning.",
5037
- "On desktop, allow user-controlled expand and collapse and persist the preference with storageKey when cross-session persistence is appropriate."
4979
+ "Without multiple sections the center renders heading.",
4980
+ "With multiple sections the center renders the controlled MobileSectionSwitcher.",
4981
+ "Optional subsections render in a second row and emit dsSubsectionChange without changing the primary section.",
4982
+ "Sections represent peer destinations at the current navigation level; subsections represent local views beneath the selected page or detail identity.",
4983
+ "Brand tone changes surface and foreground without changing geometry or interaction ownership."
5038
4984
  ],
5039
4985
  "responsiveBehavior": [
5040
- "At 1200px and wider, default to expanded, allow the user to expand or collapse, and restore the locally persisted desktop preference when available.",
5041
- "From 768px through 1199px, present PanelNav permanently collapsed and do not allow user expansion.",
5042
- "Below 768px, the consuming application replaces PanelNav with a dedicated mobile navigation component; PanelNav does not own mobile navigation.",
5043
- "ShellApp permanently owns responsive composition: it determines shell mode, enforces tablet collapse, and replaces PanelNav with future mobile navigation below 768px.",
5044
- "When the viewport is below breakpoint, PanelNav locks collapsed, disables its header toggle affordance, and preserves the persisted desktop collapse preference.",
5045
- "Collapsed presentation must preserve destination ordering, active state, notification status, and accessible names."
4986
+ "The primary 48px lane is dedicated to the below-768px presentation; optional subsections add one subordinate 48px lane.",
4987
+ "Equal flexible side lanes keep the center mathematically aligned when actions are asymmetric."
5046
4988
  ],
5047
- "frameworkCaveats": {
5048
- "customElements": [
5049
- "Assign groups as a JavaScript property for structured data; a JSON string attribute is also supported.",
5050
- "Set nav-style before the element connects when first-paint style must match the current route."
5051
- ],
5052
- "react": [
5053
- "Pass groups as an array through the generated React wrapper and synchronize currentUrl with the host router.",
5054
- "ShellApp owns mobile replacement; PanelNav enforces its configured breakpoint expansion lock."
5055
- ],
5056
- "angular": [
5057
- "Import DsPanelNav from @ds-mo/ui/angular/ds-panel-nav and bind groups as a property.",
5058
- "Bind both the nav-style attribute and navStyle property when first-paint route styling must be deterministic.",
5059
- "ShellApp owns mobile replacement; PanelNav enforces its configured breakpoint expansion lock."
5060
- ]
5061
- },
5062
4989
  "references": [
5063
4990
  {
5064
- "label": "Executable Storybook examples",
5065
- "path": "src/wc/components/PanelNav/PanelNav.stories.ts"
5066
- },
5067
- {
5068
- "label": "Framework and routing integration",
5069
- "path": "docs/framework-integration.md"
5070
- },
5071
- {
5072
- "label": "Application shell composition",
5073
- "path": "agent/patterns/application-shell/pattern.agent.json"
4991
+ "label": "Storybook",
4992
+ "path": "src/wc/components/MobileHeader/MobileHeader.stories.ts"
5074
4993
  }
5075
4994
  ]
5076
4995
  },
5077
4996
  "api": {
5078
4997
  "props": {
5079
- "accountLabel": {
4998
+ "heading": {
5080
4999
  "type": "string",
5081
5000
  "required": false
5082
5001
  },
5083
- "accountMenuExpanded": {
5084
- "type": "boolean",
5002
+ "headingLevel": {
5003
+ "type": "MobileHeaderHeadingLevel",
5085
5004
  "required": false
5086
5005
  },
5087
- "activeId": {
5088
- "type": "string",
5006
+ "sections": {
5007
+ "type": "TabItem[]",
5089
5008
  "required": false
5090
5009
  },
5091
- "breakpoint": {
5092
- "type": "number",
5010
+ "sectionsAriaLabel": {
5011
+ "type": "string",
5093
5012
  "required": false
5094
5013
  },
5095
- "collapseNavigationLabel": {
5014
+ "sectionsJson": {
5096
5015
  "type": "string",
5097
5016
  "required": false
5098
5017
  },
5099
- "collapsed": {
5100
- "type": "boolean",
5018
+ "subsections": {
5019
+ "type": "TabItem[]",
5101
5020
  "required": false
5102
5021
  },
5103
- "currentUrl": {
5022
+ "subsectionsAriaLabel": {
5104
5023
  "type": "string",
5105
5024
  "required": false
5106
5025
  },
5107
- "dashboardLabel": {
5026
+ "subsectionsJson": {
5108
5027
  "type": "string",
5109
5028
  "required": false
5110
5029
  },
5111
- "dashboardNavigationLabel": {
5030
+ "subvalue": {
5112
5031
  "type": "string",
5113
5032
  "required": false
5114
5033
  },
5115
- "disableViewTransition": {
5116
- "type": "boolean",
5117
- "required": false
5118
- },
5119
- "expandNavigationLabel": {
5120
- "type": "string",
5121
- "required": false
5122
- },
5123
- "groups": {
5124
- "type": "string | PanelNavGroup[]",
5125
- "required": false
5126
- },
5127
- "navStyle": {
5128
- "type": "NavChromeStyle",
5129
- "required": false
5130
- },
5131
- "navigationItemsLabel": {
5132
- "type": "string",
5133
- "required": false
5134
- },
5135
- "routerMode": {
5136
- "type": "PanelNavRouterMode",
5137
- "required": false
5138
- },
5139
- "settingsLabel": {
5140
- "type": "string",
5141
- "required": false
5142
- },
5143
- "settingsNavigationLabel": {
5144
- "type": "string",
5145
- "required": false
5146
- },
5147
- "storageKey": {
5148
- "type": "string",
5149
- "required": false
5150
- },
5151
- "userInitial": {
5152
- "type": "string",
5034
+ "tone": {
5035
+ "type": "MobileHeaderTone",
5153
5036
  "required": false
5154
5037
  },
5155
- "userName": {
5038
+ "value": {
5156
5039
  "type": "string",
5157
5040
  "required": false
5158
5041
  }
5159
5042
  },
5160
5043
  "events": [
5161
5044
  {
5162
- "name": "dsChromeTransitionEnd",
5163
- "detail": "ChromeTransitionDetail"
5164
- },
5165
- {
5166
- "name": "dsChromeTransitionStart",
5167
- "detail": "ChromeTransitionDetail"
5168
- },
5169
- {
5170
- "name": "dsNavFooterAction",
5171
- "detail": "void"
5172
- },
5173
- {
5174
- "name": "dsNavSelect",
5045
+ "name": "dsSectionChange",
5175
5046
  "detail": "string"
5176
5047
  },
5177
5048
  {
5178
- "name": "dsNavToggle",
5179
- "detail": "boolean"
5180
- },
5181
- {
5182
- "name": "dsNavUserAction",
5183
- "detail": "PanelNavUserActionDetail"
5049
+ "name": "dsSubsectionChange",
5050
+ "detail": "string"
5184
5051
  }
5185
5052
  ],
5186
5053
  "slots": []
5187
5054
  },
5188
5055
  "exports": {
5189
- "customElement": "ds-panel-nav",
5190
- "react": "DsPanelNav",
5191
- "angular": "DsPanelNav"
5056
+ "customElement": "ds-mobile-header",
5057
+ "react": "DsMobileHeader",
5058
+ "angular": "DsMobileHeader"
5192
5059
  },
5193
5060
  "dependencies": [
5194
5061
  "@ds-mo/ui",
5195
- "@ds-mo/tokens",
5196
- "@ds-mo/icons"
5062
+ "@ds-mo/tokens"
5197
5063
  ],
5198
5064
  "componentDependencies": [
5199
- "badge",
5200
- "button-unfilled",
5201
- "icon",
5202
- "text",
5203
- "tooltip"
5065
+ "mobile-section-switcher",
5066
+ "text"
5204
5067
  ]
5205
5068
  },
5206
5069
  {
5207
- "id": "component:ds-panel-sub-nav",
5208
- "tag": "ds-panel-sub-nav",
5209
- "name": "panel-sub-nav",
5210
- "title": "PanelSubNav",
5211
- "summary": "Persistent vertical tab navigation for a panel or card side rail, switching adjacent local content with menu-like selected fill and stable text weight.",
5070
+ "id": "component:ds-mobile-section-switcher",
5071
+ "tag": "ds-mobile-section-switcher",
5072
+ "name": "mobile-section-switcher",
5073
+ "title": "MobileSectionSwitcher",
5074
+ "summary": "Controlled mobile section chooser showing the current section, adjacent-position hints, and a complete tap menu.",
5212
5075
  "intentStatus": "complete",
5213
5076
  "intent": {
5214
- "audience": "general",
5215
- "status": "stable",
5216
- "summary": "Persistent vertical tab navigation for a panel or card side rail, switching adjacent local content with menu-like selected fill and stable text weight.",
5077
+ "audience": "specialized",
5078
+ "status": "experimental",
5079
+ "summary": "Controlled mobile section chooser showing the current section, adjacent-position hints, and a complete tap menu.",
5217
5080
  "useWhen": [
5218
- "A panel or card side rail needs a persistent vertical list that switches adjacent local content.",
5219
- "Each concise text label controls an immediately available tabpanel without changing application routes."
5081
+ "A mobile page or tool header must combine current-page identity with ordered peer-section navigation."
5220
5082
  ],
5221
5083
  "avoidWhen": [
5222
- "The navigation is not contained in a panel or card side rail.",
5223
- "Local views should be arranged horizontally; use TabGroup instead.",
5224
- "The choices navigate routes in application shell chrome; use PanelNav or BarNav instead.",
5225
- "The choices are temporary commands or contextual options; use Menu instead.",
5226
- "Rows need icons, subtext, notification dots, nested levels, or section headers."
5227
- ],
5228
- "alternatives": [
5229
- {
5230
- "when": "Local panel choices fit a horizontal tab row.",
5231
- "component": "component:ds-tab-group",
5232
- "reason": "TabGroup is the horizontal local-view counterpart."
5233
- },
5234
- {
5235
- "when": "The choices are primary application destinations.",
5236
- "component": "component:ds-panel-nav",
5237
- "reason": "PanelNav owns primary application navigation."
5238
- },
5239
- {
5240
- "when": "The choices are secondary application routes.",
5241
- "component": "component:ds-bar-nav",
5242
- "reason": "BarNav owns route sections inside ShellApp."
5243
- },
5244
- {
5245
- "when": "The choices are transient actions or options.",
5246
- "component": "component:ds-menu",
5247
- "reason": "Menu owns temporary popup collections."
5248
- }
5084
+ "Rendering desktop BarNav.",
5085
+ "The destination collection is primary application navigation."
5249
5086
  ],
5250
5087
  "commonlyComposedWith": [
5251
- "component:ds-card-setting",
5252
- "component:ds-text"
5088
+ "component:ds-mobile-header"
5089
+ ],
5090
+ "patterns": [
5091
+ "pattern:application-shell"
5253
5092
  ],
5254
5093
  "accessibility": [
5255
- "Provide an accessible name with aria-label or aria-labelledby.",
5256
- "Give every item a unique id and the id of its controlled tabpanel.",
5257
- "Keep each controlled tabpanel labelled by its matching item id.",
5258
- "Always provide a valid selected item when enabled items exist so exactly one tab and panel are active.",
5259
- "ArrowUp and ArrowDown move and activate selection; Home and End select the first and last available items.",
5260
- "Do not use selected text weight as the selection cue; active fill and primary foreground communicate selection."
5094
+ "The trigger exposes the current section, popup relationship, and expanded state.",
5095
+ "Decorative previous and next position hints are hidden from assistive technology.",
5096
+ "The menu is always available so a future swipe gesture is never the only navigation mechanism.",
5097
+ "Peer destinations use menuitem semantics with aria-current on the active page; they do not present a radio-control affordance."
5261
5098
  ],
5262
5099
  "states": [
5263
- "The parent owns the canonical selected value and panel visibility, and should update both from dsChange.",
5264
- "A missing, empty, or unknown selected value is invalid when enabled items exist; the component does not choose a fallback selection.",
5265
- "Inactive items remain visible but cannot be focused or selected.",
5266
- "Selection is singular and follows keyboard focus.",
5267
- "The omitted default surface treatment is for primary and secondary parent surfaces and uses the brand-active selected fill; pass faint explicitly on faint surfaces to use the neutral active fill.",
5268
- "Rows contain one text label only and do not express nested navigation or grouped hierarchy."
5100
+ "Selection is controlled and dsChange reports intent without mutating value.",
5101
+ "Dividers group menu items but never participate in previous or next resolution.",
5102
+ "The first and last selectable sections expose only the available neighboring direction."
5269
5103
  ],
5270
5104
  "responsiveBehavior": [
5271
- "The component remains vertical at every width.",
5272
- "The consuming panel owns responsive adaptation and decides whether to reposition or replace the side rail."
5105
+ "Use only in the dedicated mobile header presentation."
5273
5106
  ],
5274
- "frameworkCaveats": {
5275
- "customElements": [
5276
- "Assign items as a JavaScript property because structured arrays are not represented by HTML attributes.",
5277
- "Keep value synchronized to a valid enabled item and update the controlled panel from dsChange."
5278
- ],
5279
- "react": [
5280
- "Pass items as an array through the generated wrapper, keep value controlled, and use onDsChange to synchronize the visible panel."
5281
- ],
5282
- "angular": [
5283
- "Bind items and a valid value as properties, and handle dsChange to synchronize the visible panel."
5284
- ]
5285
- }
5107
+ "references": [
5108
+ {
5109
+ "label": "Storybook",
5110
+ "path": "src/wc/components/MobileSectionSwitcher/MobileSectionSwitcher.stories.ts"
5111
+ }
5112
+ ]
5286
5113
  },
5287
5114
  "api": {
5288
5115
  "props": {
5289
- "ariaLabel": {
5290
- "type": "string | null",
5291
- "required": false
5292
- },
5293
- "ariaLabelledby": {
5294
- "type": "string | undefined",
5116
+ "navigationLabel": {
5117
+ "type": "string",
5295
5118
  "required": false
5296
5119
  },
5297
- "background": {
5298
- "type": "PanelSubNavBackground | undefined",
5120
+ "sections": {
5121
+ "type": "TabItem[]",
5299
5122
  "required": false
5300
5123
  },
5301
- "items": {
5302
- "type": "PanelSubNavItem[]",
5124
+ "sectionsJson": {
5125
+ "type": "string",
5303
5126
  "required": false
5304
5127
  },
5305
5128
  "value": {
@@ -5316,387 +5139,390 @@
5316
5139
  "slots": []
5317
5140
  },
5318
5141
  "exports": {
5319
- "customElement": "ds-panel-sub-nav",
5320
- "react": "DsPanelSubNav",
5321
- "angular": "DsPanelSubNav"
5142
+ "customElement": "ds-mobile-section-switcher",
5143
+ "react": "DsMobileSectionSwitcher",
5144
+ "angular": "DsMobileSectionSwitcher"
5322
5145
  },
5323
5146
  "dependencies": [
5324
5147
  "@ds-mo/ui",
5325
5148
  "@ds-mo/tokens"
5326
5149
  ],
5327
5150
  "componentDependencies": [
5151
+ "menu",
5328
5152
  "text"
5329
5153
  ]
5330
5154
  },
5331
5155
  {
5332
- "id": "component:ds-panel-tool-header",
5333
- "tag": "ds-panel-tool-header",
5334
- "name": "panel-tool-header",
5335
- "title": "PanelToolHeader",
5336
- "summary": "Canonical left-aligned PanelTools header with an optional leading navigation or dismiss action and application-owned trailing icon actions.",
5156
+ "id": "component:ds-mobile-sheet-nav",
5157
+ "tag": "ds-mobile-sheet-nav",
5158
+ "name": "mobile-sheet-nav",
5159
+ "title": "MobileSheetNav",
5160
+ "summary": "Full-height mobile navigation sheet with a single brand, context, and utility header above large primary destinations.",
5337
5161
  "intentStatus": "complete",
5338
5162
  "intent": {
5339
- "audience": "general",
5163
+ "audience": "specialized",
5340
5164
  "status": "experimental",
5341
- "summary": "Canonical left-aligned PanelTools header with an optional leading navigation or dismiss action and application-owned trailing icon actions.",
5165
+ "summary": "Full-height mobile navigation sheet with a single brand, context, and utility header above large primary destinations.",
5342
5166
  "useWhen": [
5343
- "PanelTools needs its one shared root or detail header.",
5344
- "A tool header needs a title with optional Back or Close navigation, menu, fullscreen, or other compact icon actions."
5167
+ "The mobile ShellApp Menu control needs to expose the complete primary navigation collection."
5345
5168
  ],
5346
5169
  "avoidWhen": [
5347
- "Rendering inside a PanelTools tool body; PanelTools already composes this canonical header above the body.",
5348
- "The header belongs to page content."
5170
+ "Rendering desktop PanelNav.",
5171
+ "Switching local page content."
5349
5172
  ],
5350
5173
  "commonlyComposedWith": [
5351
- "component:ds-button-unfilled"
5174
+ "component:ds-shell-app",
5175
+ "component:ds-mobile-bar-nav"
5176
+ ],
5177
+ "patterns": [
5178
+ "pattern:application-shell"
5352
5179
  ],
5353
5180
  "accessibility": [
5354
- "Leading navigation or dismiss actions and trailing icon actions require concise localized names; the header reuses each name as the action tooltip.",
5355
- "The visible heading names the active panel or subview."
5181
+ "The sheet is a named navigation landmark and retains visible labels for every primary destination.",
5182
+ "Dashboard and Settings use icon-only tabs with localized accessible names; Help and Account use icon-only actions with matching tooltips.",
5183
+ "Escape requests dismissal and opening moves focus to the selected or first available area."
5356
5184
  ],
5357
5185
  "states": [
5358
- "The title remains left aligned whether the header has no actions, Back, one trailing action, or several trailing actions.",
5359
- "Leading and trailing control zones never shrink; only the title consumes and truncates within the remaining width, with a fixed 4px gap between zones.",
5360
- "Header chrome text is not selectable; actions remain keyboard focusable and interactive.",
5361
- "Adjacent trailing actions keep the shared 4px control gap in drawer and fullscreen presentations.",
5362
- "When fullscreen and overflow actions appear together, author fullscreen before overflow so Ellipses remains the rightmost action.",
5363
- "PanelTools supplies application-owned actions and relays their ids through its shared dsHeaderAction event."
5186
+ "Dashboard and Settings change only the flat destination collection being browsed.",
5187
+ "Area, Help, and Account events express intent while the application owns navigation and product behavior."
5364
5188
  ],
5365
5189
  "responsiveBehavior": [
5366
- "The title truncates between optional leading navigation and trailing action zones."
5190
+ "The pane fills the mobile content stage while the bottom bar remains available."
5367
5191
  ],
5368
5192
  "references": [
5369
5193
  {
5370
- "label": "Standalone examples",
5371
- "path": "src/wc/components/PanelToolHeader/PanelToolHeader.stories.ts"
5194
+ "label": "Storybook",
5195
+ "path": "src/wc/components/MobileSheetNav/MobileSheetNav.stories.ts"
5372
5196
  }
5373
5197
  ]
5374
5198
  },
5375
5199
  "api": {
5376
5200
  "props": {
5377
- "actions": {
5378
- "type": "PanelToolsHeaderAction[]",
5379
- "required": false
5380
- },
5381
- "backAriaLabel": {
5201
+ "accountLabel": {
5382
5202
  "type": "string",
5383
5203
  "required": false
5384
5204
  },
5385
- "backIcon": {
5386
- "type": "string",
5205
+ "browseContext": {
5206
+ "type": "NavChromeStyle",
5387
5207
  "required": false
5388
5208
  },
5389
- "heading": {
5209
+ "currentUrl": {
5390
5210
  "type": "string",
5391
5211
  "required": false
5392
5212
  },
5393
- "menuAriaLabel": {
5394
- "type": "string",
5213
+ "dashboardGroups": {
5214
+ "type": "PanelNavGroup[]",
5395
5215
  "required": false
5396
5216
  },
5397
- "menuControls": {
5398
- "type": "string | undefined",
5217
+ "dashboardLabel": {
5218
+ "type": "string",
5399
5219
  "required": false
5400
5220
  },
5401
- "menuExpanded": {
5402
- "type": "boolean",
5221
+ "helpLabel": {
5222
+ "type": "string",
5403
5223
  "required": false
5404
5224
  },
5405
- "menuTriggerId": {
5225
+ "navigationLabel": {
5406
5226
  "type": "string",
5407
5227
  "required": false
5408
5228
  },
5409
- "showBack": {
5229
+ "open": {
5410
5230
  "type": "boolean",
5411
5231
  "required": false
5412
5232
  },
5413
- "showMenu": {
5414
- "type": "boolean",
5233
+ "settingsGroups": {
5234
+ "type": "PanelNavGroup[]",
5235
+ "required": false
5236
+ },
5237
+ "settingsLabel": {
5238
+ "type": "string",
5415
5239
  "required": false
5416
5240
  }
5417
5241
  },
5418
5242
  "events": [
5419
5243
  {
5420
- "name": "dsAction",
5421
- "detail": "{ id: string; originalEvent: MouseEvent }"
5244
+ "name": "dsAreaSelect",
5245
+ "detail": "string"
5422
5246
  },
5423
5247
  {
5424
- "name": "dsBack",
5425
- "detail": "MouseEvent"
5248
+ "name": "dsBrowseContextChange",
5249
+ "detail": "NavChromeStyle"
5426
5250
  },
5427
5251
  {
5428
- "name": "dsMenuToggle",
5429
- "detail": "MouseEvent"
5252
+ "name": "dsClose",
5253
+ "detail": "void"
5430
5254
  }
5431
5255
  ],
5432
5256
  "slots": []
5433
5257
  },
5434
5258
  "exports": {
5435
- "customElement": "ds-panel-tool-header",
5436
- "react": "DsPanelToolHeader",
5437
- "angular": "DsPanelToolHeader"
5259
+ "customElement": "ds-mobile-sheet-nav",
5260
+ "react": "DsMobileSheetNav",
5261
+ "angular": "DsMobileSheetNav"
5438
5262
  },
5439
5263
  "dependencies": [
5440
5264
  "@ds-mo/ui",
5441
- "@ds-mo/tokens"
5265
+ "@ds-mo/tokens",
5266
+ "@ds-mo/icons"
5442
5267
  ],
5443
5268
  "componentDependencies": [
5269
+ "badge",
5444
5270
  "button-unfilled",
5271
+ "icon",
5272
+ "tab-group",
5445
5273
  "text",
5446
5274
  "tooltip"
5447
5275
  ]
5448
5276
  },
5449
5277
  {
5450
- "id": "component:ds-panel-tool-search",
5451
- "tag": "ds-panel-tool-search",
5452
- "name": "panel-tool-search",
5453
- "title": "PanelToolSearch",
5454
- "summary": "Transparent search row for the top of a PanelTools product view, with a fixed 48px allocation around the standard md search control and an optional filter-menu trigger.",
5278
+ "id": "component:ds-modal",
5279
+ "tag": "ds-modal",
5280
+ "name": "modal",
5281
+ "title": "Modal",
5282
+ "summary": "Dismissible native top-layer dialog for a focused confirmation or short blocking task, with a fixed title-and-close header, composable content, and an optional two-action footer.",
5455
5283
  "intentStatus": "complete",
5456
5284
  "intent": {
5457
5285
  "audience": "general",
5458
- "status": "experimental",
5459
- "summary": "Transparent search row for the top of a PanelTools product view, with a fixed 48px allocation around the standard md search control and an optional filter-menu trigger.",
5286
+ "status": "stable",
5287
+ "summary": "Dismissible native top-layer dialog for a focused confirmation or short blocking task, with a fixed title-and-close header, composable content, and an optional two-action footer.",
5460
5288
  "useWhen": [
5461
- "A PanelTools base view filters or searches the tool's own content.",
5462
- "Several tool products need the same search-row geometry directly below the shared PanelTools header.",
5463
- "The product needs a compact filter menu next to search while keeping its filter choices and matching policy application-owned."
5289
+ "The user must confirm or cancel one focused decision before returning to the underlying interface.",
5290
+ "A short blocking task or compact form needs dialog semantics, focus containment, and explicit completion actions.",
5291
+ "The content can be safely dismissed through Close, Escape, or the backdrop."
5464
5292
  ],
5465
5293
  "avoidWhen": [
5466
- "The search belongs inside a Select or SelectMulti popup; use that component's searchable behavior.",
5467
- "A form needs a labelled standalone field; compose ds-input inside ds-field instead."
5294
+ "The message is non-blocking feedback or a transient status update.",
5295
+ "The interaction is a contextual list of commands anchored to a trigger.",
5296
+ "The workflow is multi-step, long-form, or requires substantial navigation.",
5297
+ "Dismissal would lose work or leave an irreversible operation in an unsafe state.",
5298
+ "A second modal would be opened over an existing modal."
5299
+ ],
5300
+ "alternatives": [
5301
+ {
5302
+ "when": "The user needs non-blocking feedback or a transient status message.",
5303
+ "component": "component:ds-toast",
5304
+ "reason": "Toast communicates transient status without trapping focus or blocking the page."
5305
+ },
5306
+ {
5307
+ "when": "A trigger reveals a short contextual list of commands.",
5308
+ "component": "component:ds-menu",
5309
+ "reason": "Menu provides anchored command semantics without creating a blocking dialog."
5310
+ },
5311
+ {
5312
+ "when": "Editable settings should remain visible without blocking the rest of the interface.",
5313
+ "component": "component:ds-card-setting",
5314
+ "reason": "CardSetting provides a persistent controlled settings workflow without modal focus containment."
5315
+ }
5468
5316
  ],
5469
5317
  "commonlyComposedWith": [
5470
- "component:ds-panel-tools",
5471
- "component:ds-conversation-list",
5472
- "component:ds-input"
5318
+ "component:ds-button-filled",
5319
+ "component:ds-button-unfilled",
5320
+ "component:ds-field",
5321
+ "component:ds-text"
5473
5322
  ],
5474
5323
  "accessibility": [
5475
- "Provide an aria-label that names the searched domain, such as Search agent chats or Search messages.",
5476
- "The standard search clear action restores focus, uses the concise localized clearLabel by itself for both its tooltip and accessible name, and emits both the empty query and dsClear.",
5477
- "When showFilter is enabled, provide stable filterTriggerId and filterControls values, synchronize filterExpanded with the controlled menu, and restore focus after selection; filterAriaLabel also labels its tooltip."
5324
+ "Provide a concise visible heading; the component uses it as the dialog's accessible name.",
5325
+ "Give the primary explanatory copy a stable id and pass it through aria-describedby so assistive technology receives the decision context.",
5326
+ "Opening the native modal dialog moves focus to the header Close action, whose visible tooltip matches its accessible name, traps Tab navigation inside the top layer, and makes outside content inert.",
5327
+ "Close, Escape, and backdrop activation emit dsClose with close-button, escape, or backdrop reason before beginning dismissal; use the component only when every dismissal path is safe.",
5328
+ "After exit motion completes, the native dialog leaves the top layer, focus returns to the previously focused element, and dsAfterClose emits.",
5329
+ "Use visible label-only footer buttons. Keep at most two actions: one bold filled primary action followed by one bordered unfilled action, or two bordered unfilled actions.",
5330
+ "Use negative intent for a filled destructive action and state the irreversible consequence in the content.",
5331
+ "Do not open a modal from another modal; keep one blocking decision in focus at a time."
5478
5332
  ],
5479
5333
  "states": [
5480
- "The row is always 48px high with 8px outer padding and a complete md search recipe: 32px control, text-body-medium at 14px/20px, and a 20px md search icon.",
5481
- "The search icon stays foreground-secondary at rest, hover, focus, active, and while the query is filled.",
5482
- "The row and control surface remain transparent so the ShellApp chrome wash is visible behind them.",
5483
- "The row divider remains the same tertiary 1px boundary while the input is focused because it belongs to the 48px container rather than the input control.",
5484
- "With filtering enabled, the md search control, decorative vertical divider, and borderless md Filter action are separated by 8px; filterActive promotes only the trigger foreground without adding a selected fill."
5334
+ "The owner opens the modal through the open property and responds to the typed dsClose detail for application state synchronization or dismissal analytics.",
5335
+ "The component mutates open to false for Close, Escape, and backdrop dismissal while retaining its rendered surface through exit motion.",
5336
+ "The default slot owns task content; the named footer slot is optional and is hidden when no actions are assigned.",
5337
+ "Primary actions use a bold filled button with semantic intent. Secondary and cancel actions use bordered label-only unfilled buttons.",
5338
+ "The owner performs save, delete, cancel, and other product consequences before or while closing the modal."
5485
5339
  ],
5486
5340
  "responsiveBehavior": [
5487
- "The row fills the available drawer or fullscreen width, allows its search region to shrink inside a 300px drawer without pushing the filter trigger under the tool rail, and does not reduce its control below md density."
5341
+ "Choose the smallest sm, md, or lg width that fits the focused task; the top-layer dialog clamps to the viewport with token-based outer space.",
5342
+ "Content scrolls independently when needed while the 64px header and optional 64px footer remain fixed.",
5343
+ "Avoid layouts whose minimum content width exceeds the narrow viewport clamp.",
5344
+ "The native top layer escapes transformed ancestors, clipping containers, and application stacking contexts without moving slotted content."
5488
5345
  ],
5489
5346
  "frameworkCaveats": {
5490
5347
  "customElements": [
5491
- "Listen for dsChange to receive the current string query and dsClear when the clear action is used.",
5492
- "Listen for dsFilterToggle and pair the trigger with an externally controlled ds-menu; product-specific filter labels and filtering remain outside this component."
5348
+ "Set open as a JavaScript property when controlling the modal; inspect dsClose.detail.reason and use dsAfterClose for cleanup that must wait for exit motion and focus restoration.",
5349
+ "Connect the most relevant slotted explanatory text through aria-describedby.",
5350
+ "Footer actions are slotted application-owned controls and must implement their own product consequence."
5493
5351
  ],
5494
5352
  "react": [
5495
- "Use DsPanelToolSearch, bind value for controlled state, and handle onDsChange.",
5496
- "Bind the optional filter trigger state and connect onDsFilterToggle to a controlled DsMenu."
5353
+ "Pass open to DsModal, inspect onDsClose event detail, and use onDsAfterClose only for cleanup after exit motion and focus restoration.",
5354
+ "Connect the most relevant slotted explanatory text through aria-describedby.",
5355
+ "Assign footer controls with slot=\"footer\" and handle each action before updating open."
5497
5356
  ],
5498
5357
  "angular": [
5499
- "Import DsPanelToolSearch and bind value as a property; this search composition is not a form value accessor.",
5500
- "Bind showFilter, filterExpanded, and filterActive, then connect dsFilterToggle to a product-owned ds-menu."
5358
+ "Bind [open], inspect $event.detail from (dsClose), and use (dsAfterClose) only for cleanup after exit motion and focus restoration.",
5359
+ "Connect the most relevant slotted explanatory text through aria-describedby.",
5360
+ "Assign footer controls with slot=\"footer\" and handle each action before updating open."
5501
5361
  ]
5502
5362
  },
5503
5363
  "references": [
5504
5364
  {
5505
- "label": "Storybook examples",
5506
- "path": "src/wc/components/PanelToolSearch/PanelToolSearch.stories.ts"
5365
+ "label": "Storybook confirmation and footer examples",
5366
+ "path": "src/wc/components/Modal/Modal.stories.ts"
5367
+ },
5368
+ {
5369
+ "label": "Cross-browser focus, dismissal, geometry, and accessibility coverage",
5370
+ "path": "tests/e2e/accessibility-overlays.spec.ts"
5371
+ },
5372
+ {
5373
+ "label": "Reduced-motion overlay coverage",
5374
+ "path": "tests/e2e/reduced-motion.spec.ts"
5507
5375
  }
5508
5376
  ]
5509
5377
  },
5510
5378
  "api": {
5511
5379
  "props": {
5512
- "ariaLabel": {
5513
- "type": "string",
5514
- "required": false
5515
- },
5516
- "controls": {
5380
+ "ariaDescribedby": {
5517
5381
  "type": "string | undefined",
5518
5382
  "required": false
5519
5383
  },
5520
- "filterActive": {
5521
- "type": "boolean",
5522
- "required": false
5523
- },
5524
- "filterAriaLabel": {
5384
+ "closeAriaLabel": {
5525
5385
  "type": "string",
5526
5386
  "required": false
5527
5387
  },
5528
- "filterControls": {
5529
- "type": "string | undefined",
5530
- "required": false
5531
- },
5532
- "filterExpanded": {
5533
- "type": "boolean",
5534
- "required": false
5535
- },
5536
- "filterTriggerId": {
5388
+ "heading": {
5537
5389
  "type": "string",
5538
- "required": false
5539
- },
5540
- "isInactive": {
5541
- "type": "boolean",
5542
- "required": false
5390
+ "required": true
5543
5391
  },
5544
- "placeholder": {
5545
- "type": "string",
5392
+ "modalWidth": {
5393
+ "type": "ModalWidth | string",
5546
5394
  "required": false
5547
5395
  },
5548
- "showFilter": {
5396
+ "open": {
5549
5397
  "type": "boolean",
5550
5398
  "required": false
5551
- },
5552
- "value": {
5553
- "type": "string",
5554
- "required": false
5555
5399
  }
5556
5400
  },
5557
5401
  "events": [
5558
5402
  {
5559
- "name": "dsChange",
5560
- "detail": "string"
5561
- },
5562
- {
5563
- "name": "dsClear",
5403
+ "name": "dsAfterClose",
5564
5404
  "detail": "void"
5565
5405
  },
5566
5406
  {
5567
- "name": "dsFilterToggle",
5568
- "detail": "MouseEvent"
5407
+ "name": "dsClose",
5408
+ "detail": "ModalCloseDetail"
5569
5409
  }
5570
5410
  ],
5571
5411
  "slots": []
5572
5412
  },
5573
5413
  "exports": {
5574
- "customElement": "ds-panel-tool-search",
5575
- "react": "DsPanelToolSearch",
5576
- "angular": "DsPanelToolSearch"
5414
+ "customElement": "ds-modal",
5415
+ "react": "DsModal",
5416
+ "angular": "DsModal"
5577
5417
  },
5578
5418
  "dependencies": [
5579
5419
  "@ds-mo/ui",
5580
- "@ds-mo/tokens",
5581
- "@ds-mo/icons"
5420
+ "@ds-mo/tokens"
5582
5421
  ],
5583
5422
  "componentDependencies": [
5584
5423
  "button-unfilled",
5585
- "divider",
5586
- "icon",
5587
5424
  "text",
5588
5425
  "tooltip"
5589
5426
  ]
5590
5427
  },
5591
5428
  {
5592
- "id": "component:ds-panel-tools",
5593
- "tag": "ds-panel-tools",
5594
- "name": "panel-tools",
5595
- "title": "PanelTools",
5596
- "summary": "Required ShellApp utility rail and persistent drawer host for the fixed set of global Search, Agents, Messages, Stacks, Activity, and Help products.",
5429
+ "id": "component:ds-panel-nav",
5430
+ "tag": "ds-panel-nav",
5431
+ "name": "panel-nav",
5432
+ "title": "PanelNav",
5433
+ "summary": "The single persistent primary navigation for an application, providing grouped top-level destinations, active-route state, standard dashboard/settings switching, user access, and collapsible desktop and tablet presentation.",
5597
5434
  "intentStatus": "complete",
5598
5435
  "intent": {
5599
5436
  "audience": "specialized",
5600
5437
  "status": "stable",
5601
- "summary": "Required ShellApp utility rail and persistent drawer host for the fixed set of global Search, Agents, Messages, Stacks, Activity, and Help products.",
5438
+ "summary": "The single persistent primary navigation for an application, providing grouped top-level destinations, active-route state, standard dashboard/settings switching, user access, and collapsible desktop and tablet presentation.",
5602
5439
  "useWhen": [
5603
- "Composing the required global tools region inside the application's single ShellApp.",
5604
- "Users need to move between application-wide utilities without losing each tool's in-progress state.",
5605
- "Search, AI conversations, user messages, review stacks, notifications, or help content must remain available alongside route content."
5440
+ "Building the one primary navigation surface for an application that uses the CompoMo system.",
5441
+ "Top-level destinations must remain consistently available while the application's page content changes.",
5442
+ "Primary destinations need visual grouping, icons, notification indicators, active-route state, and expanded or collapsed presentation."
5606
5443
  ],
5607
5444
  "avoidWhen": [
5608
- "The action is specific to the current page or selected content rather than globally available across the application.",
5609
- "The item navigates to a primary or secondary route; use PanelNav or BarNav instead.",
5610
- "A consumer wants to add arbitrary tools, reorder fixed tools, or repurpose a semantic tool id.",
5611
- "Building the mobile tools experience; future mobile ShellApp composition uses a different bottom-bar and panel pattern.",
5612
- "PanelTools would be mounted outside the application's single ShellApp."
5445
+ "A second navigation surface is needed within the same application; an application must have only one PanelNav.",
5446
+ "The choices represent sections within the active primary destination; use BarNav instead.",
5447
+ "The choices switch local content without changing the application's primary destination; use TabGroup instead.",
5448
+ "The interaction performs a command or presents temporary contextual choices; use a button or Menu instead.",
5449
+ "Building navigation below the mobile breakpoint; use the application's dedicated mobile navigation component instead."
5613
5450
  ],
5614
5451
  "alternatives": [
5615
5452
  {
5616
- "when": "The action navigates to a top-level application destination.",
5617
- "component": "component:ds-panel-nav",
5618
- "reason": "PanelNav exclusively owns primary application navigation."
5453
+ "when": "The choices represent route sections within the active primary destination.",
5454
+ "component": "component:ds-bar-nav",
5455
+ "reason": "BarNav owns secondary section navigation within the destination selected by PanelNav."
5619
5456
  },
5620
5457
  {
5621
- "when": "The action navigates between route sections of the active destination.",
5622
- "component": "component:ds-bar-nav",
5623
- "reason": "BarNav exclusively owns secondary route navigation."
5458
+ "when": "The choices switch local content without changing the application's primary destination.",
5459
+ "component": "component:ds-tab-group",
5460
+ "reason": "TabGroup owns local view selection and tab semantics."
5624
5461
  },
5625
5462
  {
5626
- "when": "Temporary contextual actions or options are needed.",
5463
+ "when": "The choices are commands or temporary contextual actions.",
5627
5464
  "component": "component:ds-menu",
5628
- "reason": "Menu owns transient contextual choices rather than persistent global products."
5465
+ "reason": "Menu owns transient action and option collections rather than persistent destinations."
5629
5466
  }
5630
5467
  ],
5631
5468
  "commonlyComposedWith": [
5632
5469
  "component:ds-shell-app",
5633
- "component:ds-panel-nav",
5634
- "component:ds-bar-nav"
5470
+ "component:ds-bar-nav",
5471
+ "component:ds-panel-tools",
5472
+ "component:ds-menu"
5635
5473
  ],
5636
5474
  "patterns": [
5637
5475
  "pattern:application-shell"
5638
5476
  ],
5639
5477
  "accessibility": [
5640
- "Provide localized accessible labels for the rail, shortcut group, and every rendered tool.",
5641
- "Keep Search first in the rail header and Help last in the rail footer so keyboard and visual order remain predictable.",
5642
- "Keep focus on the selected rail action when opening a drawer and allow normal Tab navigation into its content.",
5643
- "Do not trigger global shortcuts while focus is in an editable control.",
5644
- "Use notification dots only as supplemental unread or new-content status and never as the sole status indication.",
5645
- "Explain temporarily inactive tools through an accessible label or adjacent product guidance; omit unauthorized tools entirely."
5478
+ "Give every primary destination a concise visible label and an icon that supports rather than replaces that label.",
5479
+ "Provide localized dashboard, settings, account, navigation, collapse, and expand labels.",
5480
+ "Preserve accessible destination names when the panel is collapsed to icon-only presentation.",
5481
+ "Use notification dots as supplemental status and never as the only indication of important information.",
5482
+ "When the destination body overflows, it becomes a localized keyboard-focusable scroll region in addition to the roving destination controls.",
5483
+ "Keep the standard dashboard/settings switch and user/account entry available in the footer."
5646
5484
  ],
5647
5485
  "states": [
5648
- "Search and Help are required; optional Agents, Messages, Stacks, and Activity tools are filtered by the application for authorization and entitlement.",
5649
- "Use only the fixed semantic tool ids and canonical order: Search, Agents, Messages, Stacks, Activity, Help; do not reorder, duplicate, or repurpose them.",
5650
- "Search is application-wide; Agents is user-to-AI chat; Messages is user-to-user chat; Stacks is a specialized inbox of grouped application events for review; Activity is the notification center; Help is drawer content that may link to external resources.",
5651
- "Only one drawer is open at a time; selecting another tool switches directly and selecting the active tool closes to rail-only mode.",
5652
- "The drawer starts closed, remains open across ordinary route changes, and retains every mounted tool's independent conversation, query, scroll, and work state.",
5653
- "When storageKey is set, persist only the last active tool in this browser and still restore the drawer closed after reload.",
5654
- "The application owns unread state; opening Messages, Agents, Stacks, or Activity does not automatically clear its notification dot.",
5655
- "PanelTools owns the one visible header above every drawer tool view and above fullscreen views using the default shared header mode. Slotted tool content must not render a second header unless the conversation product explicitly opts into split fullscreen headers.",
5656
- "PanelTools composes ds-panel-tool-header as its canonical left-aligned header implementation so standalone header stories and shell rendering cannot diverge.",
5657
- "Each tool supplies its current header title, base-versus-detail Back state, and right-side actions through the headers property. Base views omit Back; deeper views expose Back and update the same header in place.",
5658
- "Header Back and action events express intent only; the owning tool changes product navigation, menus, and data state. PanelTools keeps the final header action exactly 8px from the drawer edge.",
5659
- "Menus opened from a right-side header action use PANEL_TOOLS_HEADER_MENU_PLACEMENT: bottom/end choice-cell alignment and a 12px side offset, placing the popup 4px below the 48px header while aligning the final menu item edge with the trigger.",
5660
- "Tool view roots stay transparent so ShellApp's chrome wash remains visible; only explicitly designed child surfaces introduce a fill.",
5661
- "Tools with search compose ds-panel-tool-search immediately below the shared header. Its 48px row always contains the md search control and must not be reduced to sm or xs.",
5662
- "If an active optional tool becomes unavailable, PanelTools closes the drawer, clears activeTool, and emits its deselection.",
5663
- "Use isInactive only for a temporarily unavailable visible tool; omit tools the user is not authorized to access.",
5664
- "The application owns slotted tool products and data while PanelTools owns rail ordering, drawer selection, open state, motion, and shell events.",
5665
- "Opening and closing clip an already-rendered fixed-width surface. Header and tool content remain fully opaque and retained during width motion; transition completion is accepted only at the measured terminal clip width, after which the closed surface becomes inert and paint-skipped.",
5666
- "Entering and exiting fullscreen snaps without borrowing the drawer open or close animation.",
5667
- "When fullscreenHeaderMode is split, PanelTools suppresses only its fullscreen shared header. The application renders exactly two canonical ds-panel-tool-header instances: a tool-title/list-actions header over the 300px history pane and a chat-title/Exit-fullscreen/chat-actions header over the detail pane. The detail header omits Back because the list remains visible."
5486
+ "Render exactly one PanelNav per application; it owns primary application destinations and no other navigation role.",
5487
+ "The host router owns the current route; prefer currentUrl for active destination matching and use activeId only when route matching is unavailable.",
5488
+ "Use anchor mode for native links or routers that intercept anchors; use event mode when the host performs navigation from dsNavSelect.",
5489
+ "Groups visually organize top-level destinations only and must not be interpreted as nested or expandable navigation.",
5490
+ "Dashboard presents day-to-day operational destinations; Settings presents administrative and configuration destinations.",
5491
+ "The standard footer switches the entire destination collection and navStyle between Dashboard and Settings and exposes the user/account entry.",
5492
+ "The host owns the external user menu opened from dsNavUserAction.",
5493
+ "Item and header controls inherit the shared md control radius while local shell geometry continues to own collapsed layout and footer animation positioning.",
5494
+ "On desktop, allow user-controlled expand and collapse and persist the preference with storageKey when cross-session persistence is appropriate."
5668
5495
  ],
5669
5496
  "responsiveBehavior": [
5670
- "The open drawer reduces main-content width and uses --dimension-panel-width-xs (300px) on every supported desktop and tablet viewport.",
5671
- "ShellApp owns the fixed drawer-width variable; consumers must not hardcode alternate drawer widths.",
5672
- "Below 768px, do not reuse desktop PanelTools: future ShellApp mobile composition uses a bottom bar for Search, Agents, Notifications, and Stacks, while Help moves into mobile primary navigation.",
5673
- "Keep named-slot content mounted while tools switch or the drawer closes so users can return to in-progress global work.",
5674
- "Conversation products may use fullscreenHeaderMode split for a 300px history rail beside a flexible detail pane, each with its own canonical header; the application owns that internal split layout.",
5675
- "Use fixed drawer widths for now; do not add user resizing or width persistence."
5497
+ "At 1200px and wider, default to expanded, allow the user to expand or collapse, and restore the locally persisted desktop preference when available.",
5498
+ "From 768px through 1199px, present PanelNav permanently collapsed and do not allow user expansion.",
5499
+ "Below 768px, the consuming application replaces PanelNav with a dedicated mobile navigation component; PanelNav does not own mobile navigation.",
5500
+ "ShellApp permanently owns responsive composition: it determines shell mode, enforces tablet collapse, and replaces PanelNav with future mobile navigation below 768px.",
5501
+ "When the viewport is below breakpoint, PanelNav locks collapsed, disables its header toggle affordance, and preserves the persisted desktop collapse preference.",
5502
+ "Collapsed presentation must preserve destination ordering, active state, notification status, and accessible names."
5676
5503
  ],
5677
5504
  "frameworkCaveats": {
5678
5505
  "customElements": [
5679
- "Assign items as a JavaScript property for structured data; items-json is the string fallback.",
5680
- "Assign headers as a JavaScript property and replace its object identity whenever an active tool changes title, depth, or actions.",
5681
- "Keep PanelTools mounted at ShellApp scope across route changes and provide each product through its matching named slot."
5506
+ "Assign groups as a JavaScript property for structured data; a JSON string attribute is also supported.",
5507
+ "Set nav-style before the element connects when first-paint style must match the current route."
5682
5508
  ],
5683
5509
  "react": [
5684
- "Pass the fixed item collection through the generated React wrapper and keep named-slot product content mounted at ShellApp scope.",
5685
- "Use storageKey only for same-browser last-tool continuity; do not persist the open drawer."
5510
+ "Pass groups as an array through the generated React wrapper and synchronize currentUrl with the host router.",
5511
+ "ShellApp owns mobile replacement; PanelNav enforces its configured breakpoint expansion lock."
5686
5512
  ],
5687
5513
  "angular": [
5688
- "Import DsPanelTools from @ds-mo/ui/angular/ds-panel-tools and bind items as a property.",
5689
- "Bind headers as a replaced object and route dsHeaderBack and dsHeaderAction to the active tool owner.",
5690
- "Keep the component in the persistent shell layout rather than recreating it in routed page components."
5514
+ "Import DsPanelNav from @ds-mo/ui/angular/ds-panel-nav and bind groups as a property.",
5515
+ "Bind both the nav-style attribute and navStyle property when first-paint route styling must be deterministic.",
5516
+ "ShellApp owns mobile replacement; PanelNav enforces its configured breakpoint expansion lock."
5691
5517
  ]
5692
5518
  },
5693
5519
  "references": [
5694
5520
  {
5695
5521
  "label": "Executable Storybook examples",
5696
- "path": "src/wc/components/PanelTools/PanelTools.stories.ts"
5522
+ "path": "src/wc/components/PanelNav/PanelNav.stories.ts"
5697
5523
  },
5698
5524
  {
5699
- "label": "Framework and shell integration",
5525
+ "label": "Framework and routing integration",
5700
5526
  "path": "docs/framework-integration.md"
5701
5527
  },
5702
5528
  {
@@ -5707,47 +5533,83 @@
5707
5533
  },
5708
5534
  "api": {
5709
5535
  "props": {
5710
- "activeTool": {
5711
- "type": "PanelToolsToolId | ''",
5536
+ "accountLabel": {
5537
+ "type": "string",
5712
5538
  "required": false
5713
5539
  },
5714
- "fullscreenHeaderMode": {
5715
- "type": "'shared' | 'split'",
5540
+ "accountMenuExpanded": {
5541
+ "type": "boolean",
5716
5542
  "required": false
5717
5543
  },
5718
- "headers": {
5719
- "type": "PanelToolsHeaders",
5544
+ "activeId": {
5545
+ "type": "string",
5720
5546
  "required": false
5721
5547
  },
5722
- "headersJson": {
5548
+ "breakpoint": {
5549
+ "type": "number",
5550
+ "required": false
5551
+ },
5552
+ "collapseNavigationLabel": {
5723
5553
  "type": "string",
5724
5554
  "required": false
5725
5555
  },
5726
- "items": {
5727
- "type": "PanelToolsItem[]",
5556
+ "collapsed": {
5557
+ "type": "boolean",
5728
5558
  "required": false
5729
5559
  },
5730
- "itemsJson": {
5560
+ "currentUrl": {
5731
5561
  "type": "string",
5732
5562
  "required": false
5733
5563
  },
5734
- "open": {
5564
+ "dashboardLabel": {
5565
+ "type": "string",
5566
+ "required": false
5567
+ },
5568
+ "dashboardNavigationLabel": {
5569
+ "type": "string",
5570
+ "required": false
5571
+ },
5572
+ "disableViewTransition": {
5735
5573
  "type": "boolean",
5736
5574
  "required": false
5737
5575
  },
5738
- "presentation": {
5739
- "type": "'drawer' | 'fullscreen'",
5576
+ "expandNavigationLabel": {
5577
+ "type": "string",
5578
+ "required": false
5579
+ },
5580
+ "groups": {
5581
+ "type": "string | PanelNavGroup[]",
5582
+ "required": false
5583
+ },
5584
+ "navStyle": {
5585
+ "type": "NavChromeStyle",
5586
+ "required": false
5587
+ },
5588
+ "navigationItemsLabel": {
5589
+ "type": "string",
5590
+ "required": false
5591
+ },
5592
+ "routerMode": {
5593
+ "type": "PanelNavRouterMode",
5594
+ "required": false
5595
+ },
5596
+ "settingsLabel": {
5597
+ "type": "string",
5598
+ "required": false
5599
+ },
5600
+ "settingsNavigationLabel": {
5601
+ "type": "string",
5740
5602
  "required": false
5741
5603
  },
5742
5604
  "storageKey": {
5743
5605
  "type": "string",
5744
5606
  "required": false
5745
5607
  },
5746
- "toolShortcutsLabel": {
5608
+ "userInitial": {
5747
5609
  "type": "string",
5748
5610
  "required": false
5749
5611
  },
5750
- "toolsLabel": {
5612
+ "userName": {
5751
5613
  "type": "string",
5752
5614
  "required": false
5753
5615
  }
@@ -5762,119 +5624,122 @@
5762
5624
  "detail": "ChromeTransitionDetail"
5763
5625
  },
5764
5626
  {
5765
- "name": "dsHeaderAction",
5766
- "detail": "{\n tool: PanelToolsToolId;\n id: string;\n }"
5627
+ "name": "dsNavFooterAction",
5628
+ "detail": "void"
5767
5629
  },
5768
5630
  {
5769
- "name": "dsHeaderBack",
5770
- "detail": "{\n tool: PanelToolsToolId;\n }"
5631
+ "name": "dsNavSelect",
5632
+ "detail": "string"
5771
5633
  },
5772
5634
  {
5773
- "name": "dsPresentationChange",
5774
- "detail": "{\n presentation: 'drawer' | 'fullscreen';\n }"
5635
+ "name": "dsNavToggle",
5636
+ "detail": "boolean"
5775
5637
  },
5776
5638
  {
5777
- "name": "dsToolChange",
5778
- "detail": "{\n id: PanelToolsToolId;\n selected: boolean;\n }"
5639
+ "name": "dsNavUserAction",
5640
+ "detail": "PanelNavUserActionDetail"
5779
5641
  }
5780
5642
  ],
5781
5643
  "slots": []
5782
5644
  },
5783
5645
  "exports": {
5784
- "customElement": "ds-panel-tools",
5785
- "react": "DsPanelTools",
5786
- "angular": "DsPanelTools"
5646
+ "customElement": "ds-panel-nav",
5647
+ "react": "DsPanelNav",
5648
+ "angular": "DsPanelNav"
5787
5649
  },
5788
5650
  "dependencies": [
5789
5651
  "@ds-mo/ui",
5790
- "@ds-mo/tokens"
5652
+ "@ds-mo/tokens",
5653
+ "@ds-mo/icons"
5791
5654
  ],
5792
5655
  "componentDependencies": [
5656
+ "badge",
5793
5657
  "button-unfilled",
5794
- "panel-tool-header",
5658
+ "icon",
5659
+ "text",
5795
5660
  "tooltip"
5796
5661
  ]
5797
5662
  },
5798
5663
  {
5799
- "id": "component:ds-radio",
5800
- "tag": "ds-radio",
5801
- "name": "radio",
5802
- "title": "Radio",
5803
- "summary": "Form-associated one-of-many radio selection set with vertical or horizontal layout, three densities, per-option inactive state, and roving keyboard focus.",
5664
+ "id": "component:ds-panel-sub-nav",
5665
+ "tag": "ds-panel-sub-nav",
5666
+ "name": "panel-sub-nav",
5667
+ "title": "PanelSubNav",
5668
+ "summary": "Persistent vertical tab navigation for a panel or card side rail, switching adjacent local content with menu-like selected fill and stable text weight.",
5804
5669
  "intentStatus": "complete",
5805
5670
  "intent": {
5806
5671
  "audience": "general",
5807
5672
  "status": "stable",
5808
- "summary": "Form-associated one-of-many radio selection set with vertical or horizontal layout, three densities, per-option inactive state, and roving keyboard focus.",
5673
+ "summary": "Persistent vertical tab navigation for a panel or card side rail, switching adjacent local content with menu-like selected fill and stable text weight.",
5809
5674
  "useWhen": [
5810
- "A user must select exactly one visible option from a small set.",
5811
- "All available choices should remain visible for comparison.",
5812
- "A form needs one selected string value with native validation, reset, or external form association."
5675
+ "A panel or card side rail needs a persistent vertical list that switches adjacent local content.",
5676
+ "Each concise text label controls an immediately available tabpanel without changing application routes."
5813
5677
  ],
5814
5678
  "avoidWhen": [
5815
- "A user may select zero or multiple independent choices.",
5816
- "A binary setting applies immediately rather than selecting from a set.",
5817
- "The option list is too long or space-constrained to remain visible."
5679
+ "The navigation is not contained in a panel or card side rail.",
5680
+ "Local views should be arranged horizontally; use TabGroup instead.",
5681
+ "The choices navigate routes in application shell chrome; use PanelNav or BarNav instead.",
5682
+ "The choices are temporary commands or contextual options; use Menu instead.",
5683
+ "Rows need icons, subtext, notification dots, nested levels, or section headers."
5818
5684
  ],
5819
5685
  "alternatives": [
5820
5686
  {
5821
- "when": "A user may select zero or multiple independent choices.",
5822
- "component": "component:ds-checkbox",
5823
- "reason": "Checkbox communicates independent selection rather than one-of-many choice."
5687
+ "when": "Local panel choices fit a horizontal tab row.",
5688
+ "component": "component:ds-tab-group",
5689
+ "reason": "TabGroup is the horizontal local-view counterpart."
5824
5690
  },
5825
5691
  {
5826
- "when": "A binary setting applies immediately.",
5827
- "component": "component:ds-switch",
5828
- "reason": "Switch communicates an immediately applied on/off setting."
5692
+ "when": "The choices are primary application destinations.",
5693
+ "component": "component:ds-panel-nav",
5694
+ "reason": "PanelNav owns primary application navigation."
5829
5695
  },
5830
5696
  {
5831
- "when": "The option list is long or the available space is constrained.",
5832
- "component": "component:ds-select",
5833
- "reason": "Select keeps a larger one-of-many choice set compact."
5697
+ "when": "The choices are secondary application routes.",
5698
+ "component": "component:ds-bar-nav",
5699
+ "reason": "BarNav owns route sections inside ShellApp."
5700
+ },
5701
+ {
5702
+ "when": "The choices are transient actions or options.",
5703
+ "component": "component:ds-menu",
5704
+ "reason": "Menu owns temporary popup collections."
5834
5705
  }
5835
5706
  ],
5836
5707
  "commonlyComposedWith": [
5837
- "component:ds-field",
5708
+ "component:ds-card-setting",
5838
5709
  "component:ds-text"
5839
5710
  ],
5840
5711
  "accessibility": [
5841
- "The host exposes radiogroup semantics and requires an accessible group name from aria-label or aria-labelledby.",
5842
- "Each visible option exposes radio semantics, its checked state, its label text, and any inactive state.",
5843
- "Arrow keys move and select through active options; Home and End select the first and last active options; Space and Enter select the focused option.",
5844
- "Roving tabindex keeps one active option in the tab order, preferring the selected option."
5712
+ "Provide an accessible name with aria-label or aria-labelledby.",
5713
+ "Give every item a unique id and the id of its controlled tabpanel.",
5714
+ "Keep each controlled tabpanel labelled by its matching item id.",
5715
+ "Always provide a valid selected item when enabled items exist so exactly one tab and panel are active.",
5716
+ "ArrowUp and ArrowDown move and activate selection; Home and End select the first and last available items.",
5717
+ "Do not use selected text weight as the selection cue; active fill and primary foreground communicate selection."
5845
5718
  ],
5846
5719
  "states": [
5847
- "Unchecked circles use a tertiary-foreground inset stroke: 1.25px at md, 1px at sm, and 0.75px at xs.",
5848
- "Selected circles remove the border, use a brand fill, and draw a centered on-bold foreground dot sized 8px at md, 6px at sm, and 4px at xs.",
5849
- "Sizes are md with a 16px circle in a 20px placement, sm with a 12px circle in a 16px placement, and xs with an 8px circle in a 12px placement.",
5850
- "The initial value is restored by native form reset; the selected value submits under name and a required set is invalid until one active option is selected."
5720
+ "The parent owns the canonical selected value and panel visibility, and should update both from dsChange.",
5721
+ "A missing, empty, or unknown selected value is invalid when enabled items exist; the component does not choose a fallback selection.",
5722
+ "Inactive items remain visible but cannot be focused or selected.",
5723
+ "Selection is singular and follows keyboard focus.",
5724
+ "The omitted default surface treatment is for primary and secondary parent surfaces and uses the brand-active selected fill; pass faint explicitly on faint surfaces to use the neutral active fill.",
5725
+ "Rows contain one text label only and do not express nested navigation or grouped hierarchy."
5851
5726
  ],
5852
5727
  "responsiveBehavior": [
5853
- "Choose size from the density of the containing form or settings row.",
5854
- "Prefer vertical layout when labels may wrap or horizontal space is constrained; horizontal layout is appropriate for short labels in a small set."
5728
+ "The component remains vertical at every width.",
5729
+ "The consuming panel owns responsive adaptation and decides whether to reposition or replace the side rail."
5855
5730
  ],
5856
5731
  "frameworkCaveats": {
5857
5732
  "customElements": [
5858
- "Assign options as a JavaScript property, set value as a property for application state updates, and listen for dsChange.",
5859
- "Use the form attribute on the host when associating a radio set rendered outside its owning form."
5733
+ "Assign items as a JavaScript property because structured arrays are not represented by HTML attributes.",
5734
+ "Keep value synchronized to a valid enabled item and update the controlled panel from dsChange."
5860
5735
  ],
5861
5736
  "react": [
5862
- "Use DsRadio, pass options as an array, and handle onDsChange; value is mutable and updates after user selection."
5737
+ "Pass items as an array through the generated wrapper, keep value controlled, and use onDsChange to synchronize the visible panel."
5863
5738
  ],
5864
5739
  "angular": [
5865
- "Use DsRadio with options and value bindings plus dsChange, or import the generated radio value accessor with the component adapter."
5740
+ "Bind items and a valid value as properties, and handle dsChange to synchronize the visible panel."
5866
5741
  ]
5867
- },
5868
- "references": [
5869
- {
5870
- "label": "Storybook examples",
5871
- "path": "src/wc/components/Radio/Radio.stories.ts"
5872
- },
5873
- {
5874
- "label": "Cross-browser form and accessibility coverage",
5875
- "path": "tests/e2e/forms.spec.ts"
5876
- }
5877
- ]
5742
+ }
5878
5743
  },
5879
5744
  "api": {
5880
5745
  "props": {
@@ -5886,40 +5751,12 @@
5886
5751
  "type": "string | undefined",
5887
5752
  "required": false
5888
5753
  },
5889
- "direction": {
5890
- "type": "'vertical' | 'horizontal'",
5891
- "required": false
5892
- },
5893
- "disabled": {
5894
- "type": "boolean",
5895
- "required": false
5896
- },
5897
- "form": {
5898
- "type": "string | undefined",
5899
- "required": false
5900
- },
5901
- "isInactive": {
5902
- "type": "boolean",
5903
- "required": false
5904
- },
5905
- "name": {
5906
- "type": "string | undefined",
5907
- "required": false
5908
- },
5909
- "options": {
5910
- "type": "RadioOption[]",
5911
- "required": false
5912
- },
5913
- "required": {
5914
- "type": "boolean",
5915
- "required": false
5916
- },
5917
- "requiredMessage": {
5918
- "type": "string",
5754
+ "background": {
5755
+ "type": "PanelSubNavBackground | undefined",
5919
5756
  "required": false
5920
5757
  },
5921
- "size": {
5922
- "type": "RadioSize",
5758
+ "items": {
5759
+ "type": "PanelSubNavItem[]",
5923
5760
  "required": false
5924
5761
  },
5925
5762
  "value": {
@@ -5936,9 +5773,9 @@
5936
5773
  "slots": []
5937
5774
  },
5938
5775
  "exports": {
5939
- "customElement": "ds-radio",
5940
- "react": "DsRadio",
5941
- "angular": "DsRadio"
5776
+ "customElement": "ds-panel-sub-nav",
5777
+ "react": "DsPanelSubNav",
5778
+ "angular": "DsPanelSubNav"
5942
5779
  },
5943
5780
  "dependencies": [
5944
5781
  "@ds-mo/ui",
@@ -5949,305 +5786,229 @@
5949
5786
  ]
5950
5787
  },
5951
5788
  {
5952
- "id": "component:ds-scroll-overlay",
5953
- "tag": "ds-scroll-overlay",
5954
- "name": "scroll-overlay",
5955
- "title": "ScrollOverlay",
5956
- "summary": "Generic scroll owner for content that moves behind a persistent footer action or composer with an always-active alpha fade.",
5789
+ "id": "component:ds-panel-tool-header",
5790
+ "tag": "ds-panel-tool-header",
5791
+ "name": "panel-tool-header",
5792
+ "title": "PanelToolHeader",
5793
+ "summary": "Canonical left-aligned PanelTools header with an optional leading navigation or dismiss action and application-owned trailing icon actions.",
5957
5794
  "intentStatus": "complete",
5958
5795
  "intent": {
5959
5796
  "audience": "general",
5960
5797
  "status": "experimental",
5961
- "summary": "Generic scroll owner for content that moves behind a persistent footer action or composer with an always-active alpha fade.",
5798
+ "summary": "Canonical left-aligned PanelTools header with an optional leading navigation or dismiss action and application-owned trailing icon actions.",
5962
5799
  "useWhen": [
5963
- "A bounded region owns scrolling while footer actions remain overlaid and continuously visible.",
5964
- "The final content must clear a live-height footer while earlier content can move behind it."
5800
+ "PanelTools needs its one shared root or detail header.",
5801
+ "A tool header needs a title with optional Back or Close navigation, menu, fullscreen, or other compact icon actions."
5965
5802
  ],
5966
5803
  "avoidWhen": [
5967
- "The footer belongs in normal document flow rather than overlaying content.",
5968
- "Another component already owns scrolling and cannot delegate its scrollport to this component."
5804
+ "Rendering inside a PanelTools tool body; PanelTools already composes this canonical header above the body.",
5805
+ "The header belongs to page content."
5969
5806
  ],
5970
5807
  "commonlyComposedWith": [
5971
- "component:ds-button-filled",
5972
- "component:ds-message-composer"
5808
+ "component:ds-button-unfilled"
5973
5809
  ],
5974
5810
  "accessibility": [
5975
- "Provide scrollLabel when the scrollport needs its own named, keyboard-focusable region.",
5976
- "Keep footer actions keyboard accessible and explicitly named; the fade is decorative and never intercepts pointer input."
5811
+ "Leading navigation or dismiss actions and trailing icon actions require concise localized names; the header reuses each name as the action tooltip.",
5812
+ "The visible heading names the active panel or subview."
5977
5813
  ],
5978
5814
  "states": [
5979
- "The alpha mask remains active at every scroll position and moves in content coordinates so it stays pinned behind the footer without masking native scrollbars.",
5980
- "The component measures the complete overlay for end clearance, measures its visible child for fade depth, and begins the fade 8px before that visible content.",
5981
- "An md 32px footer action with 8px bottom inset therefore produces a 48px fade; variable-height composers produce a correspondingly taller measured fade."
5815
+ "The title remains left aligned whether the header has no actions, Back, one trailing action, or several trailing actions.",
5816
+ "Leading and trailing control zones never shrink; only the title consumes and truncates within the remaining width, with a fixed 4px gap between zones.",
5817
+ "Header chrome text is not selectable; actions remain keyboard focusable and interactive.",
5818
+ "Adjacent trailing actions keep the shared 4px control gap in drawer and fullscreen presentations.",
5819
+ "When fullscreen and overflow actions appear together, author fullscreen before overflow so Ellipses remains the rightmost action.",
5820
+ "PanelTools supplies application-owned actions and relays their ids through its shared dsHeaderAction event."
5982
5821
  ],
5983
5822
  "responsiveBehavior": [
5984
- "The scrollport and overlay fill the available width and height; the owner supplies responsive sizing and overlay insets."
5823
+ "The title truncates between optional leading navigation and trailing action zones."
5985
5824
  ],
5986
- "frameworkCaveats": {
5987
- "customElements": [
5988
- "Place scrollable content in the default slot and one footer wrapper in the overlay slot; use dsScroll only when the application needs position data."
5989
- ],
5990
- "react": [
5991
- "Use DsScrollOverlay with ordinary children plus an element carrying slot=\"overlay\"."
5992
- ],
5993
- "angular": [
5994
- "Import DsScrollOverlay and project the persistent footer wrapper with slot=\"overlay\"."
5995
- ]
5996
- },
5997
5825
  "references": [
5998
5826
  {
5999
- "label": "Storybook examples",
6000
- "path": "src/wc/components/ScrollOverlay/ScrollOverlay.stories.ts"
5827
+ "label": "Standalone examples",
5828
+ "path": "src/wc/components/PanelToolHeader/PanelToolHeader.stories.ts"
6001
5829
  }
6002
5830
  ]
6003
5831
  },
6004
5832
  "api": {
6005
5833
  "props": {
6006
- "scrollLabel": {
5834
+ "actions": {
5835
+ "type": "PanelToolsHeaderAction[]",
5836
+ "required": false
5837
+ },
5838
+ "backAriaLabel": {
5839
+ "type": "string",
5840
+ "required": false
5841
+ },
5842
+ "backIcon": {
5843
+ "type": "string",
5844
+ "required": false
5845
+ },
5846
+ "heading": {
5847
+ "type": "string",
5848
+ "required": false
5849
+ },
5850
+ "menuAriaLabel": {
5851
+ "type": "string",
5852
+ "required": false
5853
+ },
5854
+ "menuControls": {
6007
5855
  "type": "string | undefined",
6008
5856
  "required": false
5857
+ },
5858
+ "menuExpanded": {
5859
+ "type": "boolean",
5860
+ "required": false
5861
+ },
5862
+ "menuTriggerId": {
5863
+ "type": "string",
5864
+ "required": false
5865
+ },
5866
+ "showBack": {
5867
+ "type": "boolean",
5868
+ "required": false
5869
+ },
5870
+ "showMenu": {
5871
+ "type": "boolean",
5872
+ "required": false
6009
5873
  }
6010
5874
  },
6011
5875
  "events": [
6012
5876
  {
6013
- "name": "dsScroll",
6014
- "detail": "ScrollOverlayScrollDetail"
5877
+ "name": "dsAction",
5878
+ "detail": "{ id: string; originalEvent: MouseEvent }"
5879
+ },
5880
+ {
5881
+ "name": "dsBack",
5882
+ "detail": "MouseEvent"
5883
+ },
5884
+ {
5885
+ "name": "dsMenuToggle",
5886
+ "detail": "MouseEvent"
6015
5887
  }
6016
5888
  ],
6017
5889
  "slots": []
6018
5890
  },
6019
5891
  "exports": {
6020
- "customElement": "ds-scroll-overlay",
6021
- "react": "DsScrollOverlay",
6022
- "angular": "DsScrollOverlay"
5892
+ "customElement": "ds-panel-tool-header",
5893
+ "react": "DsPanelToolHeader",
5894
+ "angular": "DsPanelToolHeader"
6023
5895
  },
6024
5896
  "dependencies": [
6025
5897
  "@ds-mo/ui",
6026
5898
  "@ds-mo/tokens"
6027
5899
  ],
6028
- "componentDependencies": []
5900
+ "componentDependencies": [
5901
+ "button-unfilled",
5902
+ "text",
5903
+ "tooltip"
5904
+ ]
6029
5905
  },
6030
5906
  {
6031
- "id": "component:ds-select",
6032
- "tag": "ds-select",
6033
- "name": "select",
6034
- "title": "Select",
6035
- "summary": "Form-associated single-value select with listbox semantics, local search, rich flat options, grouped sections, loading, clearing, and surface-aware trigger chrome.",
5907
+ "id": "component:ds-panel-tool-search",
5908
+ "tag": "ds-panel-tool-search",
5909
+ "name": "panel-tool-search",
5910
+ "title": "PanelToolSearch",
5911
+ "summary": "Transparent search row for the top of a PanelTools product view, with a fixed 48px allocation around the standard md search control and an optional filter-menu trigger.",
6036
5912
  "intentStatus": "complete",
6037
5913
  "intent": {
6038
5914
  "audience": "general",
6039
- "status": "stable",
6040
- "summary": "Form-associated single-value select with listbox semantics, local search, rich flat options, grouped sections, loading, clearing, and surface-aware trigger chrome.",
5915
+ "status": "experimental",
5916
+ "summary": "Transparent search row for the top of a PanelTools product view, with a fixed 48px allocation around the standard md search control and an optional filter-menu trigger.",
6041
5917
  "useWhen": [
6042
- "The user must choose one value from a finite set.",
6043
- "The option set benefits from local search, subtext, prefix icons, grouping, or disabled choices.",
6044
- "The choice set has more than roughly 20 options, comes from a user-managed listing, or represents a large domain such as addresses where search materially improves retrieval.",
6045
- "The selected value must participate in native, Angular, or React form state."
5918
+ "A PanelTools base view filters or searches the tool's own content.",
5919
+ "Several tool products need the same search-row geometry directly below the shared PanelTools header.",
5920
+ "The product needs a compact filter menu next to search while keeping its filter choices and matching policy application-owned."
6046
5921
  ],
6047
5922
  "avoidWhen": [
6048
- "Several values may be selected at once.",
6049
- "The rows perform commands rather than choosing a form value.",
6050
- "The choices form a hierarchy with expandable parents."
6051
- ],
6052
- "alternatives": [
6053
- {
6054
- "when": "Several independent values may be selected.",
6055
- "component": "component:ds-select-multi",
6056
- "reason": "SelectMulti owns array values, multi-selection semantics, and count presentation."
6057
- },
6058
- {
6059
- "when": "The popup contains commands or state-changing actions.",
6060
- "component": "component:ds-menu",
6061
- "reason": "Menu uses action-menu roles and command-focused keyboard behavior."
6062
- },
6063
- {
6064
- "when": "A small set of choices should remain visible.",
6065
- "component": "component:ds-radio",
6066
- "reason": "Prefer Radio for roughly two to five mutually exclusive choices when the available space allows all choices to remain visible."
6067
- }
5923
+ "The search belongs inside a Select or SelectMulti popup; use that component's searchable behavior.",
5924
+ "A form needs a labelled standalone field; compose ds-input inside ds-field instead."
6068
5925
  ],
6069
5926
  "commonlyComposedWith": [
6070
- "component:ds-text",
6071
- "component:ds-icon",
6072
- "component:ds-empty-state",
6073
- "component:ds-loader"
5927
+ "component:ds-panel-tools",
5928
+ "component:ds-conversation-list",
5929
+ "component:ds-input"
6074
5930
  ],
6075
5931
  "accessibility": [
6076
- "In forms, provide a persistent visible external field label; placeholder text is guidance and must not be the field's only label. In a compact filter bar, the trigger's visible text may supply the accessible name.",
6077
- "The trigger uses combobox semantics and the popup uses listbox and option semantics; do not replace them with menu roles.",
6078
- "Disabled options remain visible, expose aria-disabled, and are skipped by keyboard navigation and typeahead.",
6079
- "Keyboard navigation keeps the aria-activedescendant option scrolled into the visible listbox viewport.",
6080
- "Selected options rely on active fill and foreground treatment without a redundant trailing check icon.",
6081
- "Local search moves focus into the search field while preserving the active option through aria-activedescendant.",
6082
- "Use errorMessage with error so the trigger is described by the rendered alert."
5932
+ "Provide an aria-label that names the searched domain, such as Search agent chats or Search messages.",
5933
+ "The standard search clear action restores focus, uses the concise localized clearLabel by itself for both its tooltip and accessible name, and emits both the empty query and dsClear.",
5934
+ "When showFilter is enabled, provide stable filterTriggerId and filterControls values, synchronize filterExpanded with the controlled menu, and restore focus after selection; filterAriaLabel also labels its tooltip."
6083
5935
  ],
6084
5936
  "states": [
6085
- "Value is controlled through the mutable value property; dsChange reports user selection and clearing.",
6086
- "Required Selects begin without an automatic selection and require the user to make an explicit choice; do not preselect the first option merely to satisfy validity.",
6087
- "When allowClear is enabled, the clear affordance appears only after a value exists. Clearing is valid for optional and required fields; a required field becomes invalid until the user selects again.",
6088
- "Clearing emits dsChange with an empty string and dsClear, keeps the popup open, and restores useful focus.",
6089
- "Loading keeps the trigger visible, replaces its prefix icon, marks the control busy, and makes selection interaction temporarily unavailable without presenting the control as inactive.",
6090
- "The trigger label stays left-aligned at every width. The default size is md in both forms and filter bars; smaller sizes require an explicit density need.",
6091
- "Use option icons only when they help users differentiate choices. Icons render only when every option in the complete list provides one; mixed icon data falls back to the text-only row layout.",
6092
- "Create sections only for categories that are meaningful to customers, not merely to break a long list into arbitrary chunks.",
6093
- "When any option supplies subtext, every row uses the same subtext structure and missing values render an em dash. Subtext should disambiguate or add decision-helpful information.",
6094
- "Option labels and the selected trigger label stay on one line and truncate when constrained. Option subtext may wrap to at most two lines.",
6095
- "The optional prefix icon and chevron always use the parent surface's secondary foreground color, including when a selected value promotes the label to primary.",
6096
- "The shared popup search control stays md at every trigger size, using body-medium text, a 20px icon, and the same internal spacing as a borderless Select trigger. Its container uses menu-item padding on every side and owns a 1px bottom divider that becomes a 1.5px bold-brand stroke while search has focus. Search placeholder text is secondary at rest and quaternary while focused because it becomes decorative once the editable field is active.",
6097
- "When search contains text, the shared control shows a rounded sm icon-only ButtonUnfilled with the CrossCircle icon and no border. It clears the local term, stays hidden for an empty term, and returns focus to search.",
6098
- "The shared clear footer mirrors the search region's sizing: menu-item padding surrounds an md-height borderless row, and the Clear label uses the same row and label insets as option text. The outer footer owns a 1px top divider.",
6099
- "An empty filtered list composes the message-only body variant of EmptyState. Keep the default neutral no-results message unless localized product guidance makes the outcome clearer.",
6100
- "Enable searchable for more than roughly 20 options, user-managed listings, large domains such as addresses, or sets users cannot efficiently scan. Local matching includes option labels, subtext, and section headings; the owner resolves remote data before assigning options.",
6101
- "Validation timing belongs to the form owner and may be immediate or deferred until blur or submit; the Select exposes validity and error presentation without imposing that policy.",
6102
- "The error trigger uses a 1.5px bold-negative inset stroke so invalid state remains distinguishable from the normal 1px border without changing control geometry.",
6103
- "An initially empty option set is not an expected Select use case. The no-results state describes a search with no matches, not a source with no choices.",
6104
- "Use options for a flat list or sections for grouped choices; when sections are present they take precedence.",
6105
- "The background prop describes the actual parent surface and uses the same surface set as ButtonUnfilled."
5937
+ "The row is always 48px high with 8px outer padding and a complete md search recipe: 32px control, text-body-medium at 14px/20px, and a 20px md search icon.",
5938
+ "The search icon stays foreground-secondary at rest, hover, focus, active, and while the query is filled.",
5939
+ "The row and control surface remain transparent so the ShellApp chrome wash is visible behind them.",
5940
+ "The row divider remains the same tertiary 1px boundary while the input is focused because it belongs to the 48px container rather than the input control.",
5941
+ "With filtering enabled, the md search control, decorative vertical divider, and borderless md Filter action are separated by 8px; filterActive promotes only the trigger foreground without adding a selected fill."
6106
5942
  ],
6107
5943
  "responsiveBehavior": [
6108
- "Use width fill for form fields and width hug for compact filter bars. Override those defaults only when the owning layout has a clear constraint.",
6109
- "The popup matches the trigger minimum width, may grow for content, and clamps to the viewport.",
6110
- "Long option collections scroll inside the popup; virtualization and remote search are not part of this component."
5944
+ "The row fills the available drawer or fullscreen width, allows its search region to shrink inside a 300px drawer without pushing the filter trigger under the tool rail, and does not reduce its control below md density."
6111
5945
  ],
6112
5946
  "frameworkCaveats": {
6113
5947
  "customElements": [
6114
- "Assign options and sections through JavaScript properties because arrays and objects cannot be represented safely as attributes."
5948
+ "Listen for dsChange to receive the current string query and dsClear when the clear action is used.",
5949
+ "Listen for dsFilterToggle and pair the trigger with an externally controlled ds-menu; product-specific filter labels and filtering remain outside this component."
6115
5950
  ],
6116
5951
  "react": [
6117
- "Pass options or sections as wrapper props and handle onDsChange, onDsClear, and onDsOpenChange."
5952
+ "Use DsPanelToolSearch, bind value for controlled state, and handle onDsChange.",
5953
+ "Bind the optional filter trigger state and connect onDsFilterToggle to a controlled DsMenu."
6118
5954
  ],
6119
5955
  "angular": [
6120
- "Import DsSelect and SelectValueAccessor when integrating with Angular Forms; bind options and sections as properties."
5956
+ "Import DsPanelToolSearch and bind value as a property; this search composition is not a form value accessor.",
5957
+ "Bind showFilter, filterExpanded, and filterActive, then connect dsFilterToggle to a product-owned ds-menu."
6121
5958
  ]
6122
5959
  },
6123
5960
  "references": [
6124
5961
  {
6125
5962
  "label": "Storybook examples",
6126
- "path": "src/wc/components/Select/Select.stories.ts"
6127
- },
6128
- {
6129
- "label": "Selection patterns",
6130
- "path": "src/docs/SelectionPatterns.mdx"
5963
+ "path": "src/wc/components/PanelToolSearch/PanelToolSearch.stories.ts"
6131
5964
  }
6132
5965
  ]
6133
5966
  },
6134
5967
  "api": {
6135
5968
  "props": {
6136
- "activeFill": {
6137
- "type": "boolean",
5969
+ "ariaLabel": {
5970
+ "type": "string",
6138
5971
  "required": false
6139
5972
  },
6140
- "allowClear": {
6141
- "type": "boolean",
5973
+ "controls": {
5974
+ "type": "string | undefined",
6142
5975
  "required": false
6143
5976
  },
6144
- "ariaDescribedby": {
6145
- "type": "string | undefined",
5977
+ "filterActive": {
5978
+ "type": "boolean",
6146
5979
  "required": false
6147
5980
  },
6148
- "ariaLabel": {
6149
- "type": "string | null",
5981
+ "filterAriaLabel": {
5982
+ "type": "string",
6150
5983
  "required": false
6151
5984
  },
6152
- "ariaLabelledby": {
5985
+ "filterControls": {
6153
5986
  "type": "string | undefined",
6154
5987
  "required": false
6155
5988
  },
6156
- "background": {
6157
- "type": "SelectBackground | undefined",
5989
+ "filterExpanded": {
5990
+ "type": "boolean",
6158
5991
  "required": false
6159
5992
  },
6160
- "clearLabel": {
5993
+ "filterTriggerId": {
6161
5994
  "type": "string",
6162
5995
  "required": false
6163
5996
  },
6164
- "disabled": {
5997
+ "isInactive": {
6165
5998
  "type": "boolean",
6166
5999
  "required": false
6167
6000
  },
6168
- "error": {
6169
- "type": "boolean",
6001
+ "placeholder": {
6002
+ "type": "string",
6170
6003
  "required": false
6171
6004
  },
6172
- "errorMessage": {
6173
- "type": "string | undefined",
6174
- "required": false
6175
- },
6176
- "hasBorder": {
6177
- "type": "boolean",
6178
- "required": false
6179
- },
6180
- "icon": {
6181
- "type": "string | undefined",
6182
- "required": false
6183
- },
6184
- "inputId": {
6185
- "type": "string | undefined",
6186
- "required": false
6187
- },
6188
- "isInactive": {
6189
- "type": "boolean",
6190
- "required": false
6191
- },
6192
- "isLoading": {
6193
- "type": "boolean",
6194
- "required": false
6195
- },
6196
- "loadingLabel": {
6197
- "type": "string",
6198
- "required": false
6199
- },
6200
- "name": {
6201
- "type": "string | undefined",
6202
- "required": false
6203
- },
6204
- "noResultsText": {
6205
- "type": "string",
6206
- "required": false
6207
- },
6208
- "open": {
6209
- "type": "boolean",
6210
- "required": false
6211
- },
6212
- "options": {
6213
- "type": "SelectOption[]",
6214
- "required": false
6215
- },
6216
- "placeholder": {
6217
- "type": "string",
6218
- "required": false
6219
- },
6220
- "required": {
6221
- "type": "boolean",
6222
- "required": false
6223
- },
6224
- "requiredMessage": {
6225
- "type": "string",
6226
- "required": false
6227
- },
6228
- "searchPlaceholder": {
6229
- "type": "string",
6230
- "required": false
6231
- },
6232
- "searchable": {
6005
+ "showFilter": {
6233
6006
  "type": "boolean",
6234
6007
  "required": false
6235
6008
  },
6236
- "sections": {
6237
- "type": "SelectSection[]",
6238
- "required": false
6239
- },
6240
- "size": {
6241
- "type": "SelectSize",
6242
- "required": false
6243
- },
6244
6009
  "value": {
6245
6010
  "type": "string",
6246
6011
  "required": false
6247
- },
6248
- "width": {
6249
- "type": "SelectWidth",
6250
- "required": false
6251
6012
  }
6252
6013
  },
6253
6014
  "events": [
@@ -6260,16 +6021,16 @@
6260
6021
  "detail": "void"
6261
6022
  },
6262
6023
  {
6263
- "name": "dsOpenChange",
6264
- "detail": "boolean"
6024
+ "name": "dsFilterToggle",
6025
+ "detail": "MouseEvent"
6265
6026
  }
6266
6027
  ],
6267
6028
  "slots": []
6268
6029
  },
6269
6030
  "exports": {
6270
- "customElement": "ds-select",
6271
- "react": "DsSelect",
6272
- "angular": "DsSelect"
6031
+ "customElement": "ds-panel-tool-search",
6032
+ "react": "DsPanelToolSearch",
6033
+ "angular": "DsPanelToolSearch"
6273
6034
  },
6274
6035
  "dependencies": [
6275
6036
  "@ds-mo/ui",
@@ -6278,186 +6039,152 @@
6278
6039
  ],
6279
6040
  "componentDependencies": [
6280
6041
  "button-unfilled",
6281
- "empty-state",
6042
+ "divider",
6282
6043
  "icon",
6283
- "loader",
6284
6044
  "text",
6285
6045
  "tooltip"
6286
6046
  ]
6287
6047
  },
6288
6048
  {
6289
- "id": "component:ds-select-multi",
6290
- "tag": "ds-select-multi",
6291
- "name": "select-multi",
6292
- "title": "SelectMulti",
6293
- "summary": "Form-associated multi-value select with a persistent trigger label, inline selected count, local search, rich flat options, grouped sections, loading, and clear-all behavior.",
6049
+ "id": "component:ds-panel-tools",
6050
+ "tag": "ds-panel-tools",
6051
+ "name": "panel-tools",
6052
+ "title": "PanelTools",
6053
+ "summary": "Required ShellApp utility rail and persistent drawer host for the fixed set of global Search, Agents, Messages, Stacks, Activity, and Help products.",
6294
6054
  "intentStatus": "complete",
6295
6055
  "intent": {
6296
- "audience": "general",
6056
+ "audience": "specialized",
6297
6057
  "status": "stable",
6298
- "summary": "Form-associated multi-value select with a persistent trigger label, inline selected count, local search, rich flat options, grouped sections, loading, and clear-all behavior.",
6058
+ "summary": "Required ShellApp utility rail and persistent drawer host for the fixed set of global Search, Agents, Messages, Stacks, Activity, and Help products.",
6299
6059
  "useWhen": [
6300
- "The user may choose several independent values from one finite set.",
6301
- "A compact trigger should summarize selection with the field label and a count.",
6302
- "The option set benefits from local search, subtext, grouping, or disabled choices.",
6303
- "The choice set has more than roughly 20 options, comes from a user-managed listing, or represents a large domain where search materially improves retrieval."
6060
+ "Composing the required global tools region inside the application's single ShellApp.",
6061
+ "Users need to move between application-wide utilities without losing each tool's in-progress state.",
6062
+ "Search, AI conversations, user messages, review stacks, notifications, or help content must remain available alongside route content."
6304
6063
  ],
6305
6064
  "avoidWhen": [
6306
- "Exactly one value may be selected.",
6307
- "Selected values must remain individually removable as persistent tags outside the popup.",
6308
- "The choices form a hierarchy with cascading parent selection.",
6309
- "The customer task benefits more from keeping every choice and checkbox directly visible; choose between SelectMulti and a visible checkbox list from the use-case context rather than a fixed option-count threshold."
6065
+ "The action is specific to the current page or selected content rather than globally available across the application.",
6066
+ "The item navigates to a primary or secondary route; use PanelNav or BarNav instead.",
6067
+ "A consumer wants to add arbitrary tools, reorder fixed tools, or repurpose a semantic tool id.",
6068
+ "Building the mobile tools experience; future mobile ShellApp composition uses a different bottom-bar and panel pattern.",
6069
+ "PanelTools would be mounted outside the application's single ShellApp."
6310
6070
  ],
6311
6071
  "alternatives": [
6312
6072
  {
6313
- "when": "Exactly one value may be selected.",
6314
- "component": "component:ds-select",
6315
- "reason": "Select owns scalar form value and single-select listbox behavior."
6073
+ "when": "The action navigates to a top-level application destination.",
6074
+ "component": "component:ds-panel-nav",
6075
+ "reason": "PanelNav exclusively owns primary application navigation."
6316
6076
  },
6317
6077
  {
6318
- "when": "The popup contains actions rather than values.",
6078
+ "when": "The action navigates between route sections of the active destination.",
6079
+ "component": "component:ds-bar-nav",
6080
+ "reason": "BarNav exclusively owns secondary route navigation."
6081
+ },
6082
+ {
6083
+ "when": "Temporary contextual actions or options are needed.",
6319
6084
  "component": "component:ds-menu",
6320
- "reason": "Menu uses command semantics and closes according to action-menu expectations."
6085
+ "reason": "Menu owns transient contextual choices rather than persistent global products."
6321
6086
  }
6322
6087
  ],
6323
6088
  "commonlyComposedWith": [
6324
- "component:ds-text",
6325
- "component:ds-checkbox",
6326
- "component:ds-empty-state",
6327
- "component:ds-loader"
6089
+ "component:ds-shell-app",
6090
+ "component:ds-panel-nav",
6091
+ "component:ds-bar-nav"
6092
+ ],
6093
+ "patterns": [
6094
+ "pattern:application-shell"
6328
6095
  ],
6329
6096
  "accessibility": [
6330
- "In forms, provide a persistent visible external field label. In a compact filter bar, the trigger's visible persistent label and count may supply the accessible name.",
6331
- "The popup is a listbox with aria-multiselectable and every option exposes its independent aria-selected state.",
6332
- "Disabled options expose aria-disabled and are skipped by keyboard navigation and typeahead.",
6333
- "Keyboard navigation keeps the aria-activedescendant option scrolled into the visible listbox viewport.",
6334
- "Each row uses a medium-size presentation-only ds-checkbox indicator; multi-select option rows never add a prefix icon alongside it, and the option remains the sole selection semantic and interaction target.",
6335
- "The trigger keeps its field label visible and appends the current selected count; an explicit aria-label or aria-labelledby remains the authoritative accessible name when supplied.",
6336
- "Use errorMessage with error so the trigger is described by the rendered alert."
6097
+ "Provide localized accessible labels for the rail, shortcut group, and every rendered tool.",
6098
+ "Keep Search first in the rail header and Help last in the rail footer so keyboard and visual order remain predictable.",
6099
+ "Keep focus on the selected rail action when opening a drawer and allow normal Tab navigation into its content.",
6100
+ "Do not trigger global shortcuts while focus is in an editable control.",
6101
+ "Use notification dots only as supplemental unread or new-content status and never as the sole status indication.",
6102
+ "Explain temporarily inactive tools through an accessible label or adjacent product guidance; omit unauthorized tools entirely."
6337
6103
  ],
6338
6104
  "states": [
6339
- "Values is a controlled JavaScript array; dsChange emits a new array after each user toggle.",
6340
- "Required SelectMulti controls begin without an automatic selection and require the user to make an explicit choice.",
6341
- "Selecting an option keeps the popup open so additional values can be toggled.",
6342
- "The trigger label stays left-aligned at every width; every option row uses the same leading medium Checkbox indicator. The default control size is md in both forms and filter bars.",
6343
- "The selected count always follows the persistent label as plain text separated by a centered dot, including for one selection, and counts every selected value even when search or grouping hides it. Never replace the count with selected option names.",
6344
- "Create sections only for categories that are meaningful to customers, not merely to break a long list into arbitrary chunks.",
6345
- "When any option supplies subtext, every row uses the same subtext structure and missing values render an em dash. Subtext should disambiguate or add decision-helpful information.",
6346
- "Option labels stay on one line and truncate when constrained. Option subtext may wrap to at most two lines.",
6347
- "The optional prefix icon and chevron always use the parent surface's secondary foreground color, including when selection promotes the label and count to primary.",
6348
- "The shared popup search control stays md at every trigger size, using body-medium text, a 20px icon, and the same internal spacing as a borderless Select trigger. Its container uses menu-item padding on every side and owns a 1px bottom divider that becomes a 1.5px bold-brand stroke while search has focus. Search placeholder text is secondary at rest and quaternary while focused because it becomes decorative once the editable field is active.",
6349
- "When search contains text, the shared control shows a rounded sm icon-only ButtonUnfilled with the Cross icon and no border. It clears the local term, stays hidden for an empty term, and returns focus to search.",
6350
- "The shared summary-and-clear footer mirrors the search region's sizing: menu-item padding surrounds an md-height borderless row, and both texts use the same row and label insets as option text. The outer footer owns a 1px top divider.",
6351
- "An empty filtered list composes the message-only body variant of EmptyState. Keep the default neutral no-results message unless localized product guidance makes the outcome clearer.",
6352
- "Enable searchable for more than roughly 20 options, user-managed listings, large domains such as addresses, or sets users cannot efficiently scan. Local matching includes option labels, subtext, and section headings; the owner resolves remote data before assigning options.",
6353
- "When allowClear is enabled, clear-all appears only after at least one value exists. Clearing is valid for optional and required fields; a required field becomes invalid until the user selects again.",
6354
- "Clear-all emits an empty dsChange and dsClear while preserving useful popup or search focus.",
6355
- "Loading keeps the trigger visible, marks the control busy, and makes selection interaction temporarily unavailable without presenting the control as inactive.",
6356
- "SelectMulti has no maximum-selection behavior; every available non-inactive option may be selected.",
6357
- "Validation timing belongs to the form owner and may be immediate or deferred until blur or submit; the component exposes validity and error presentation without imposing that policy.",
6358
- "The error trigger uses a 1.5px bold-negative inset stroke so invalid state remains distinguishable from the normal 1px border without changing control geometry.",
6359
- "An initially empty option set is not an expected SelectMulti use case. The no-results state describes a search with no matches, not a source with no choices.",
6360
- "Native form submission emits one entry per selected value under the component name.",
6361
- "Use options for a flat list or sections for grouped choices. Multi-select option contracts intentionally exclude icons because the leading checkbox owns that row zone; hierarchical parent selection is deferred."
6105
+ "Search and Help are required; optional Agents, Messages, Stacks, and Activity tools are filtered by the application for authorization and entitlement.",
6106
+ "Use only the fixed semantic tool ids and canonical order: Search, Agents, Messages, Stacks, Activity, Help; do not reorder, duplicate, or repurpose them.",
6107
+ "Search is application-wide; Agents is user-to-AI chat; Messages is user-to-user chat; Stacks is a specialized inbox of grouped application events for review; Activity is the notification center; Help is drawer content that may link to external resources.",
6108
+ "Only one drawer is open at a time; selecting another tool switches directly and selecting the active tool closes to rail-only mode.",
6109
+ "The drawer starts closed, remains open across ordinary route changes, and retains every mounted tool's independent conversation, query, scroll, and work state.",
6110
+ "When storageKey is set, persist only the last active tool in this browser and still restore the drawer closed after reload.",
6111
+ "The application owns unread state; opening Messages, Agents, Stacks, or Activity does not automatically clear its notification dot.",
6112
+ "PanelTools owns the one visible header above every drawer tool view and above fullscreen views using the default shared header mode. Slotted tool content must not render a second header unless the conversation product explicitly opts into split fullscreen headers.",
6113
+ "PanelTools composes ds-panel-tool-header as its canonical left-aligned header implementation so standalone header stories and shell rendering cannot diverge.",
6114
+ "Each tool supplies its current header title, base-versus-detail Back state, and right-side actions through the headers property. Base views omit Back; deeper views expose Back and update the same header in place.",
6115
+ "Header Back and action events express intent only; the owning tool changes product navigation, menus, and data state. PanelTools keeps the final header action exactly 8px from the drawer edge.",
6116
+ "Menus opened from a right-side header action use PANEL_TOOLS_HEADER_MENU_PLACEMENT: bottom/end choice-cell alignment and a 12px side offset, placing the popup 4px below the 48px header while aligning the final menu item edge with the trigger.",
6117
+ "Tool view roots stay transparent so ShellApp's chrome wash remains visible; only explicitly designed child surfaces introduce a fill.",
6118
+ "Tools with search compose ds-panel-tool-search immediately below the shared header. Its 48px row always contains the md search control and must not be reduced to sm or xs.",
6119
+ "If an active optional tool becomes unavailable, PanelTools closes the drawer, clears activeTool, and emits its deselection.",
6120
+ "Use isInactive only for a temporarily unavailable visible tool; omit tools the user is not authorized to access.",
6121
+ "The application owns slotted tool products and data while PanelTools owns rail ordering, drawer selection, open state, motion, and shell events.",
6122
+ "Opening and closing clip an already-rendered fixed-width surface. Header and tool content remain fully opaque and retained during width motion; transition completion is accepted only at the measured terminal clip width, after which the closed surface becomes inert and paint-skipped.",
6123
+ "Entering and exiting fullscreen snaps without borrowing the drawer open or close animation.",
6124
+ "When fullscreenHeaderMode is split, PanelTools suppresses only its fullscreen shared header. The application renders exactly two canonical ds-panel-tool-header instances: a tool-title/list-actions header over the 300px history pane and a chat-title/Exit-fullscreen/chat-actions header over the detail pane. The detail header omits Back because the list remains visible."
6362
6125
  ],
6363
6126
  "responsiveBehavior": [
6364
- "Use width fill for form fields and width hug for compact filter bars; the persistent trigger label avoids variable-width selected labels.",
6365
- "The popup matches the trigger minimum width, may grow for content, and clamps to the viewport.",
6366
- "Long option collections scroll inside the popup; virtualization and remote search are not part of this version."
6127
+ "The open drawer reduces main-content width and uses --dimension-panel-width-xs (300px) on every supported desktop and tablet viewport.",
6128
+ "ShellApp owns the fixed drawer-width variable; consumers must not hardcode alternate drawer widths.",
6129
+ "Below 768px, do not reuse desktop PanelTools: future ShellApp mobile composition uses a bottom bar for Search, Agents, Notifications, and Stacks, while Help moves into mobile primary navigation.",
6130
+ "Keep named-slot content mounted while tools switch or the drawer closes so users can return to in-progress global work.",
6131
+ "Conversation products may use fullscreenHeaderMode split for a 300px history rail beside a flexible detail pane, each with its own canonical header; the application owns that internal split layout.",
6132
+ "Use fixed drawer widths for now; do not add user resizing or width persistence."
6367
6133
  ],
6368
6134
  "frameworkCaveats": {
6369
6135
  "customElements": [
6370
- "Assign values, options, and sections through JavaScript properties; array values cannot be represented safely as attributes."
6136
+ "Assign items as a JavaScript property for structured data; items-json is the string fallback.",
6137
+ "Assign headers as a JavaScript property and replace its object identity whenever an active tool changes title, depth, or actions.",
6138
+ "Keep PanelTools mounted at ShellApp scope across route changes and provide each product through its matching named slot."
6371
6139
  ],
6372
6140
  "react": [
6373
- "Pass values, options, and sections as wrapper props and handle onDsChange, onDsClear, and onDsOpenChange."
6141
+ "Pass the fixed item collection through the generated React wrapper and keep named-slot product content mounted at ShellApp scope.",
6142
+ "Use storageKey only for same-browser last-tool continuity; do not persist the open drawer."
6374
6143
  ],
6375
6144
  "angular": [
6376
- "Import DsSelectMulti and SelectMultiValueAccessor when integrating with Angular Forms."
6145
+ "Import DsPanelTools from @ds-mo/ui/angular/ds-panel-tools and bind items as a property.",
6146
+ "Bind headers as a replaced object and route dsHeaderBack and dsHeaderAction to the active tool owner.",
6147
+ "Keep the component in the persistent shell layout rather than recreating it in routed page components."
6377
6148
  ]
6378
6149
  },
6379
6150
  "references": [
6380
6151
  {
6381
- "label": "Storybook examples",
6382
- "path": "src/wc/components/SelectMulti/SelectMulti.stories.ts"
6152
+ "label": "Executable Storybook examples",
6153
+ "path": "src/wc/components/PanelTools/PanelTools.stories.ts"
6383
6154
  },
6384
6155
  {
6385
- "label": "Selection patterns",
6386
- "path": "src/docs/SelectionPatterns.mdx"
6156
+ "label": "Framework and shell integration",
6157
+ "path": "docs/framework-integration.md"
6158
+ },
6159
+ {
6160
+ "label": "Application shell composition",
6161
+ "path": "agent/patterns/application-shell/pattern.agent.json"
6387
6162
  }
6388
6163
  ]
6389
6164
  },
6390
6165
  "api": {
6391
6166
  "props": {
6392
- "activeFill": {
6393
- "type": "boolean",
6394
- "required": false
6395
- },
6396
- "allowClear": {
6397
- "type": "boolean",
6167
+ "activeTool": {
6168
+ "type": "PanelToolsToolId | ''",
6398
6169
  "required": false
6399
6170
  },
6400
- "ariaDescribedby": {
6401
- "type": "string | undefined",
6171
+ "fullscreenHeaderMode": {
6172
+ "type": "'shared' | 'split'",
6402
6173
  "required": false
6403
6174
  },
6404
- "ariaLabel": {
6405
- "type": "string | null",
6175
+ "headers": {
6176
+ "type": "PanelToolsHeaders",
6406
6177
  "required": false
6407
6178
  },
6408
- "ariaLabelledby": {
6409
- "type": "string | undefined",
6179
+ "headersJson": {
6180
+ "type": "string",
6410
6181
  "required": false
6411
6182
  },
6412
- "background": {
6413
- "type": "SelectMultiBackground | undefined",
6183
+ "items": {
6184
+ "type": "PanelToolsItem[]",
6414
6185
  "required": false
6415
6186
  },
6416
- "clearLabel": {
6417
- "type": "string",
6418
- "required": false
6419
- },
6420
- "disabled": {
6421
- "type": "boolean",
6422
- "required": false
6423
- },
6424
- "error": {
6425
- "type": "boolean",
6426
- "required": false
6427
- },
6428
- "errorMessage": {
6429
- "type": "string | undefined",
6430
- "required": false
6431
- },
6432
- "hasBorder": {
6433
- "type": "boolean",
6434
- "required": false
6435
- },
6436
- "icon": {
6437
- "type": "string | undefined",
6438
- "required": false
6439
- },
6440
- "inputId": {
6441
- "type": "string | undefined",
6442
- "required": false
6443
- },
6444
- "isInactive": {
6445
- "type": "boolean",
6446
- "required": false
6447
- },
6448
- "isLoading": {
6449
- "type": "boolean",
6450
- "required": false
6451
- },
6452
- "loadingLabel": {
6453
- "type": "string",
6454
- "required": false
6455
- },
6456
- "name": {
6457
- "type": "string | undefined",
6458
- "required": false
6459
- },
6460
- "noResultsText": {
6187
+ "itemsJson": {
6461
6188
  "type": "string",
6462
6189
  "required": false
6463
6190
  },
@@ -6465,792 +6192,1170 @@
6465
6192
  "type": "boolean",
6466
6193
  "required": false
6467
6194
  },
6468
- "options": {
6469
- "type": "SelectMultiOption[]",
6470
- "required": false
6471
- },
6472
- "placeholder": {
6473
- "type": "string",
6474
- "required": false
6475
- },
6476
- "required": {
6477
- "type": "boolean",
6195
+ "presentation": {
6196
+ "type": "'drawer' | 'fullscreen'",
6478
6197
  "required": false
6479
6198
  },
6480
- "requiredMessage": {
6199
+ "storageKey": {
6481
6200
  "type": "string",
6482
6201
  "required": false
6483
6202
  },
6484
- "searchPlaceholder": {
6203
+ "toolShortcutsLabel": {
6485
6204
  "type": "string",
6486
6205
  "required": false
6487
6206
  },
6488
- "searchable": {
6489
- "type": "boolean",
6490
- "required": false
6491
- },
6492
- "sections": {
6493
- "type": "SelectMultiSection[]",
6494
- "required": false
6495
- },
6496
- "selectedLabel": {
6207
+ "toolsLabel": {
6497
6208
  "type": "string",
6498
6209
  "required": false
6499
- },
6500
- "size": {
6501
- "type": "SelectMultiSize",
6502
- "required": false
6503
- },
6504
- "values": {
6505
- "type": "string[]",
6506
- "required": false
6507
- },
6508
- "width": {
6509
- "type": "SelectMultiWidth",
6510
- "required": false
6511
6210
  }
6512
6211
  },
6513
6212
  "events": [
6514
6213
  {
6515
- "name": "dsChange",
6516
- "detail": "string[]"
6214
+ "name": "dsChromeTransitionEnd",
6215
+ "detail": "ChromeTransitionDetail"
6517
6216
  },
6518
6217
  {
6519
- "name": "dsClear",
6520
- "detail": "void"
6218
+ "name": "dsChromeTransitionStart",
6219
+ "detail": "ChromeTransitionDetail"
6521
6220
  },
6522
6221
  {
6523
- "name": "dsOpenChange",
6524
- "detail": "boolean"
6222
+ "name": "dsHeaderAction",
6223
+ "detail": "{\n tool: PanelToolsToolId;\n id: string;\n }"
6224
+ },
6225
+ {
6226
+ "name": "dsHeaderBack",
6227
+ "detail": "{\n tool: PanelToolsToolId;\n }"
6228
+ },
6229
+ {
6230
+ "name": "dsPresentationChange",
6231
+ "detail": "{\n presentation: 'drawer' | 'fullscreen';\n }"
6232
+ },
6233
+ {
6234
+ "name": "dsToolChange",
6235
+ "detail": "{\n id: PanelToolsToolId;\n selected: boolean;\n }"
6525
6236
  }
6526
6237
  ],
6527
6238
  "slots": []
6528
6239
  },
6529
6240
  "exports": {
6530
- "customElement": "ds-select-multi",
6531
- "react": "DsSelectMulti",
6532
- "angular": "DsSelectMulti"
6241
+ "customElement": "ds-panel-tools",
6242
+ "react": "DsPanelTools",
6243
+ "angular": "DsPanelTools"
6533
6244
  },
6534
6245
  "dependencies": [
6535
6246
  "@ds-mo/ui",
6536
- "@ds-mo/tokens",
6537
- "@ds-mo/icons"
6247
+ "@ds-mo/tokens"
6538
6248
  ],
6539
6249
  "componentDependencies": [
6540
6250
  "button-unfilled",
6541
- "checkbox",
6542
- "empty-state",
6543
- "icon",
6544
- "loader",
6545
- "text",
6251
+ "panel-tool-header",
6546
6252
  "tooltip"
6547
6253
  ]
6548
6254
  },
6549
6255
  {
6550
- "id": "component:ds-shell-app",
6551
- "tag": "ds-shell-app",
6552
- "name": "shell-app",
6553
- "title": "ShellApp",
6554
- "summary": "The single required workspace root for standard authenticated application pages, coordinating primary and secondary navigation, tools chrome, responsive composition, content geometry, shared styling, and shell behavior.",
6256
+ "id": "component:ds-radio",
6257
+ "tag": "ds-radio",
6258
+ "name": "radio",
6259
+ "title": "Radio",
6260
+ "summary": "Form-associated one-of-many radio selection set with vertical or horizontal layout, three densities, per-option inactive state, and roving keyboard focus.",
6555
6261
  "intentStatus": "complete",
6556
6262
  "intent": {
6557
- "audience": "specialized",
6263
+ "audience": "general",
6558
6264
  "status": "stable",
6559
- "summary": "The single required workspace root for standard authenticated application pages, coordinating primary and secondary navigation, tools chrome, responsive composition, content geometry, shared styling, and shell behavior.",
6265
+ "summary": "Form-associated one-of-many radio selection set with vertical or horizontal layout, three densities, per-option inactive state, and roving keyboard focus.",
6560
6266
  "useWhen": [
6561
- "Building any standard authenticated product or workspace page with CompoMo.",
6562
- "PanelNav, BarNav, ShellTools, mobile navigation, page content, shared chrome, responsive behavior, and shell shortcuts must be composed as one application frame.",
6563
- "Future application templates need the supported base-page composition boundary."
6267
+ "A user must select exactly one visible option from a small set.",
6268
+ "All available choices should remain visible for comparison.",
6269
+ "A form needs one selected string value with native validation, reset, or external form association."
6564
6270
  ],
6565
6271
  "avoidWhen": [
6566
- "Building authentication, onboarding, public, marketing, print, error, or intentionally focused full-screen experiences that require a different layout.",
6567
- "Another ShellApp already exists in the page; applications must render exactly one and must never nest ShellApps.",
6568
- "Building content inside an existing ShellApp; render the page content rather than another shell."
6272
+ "A user may select zero or multiple independent choices.",
6273
+ "A binary setting applies immediately rather than selecting from a set.",
6274
+ "The option list is too long or space-constrained to remain visible."
6569
6275
  ],
6570
- "commonlyComposedWith": [
6571
- "component:ds-panel-nav",
6572
- "component:ds-bar-nav",
6573
- "component:ds-panel-tools",
6574
- "component:ds-shell-tools",
6575
- "component:ds-shell-mobile-nav",
6576
- "component:ds-shell-mobile-section-nav",
6577
- "component:ds-shell-mobile-bar",
6578
- "component:ds-shell-page",
6579
- "component:ds-swatch-picker"
6276
+ "alternatives": [
6277
+ {
6278
+ "when": "A user may select zero or multiple independent choices.",
6279
+ "component": "component:ds-checkbox",
6280
+ "reason": "Checkbox communicates independent selection rather than one-of-many choice."
6281
+ },
6282
+ {
6283
+ "when": "A binary setting applies immediately.",
6284
+ "component": "component:ds-switch",
6285
+ "reason": "Switch communicates an immediately applied on/off setting."
6286
+ },
6287
+ {
6288
+ "when": "The option list is long or the available space is constrained.",
6289
+ "component": "component:ds-select",
6290
+ "reason": "Select keeps a larger one-of-many choice set compact."
6291
+ }
6580
6292
  ],
6581
- "patterns": [
6582
- "pattern:application-shell",
6583
- "pattern:shell-page"
6293
+ "commonlyComposedWith": [
6294
+ "component:ds-field",
6295
+ "component:ds-text"
6584
6296
  ],
6585
6297
  "accessibility": [
6586
- "Keep primary destinations in PanelNav and secondary route sections in BarNav.",
6587
- "Ensure the default content region contains the page's single main landmark.",
6588
- "Keep PanelNav, BarNav, and PanelTools-compatible chrome available in desktop and tablet compositions and the persistent mobile bar available below 768px.",
6589
- "Do not override browser keyboard chords when enabling shell shortcuts.",
6590
- "Require Search and Help as the minimum PanelTools actions and provide accessible labels for every tool.",
6591
- "Preserve focus and accessible names across navigation, collapse, overflow, and responsive presentation changes."
6298
+ "The host exposes radiogroup semantics and requires an accessible group name from aria-label or aria-labelledby.",
6299
+ "Each visible option exposes radio semantics, its checked state, its label text, and any inactive state.",
6300
+ "Arrow keys move and select through active options; Home and End select the first and last active options; Space and Enter select the focused option.",
6301
+ "Roving tabindex keeps one active option in the tab order, preferring the selected option."
6592
6302
  ],
6593
6303
  "states": [
6594
- "Render exactly one ShellApp as the workspace root and never nest it.",
6595
- "PanelNav, BarNav, and ShellTools are the responsive shell regions; ShellTools contains at least Search and Help even when no additional product tools apply.",
6596
- "The application router owns the current route, authorization filtering, Dashboard or Settings context, destination collections, section collections, and localized content labels.",
6597
- "ShellApp propagates navStyle and resolved responsive mode and coordinates layout, gradient alignment, transitions, metrics, shortcuts, and mobile-stage visibility.",
6598
- "The application controls mobileDestination and mobileNavigationOpen and keeps router state independent from global tool-surface changes.",
6599
- "Set gradientPreset to the single resolved global chrome preference: neutral by default, none for solid chrome, or cool, neutral, warm, and fresh for token-based washes.",
6600
- "The application owns gradient preference persistence, cross-tab synchronization, and server or account precedence; ShellApp owns rendering the resolved preset across authenticated routes.",
6601
- "Dashboard represents day-to-day operational work while Settings represents administrative and configuration work; route state selects the context.",
6602
- "Update PanelNav groups, BarNav tabs and heading, navStyle, basePath, and currentUrl atomically from one resolved route state.",
6603
- "BarNav remains present: it shows route-section tabs when available and the active PanelNav destination label as heading otherwise.",
6604
- "Render one ShellPage as the default-slot child for each standard routed page; ShellApp owns the content scroller while ShellPage owns page header stickiness and content inset.",
6605
- "The application filters unauthorized destinations, sections, and tools before passing them into shell components."
6304
+ "Unchecked circles use a tertiary-foreground inset stroke: 1.25px at md, 1px at sm, and 0.75px at xs.",
6305
+ "Selected circles remove the border, use a brand fill, and draw a centered on-bold foreground dot sized 8px at md, 6px at sm, and 4px at xs.",
6306
+ "Sizes are md with a 16px circle in a 20px placement, sm with a 12px circle in a 16px placement, and xs with an 8px circle in a 12px placement.",
6307
+ "The initial value is restored by native form reset; the selected value submits under name and a required set is invalid until one active option is selected."
6606
6308
  ],
6607
6309
  "responsiveBehavior": [
6608
- "ShellApp owns the fixed system breakpoints and resolves desktop at 1200px and wider, tablet from 768px through 1199px, and mobile below 768px.",
6609
- "On desktop, PanelNav defaults expanded, permits user collapse or expansion, and respects the locally persisted desktop preference.",
6610
- "On tablet, ShellApp keeps PanelNav permanently collapsed and prevents user expansion without overwriting the desktop preference.",
6611
- "On mobile, ShellApp hides and inerts PanelNav and BarNav, uses a solid primary stage, and composes MobileNav, MobileSectionNav, ShellTools, and the persistent five-item MobileBar.",
6612
- "Mobile global surfaces conceal and inert the routed workspace without unmounting it, preserving nested routes and scroll state.",
6613
- "Keep PanelNav width, BarNav height, PanelTools chrome, and main-content origin stable except during intentional responsive or collapse transitions.",
6614
- "The bottom bar remains visible at all route and tool depths in the foundation release."
6310
+ "Choose size from the density of the containing form or settings row.",
6311
+ "Prefer vertical layout when labels may wrap or horizontal space is constrained; horizontal layout is appropriate for short labels in a small set."
6615
6312
  ],
6616
6313
  "frameworkCaveats": {
6617
6314
  "customElements": [
6618
- "Assign complex navigation and tool collections as JavaScript properties on the slotted components.",
6619
- "Stamp route-derived nav-style before components connect when deterministic first paint is required."
6315
+ "Assign options as a JavaScript property, set value as a property for application state updates, and listen for dsChange.",
6316
+ "Use the form attribute on the host when associating a radio set rendered outside its owning form."
6620
6317
  ],
6621
6318
  "react": [
6622
- "Use generated wrappers and preserve native slot names for desktop navigation, responsive tools, mobile navigation, and main content.",
6623
- "Resolve all shell inputs from one router state before rendering the composition."
6319
+ "Use DsRadio, pass options as an array, and handle onDsChange; value is mutable and updates after user selection."
6624
6320
  ],
6625
6321
  "angular": [
6626
- "Use generated standalone adapters and preserve slot attributes in templates.",
6627
- "Bind complex inputs as properties and update navigation inputs atomically from one resolved router state.",
6628
- "Bind both nav-style attributes and properties when deterministic first paint is required."
6322
+ "Use DsRadio with options and value bindings plus dsChange, or import the generated radio value accessor with the component adapter."
6629
6323
  ]
6630
6324
  },
6631
6325
  "references": [
6632
6326
  {
6633
- "label": "Component guide",
6634
- "path": "src/wc/components/ShellApp/ShellApp.mdx"
6635
- },
6636
- {
6637
- "label": "Executable Storybook composition",
6638
- "path": "src/wc/components/ShellApp/ShellApp.stories.ts"
6639
- },
6640
- {
6641
- "label": "Framework integration",
6642
- "path": "docs/framework-integration.md"
6327
+ "label": "Storybook examples",
6328
+ "path": "src/wc/components/Radio/Radio.stories.ts"
6643
6329
  },
6644
6330
  {
6645
- "label": "Application shell contract",
6646
- "path": "agent/patterns/application-shell/pattern.agent.json"
6331
+ "label": "Cross-browser form and accessibility coverage",
6332
+ "path": "tests/e2e/forms.spec.ts"
6647
6333
  }
6648
6334
  ]
6649
6335
  },
6650
6336
  "api": {
6651
6337
  "props": {
6652
- "gradientPreset": {
6653
- "type": "ShellGradientPreset",
6338
+ "ariaLabel": {
6339
+ "type": "string | null",
6654
6340
  "required": false
6655
6341
  },
6656
- "mobileDestination": {
6657
- "type": "ShellMobileDestination",
6342
+ "ariaLabelledby": {
6343
+ "type": "string | undefined",
6344
+ "required": false
6345
+ },
6346
+ "direction": {
6347
+ "type": "'vertical' | 'horizontal'",
6658
6348
  "required": false
6659
6349
  },
6660
- "mobileNavigationOpen": {
6350
+ "disabled": {
6661
6351
  "type": "boolean",
6662
6352
  "required": false
6663
6353
  },
6664
- "navStyle": {
6665
- "type": "NavChromeStyle",
6354
+ "form": {
6355
+ "type": "string | undefined",
6666
6356
  "required": false
6667
6357
  },
6668
- "shortcutsEnabled": {
6358
+ "isInactive": {
6669
6359
  "type": "boolean",
6670
6360
  "required": false
6671
- }
6672
- },
6673
- "events": [
6361
+ },
6362
+ "name": {
6363
+ "type": "string | undefined",
6364
+ "required": false
6365
+ },
6366
+ "options": {
6367
+ "type": "RadioOption[]",
6368
+ "required": false
6369
+ },
6370
+ "required": {
6371
+ "type": "boolean",
6372
+ "required": false
6373
+ },
6374
+ "requiredMessage": {
6375
+ "type": "string",
6376
+ "required": false
6377
+ },
6378
+ "size": {
6379
+ "type": "RadioSize",
6380
+ "required": false
6381
+ },
6382
+ "value": {
6383
+ "type": "string",
6384
+ "required": false
6385
+ }
6386
+ },
6387
+ "events": [
6674
6388
  {
6675
- "name": "dsResponsiveModeChange",
6676
- "detail": "{ mode: ShellResponsiveMode }"
6389
+ "name": "dsChange",
6390
+ "detail": "string"
6677
6391
  }
6678
6392
  ],
6679
6393
  "slots": []
6680
6394
  },
6681
6395
  "exports": {
6682
- "customElement": "ds-shell-app",
6683
- "react": "DsShellApp",
6684
- "angular": "DsShellApp"
6396
+ "customElement": "ds-radio",
6397
+ "react": "DsRadio",
6398
+ "angular": "DsRadio"
6685
6399
  },
6686
6400
  "dependencies": [
6687
6401
  "@ds-mo/ui",
6688
6402
  "@ds-mo/tokens"
6689
6403
  ],
6690
- "componentDependencies": []
6404
+ "componentDependencies": [
6405
+ "text"
6406
+ ]
6691
6407
  },
6692
6408
  {
6693
- "id": "component:ds-shell-gradient-picker",
6694
- "tag": "ds-shell-gradient-picker",
6695
- "name": "shell-gradient-picker",
6696
- "title": "ShellGradientPicker",
6697
- "summary": "Deprecated compatibility wrapper that maps the fixed ShellApp wash presets into SwatchPicker.",
6409
+ "id": "component:ds-scroll-overlay",
6410
+ "tag": "ds-scroll-overlay",
6411
+ "name": "scroll-overlay",
6412
+ "title": "ScrollOverlay",
6413
+ "summary": "Generic scroll owner for content that moves behind a persistent footer action or composer with an always-active alpha fade.",
6698
6414
  "intentStatus": "complete",
6699
6415
  "intent": {
6700
- "audience": "specialized",
6701
- "status": "deprecated",
6702
- "replacedBy": "component:ds-swatch-picker",
6703
- "replacementReason": "SwatchPicker now owns the same accessible interaction with a generic option model that supports both flat colors and gradients.",
6704
- "summary": "Deprecated compatibility wrapper that maps the fixed ShellApp wash presets into SwatchPicker.",
6416
+ "audience": "general",
6417
+ "status": "experimental",
6418
+ "summary": "Generic scroll owner for content that moves behind a persistent footer action or composer with an always-active alpha fade.",
6705
6419
  "useWhen": [
6706
- "Adding the Appearance or Theme section to the application's user or account menu.",
6707
- "Users must choose the global ShellApp chrome treatment from none, cool, neutral, warm, or fresh."
6420
+ "A bounded region owns scrolling while footer actions remain overlaid and continuously visible.",
6421
+ "The final content must clear a live-height footer while earlier content can move behind it."
6708
6422
  ],
6709
6423
  "avoidWhen": [
6710
- "Choosing semantic intent, page background, chart, content, or brand colors.",
6711
- "Building an arbitrary gradient editor or allowing custom gradient values.",
6712
- "A picker already exists for the application; provide exactly one canonical preference location.",
6713
- "Rendering an individual swatch outside the complete picker."
6714
- ],
6715
- "alternatives": [
6716
- {
6717
- "when": "The user is selecting the application light, dark, or system color mode.",
6718
- "component": "component:ds-menu",
6719
- "reason": "Color mode is a separate appearance preference and should use ordinary menu selection rows."
6720
- }
6424
+ "The footer belongs in normal document flow rather than overlaying content.",
6425
+ "Another component already owns scrolling and cannot delegate its scrollport to this component."
6721
6426
  ],
6722
6427
  "commonlyComposedWith": [
6723
- "component:ds-shell-app",
6724
- "component:ds-menu"
6725
- ],
6726
- "patterns": [
6727
- "pattern:application-shell"
6428
+ "component:ds-button-filled",
6429
+ "component:ds-message-composer"
6728
6430
  ],
6729
6431
  "accessibility": [
6730
- "Provide a localized groupLabel that describes the shell appearance choice.",
6731
- "Treat the presets as one radio group with one Tab stop; Arrow keys, Home, and End move and select within the group.",
6732
- "Keep the visible compact swatches and their accessible preset names; do not rely on color alone for assistive technology."
6432
+ "Provide scrollLabel when the scrollport needs its own named, keyboard-focusable region.",
6433
+ "Keep footer actions keyboard accessible and explicitly named; the fade is decorative and never intercepts pointer input."
6733
6434
  ],
6734
6435
  "states": [
6735
- "Neutral is the default preset; none renders solid shell chrome without a wash.",
6736
- "Cool, neutral, warm, and fresh use design tokens and automatically adapt to the active light or dark color theme.",
6737
- "Apply dsChange immediately to ShellApp.gradientPreset and keep the containing account menu open.",
6738
- "The application owns local persistence, cross-tab synchronization, and server or account preference precedence; the picker owns only selection UI and events.",
6739
- "Treat the fixed preset union as the only supported values and do not construct custom gradients."
6436
+ "The alpha mask remains active at every scroll position and moves in content coordinates so it stays pinned behind the footer without masking native scrollbars.",
6437
+ "The component measures the complete overlay for end clearance, measures its visible child for fade depth, and begins the fade 8px before that visible content.",
6438
+ "An md 32px footer action with 8px bottom inset therefore produces a 48px fade; variable-height composers produce a correspondingly taller measured fade."
6740
6439
  ],
6741
6440
  "responsiveBehavior": [
6742
- "Keep the compact picker in the user or account appearance menu on supported desktop and tablet shell compositions.",
6743
- "The future mobile account surface may present the same preference differently."
6441
+ "The scrollport and overlay fill the available width and height; the owner supplies responsive sizing and overlay insets."
6744
6442
  ],
6745
6443
  "frameworkCaveats": {
6746
6444
  "customElements": [
6747
- "Listen for dsChange, resolve application preference precedence, and assign the result to the single ShellApp gradientPreset property."
6445
+ "Place scrollable content in the default slot and one footer wrapper in the overlay slot; use dsScroll only when the application needs position data."
6748
6446
  ],
6749
6447
  "react": [
6750
- "Use the generated wrapper and handle onDsChange without closing the containing account menu."
6448
+ "Use DsScrollOverlay with ordinary children plus an element carrying slot=\"overlay\"."
6751
6449
  ],
6752
6450
  "angular": [
6753
- "Bind value to the resolved preference and handle dsChange to update application state."
6451
+ "Import DsScrollOverlay and project the persistent footer wrapper with slot=\"overlay\"."
6754
6452
  ]
6755
6453
  },
6756
6454
  "references": [
6757
6455
  {
6758
- "label": "Replacement stories",
6759
- "path": "src/wc/components/SwatchPicker/SwatchPicker.stories.ts"
6760
- },
6761
- {
6762
- "label": "ShellApp gradient contract",
6763
- "path": "src/wc/components/ShellApp/ShellApp.mdx"
6764
- },
6765
- {
6766
- "label": "Application shell composition",
6767
- "path": "agent/patterns/application-shell/pattern.agent.json"
6456
+ "label": "Storybook examples",
6457
+ "path": "src/wc/components/ScrollOverlay/ScrollOverlay.stories.ts"
6768
6458
  }
6769
6459
  ]
6770
6460
  },
6771
6461
  "api": {
6772
6462
  "props": {
6773
- "groupLabel": {
6774
- "type": "string",
6775
- "required": false
6776
- },
6777
- "value": {
6778
- "type": "ShellGradientPreset",
6463
+ "scrollLabel": {
6464
+ "type": "string | undefined",
6779
6465
  "required": false
6780
6466
  }
6781
6467
  },
6782
6468
  "events": [
6783
6469
  {
6784
- "name": "dsChange",
6785
- "detail": "ShellGradientPreset"
6470
+ "name": "dsScroll",
6471
+ "detail": "ScrollOverlayScrollDetail"
6786
6472
  }
6787
6473
  ],
6788
6474
  "slots": []
6789
6475
  },
6790
6476
  "exports": {
6791
- "customElement": "ds-shell-gradient-picker",
6792
- "react": "DsShellGradientPicker",
6793
- "angular": "DsShellGradientPicker"
6477
+ "customElement": "ds-scroll-overlay",
6478
+ "react": "DsScrollOverlay",
6479
+ "angular": "DsScrollOverlay"
6794
6480
  },
6795
6481
  "dependencies": [
6796
6482
  "@ds-mo/ui",
6797
6483
  "@ds-mo/tokens"
6798
6484
  ],
6799
- "componentDependencies": [
6800
- "swatch-picker"
6801
- ]
6485
+ "componentDependencies": []
6802
6486
  },
6803
6487
  {
6804
- "id": "component:ds-shell-gradient-swatch",
6805
- "tag": "ds-shell-gradient-swatch",
6806
- "name": "shell-gradient-swatch",
6807
- "title": "ShellGradientSwatch",
6808
- "summary": "Deprecated internal compatibility component for one legacy ShellApp gradient swatch.",
6488
+ "id": "component:ds-select",
6489
+ "tag": "ds-select",
6490
+ "name": "select",
6491
+ "title": "Select",
6492
+ "summary": "Form-associated single-value select with listbox semantics, local search, rich flat options, grouped sections, loading, clearing, and surface-aware trigger chrome.",
6809
6493
  "intentStatus": "complete",
6810
6494
  "intent": {
6811
- "audience": "internal",
6812
- "status": "deprecated",
6813
- "replacedBy": "component:ds-swatch-picker",
6814
- "replacementReason": "SwatchPicker renders its option buttons internally so an individually published radio swatch is no longer needed.",
6815
- "summary": "Deprecated internal compatibility component for one legacy ShellApp gradient swatch.",
6495
+ "audience": "general",
6496
+ "status": "stable",
6497
+ "summary": "Form-associated single-value select with listbox semantics, local search, rich flat options, grouped sections, loading, clearing, and surface-aware trigger chrome.",
6816
6498
  "useWhen": [
6817
- "Maintaining or extending ShellGradientPicker inside CompoMo."
6499
+ "The user must choose one value from a finite set.",
6500
+ "The option set benefits from local search, subtext, prefix icons, grouping, or disabled choices.",
6501
+ "The choice set has more than roughly 20 options, comes from a user-managed listing, or represents a large domain such as addresses where search materially improves retrieval.",
6502
+ "The selected value must participate in native, Angular, or React form state."
6818
6503
  ],
6819
6504
  "avoidWhen": [
6820
- "Building application UI directly; use ShellGradientPicker instead.",
6821
- "Selecting semantic, brand, chart, page, or arbitrary gradient colors.",
6822
- "Creating a partial or custom set of shell gradient choices."
6505
+ "Several values may be selected at once.",
6506
+ "The rows perform commands rather than choosing a form value.",
6507
+ "The choices form a hierarchy with expandable parents."
6823
6508
  ],
6824
6509
  "alternatives": [
6825
6510
  {
6826
- "when": "An application needs the supported global shell appearance control.",
6827
- "component": "component:ds-swatch-picker",
6828
- "reason": "SwatchPicker provides the complete radio-group semantics, keyboard behavior, generic previews, and selection event."
6511
+ "when": "Several independent values may be selected.",
6512
+ "component": "component:ds-select-multi",
6513
+ "reason": "SelectMulti owns array values, multi-selection semantics, and count presentation."
6514
+ },
6515
+ {
6516
+ "when": "The popup contains commands or state-changing actions.",
6517
+ "component": "component:ds-menu",
6518
+ "reason": "Menu uses action-menu roles and command-focused keyboard behavior."
6519
+ },
6520
+ {
6521
+ "when": "A small set of choices should remain visible.",
6522
+ "component": "component:ds-radio",
6523
+ "reason": "Prefer Radio for roughly two to five mutually exclusive choices when the available space allows all choices to remain visible."
6829
6524
  }
6830
6525
  ],
6831
6526
  "commonlyComposedWith": [
6832
- "component:ds-swatch-picker"
6527
+ "component:ds-text",
6528
+ "component:ds-icon",
6529
+ "component:ds-empty-state",
6530
+ "component:ds-loader"
6833
6531
  ],
6834
6532
  "accessibility": [
6835
- "Keep radio semantics, aria-checked state, and a preset-specific accessible name on the internal button.",
6836
- "Let ShellGradientPicker manage the roving tab stop and group keyboard navigation.",
6837
- "Do not expose an unlabeled color-only choice."
6533
+ "In forms, provide a persistent visible external field label; placeholder text is guidance and must not be the field's only label. In a compact filter bar, the trigger's visible text may supply the accessible name.",
6534
+ "The trigger uses combobox semantics and the popup uses listbox and option semantics; do not replace them with menu roles.",
6535
+ "Disabled options remain visible, expose aria-disabled, and are skipped by keyboard navigation and typeahead.",
6536
+ "Keyboard navigation keeps the aria-activedescendant option scrolled into the visible listbox viewport.",
6537
+ "Selected options rely on active fill and foreground treatment without a redundant trailing check icon.",
6538
+ "Local search moves focus into the search field while preserving the active option through aria-activedescendant.",
6539
+ "Use errorMessage with error so the trigger is described by the rendered alert."
6838
6540
  ],
6839
6541
  "states": [
6840
- "Preset determines the token-based preview; selected determines radio state and selected visuals.",
6841
- "The selected swatch owns the radio group's single tab stop while ShellGradientPicker coordinates selection and focus movement.",
6842
- "isInactive disables interaction but does not remove the accessible name."
6542
+ "Value is controlled through the mutable value property; dsChange reports user selection and clearing.",
6543
+ "Required Selects begin without an automatic selection and require the user to make an explicit choice; do not preselect the first option merely to satisfy validity.",
6544
+ "When allowClear is enabled, the clear affordance appears only after a value exists. Clearing is valid for optional and required fields; a required field becomes invalid until the user selects again.",
6545
+ "Clearing emits dsChange with an empty string and dsClear, keeps the popup open, and restores useful focus.",
6546
+ "Loading keeps the trigger visible, replaces its prefix icon, marks the control busy, and makes selection interaction temporarily unavailable without presenting the control as inactive.",
6547
+ "The trigger label stays left-aligned at every width. The default size is md in both forms and filter bars; smaller sizes require an explicit density need.",
6548
+ "Use option icons only when they help users differentiate choices. Icons render only when every option in the complete list provides one; mixed icon data falls back to the text-only row layout.",
6549
+ "Create sections only for categories that are meaningful to customers, not merely to break a long list into arbitrary chunks.",
6550
+ "When any option supplies subtext, every row uses the same subtext structure and missing values render an em dash. Subtext should disambiguate or add decision-helpful information.",
6551
+ "Option labels and the selected trigger label stay on one line and truncate when constrained. Option subtext may wrap to at most two lines.",
6552
+ "The optional prefix icon and chevron always use the parent surface's secondary foreground color, including when a selected value promotes the label to primary.",
6553
+ "The shared popup search control stays md at every trigger size, using body-medium text, a 20px icon, and the same internal spacing as a borderless Select trigger. Its container uses menu-item padding on every side and owns a 1px bottom divider that becomes a 1.5px bold-brand stroke while search has focus. Search placeholder text is secondary at rest and quaternary while focused because it becomes decorative once the editable field is active.",
6554
+ "When search contains text, the shared control shows a rounded sm icon-only ButtonUnfilled with the CrossCircle icon and no border. It clears the local term, stays hidden for an empty term, and returns focus to search.",
6555
+ "The shared clear footer mirrors the search region's sizing: menu-item padding surrounds an md-height borderless row, and the Clear label uses the same row and label insets as option text. The outer footer owns a 1px top divider.",
6556
+ "An empty filtered list composes the message-only body variant of EmptyState. Keep the default neutral no-results message unless localized product guidance makes the outcome clearer.",
6557
+ "Enable searchable for more than roughly 20 options, user-managed listings, large domains such as addresses, or sets users cannot efficiently scan. Local matching includes option labels, subtext, and section headings; the owner resolves remote data before assigning options.",
6558
+ "Validation timing belongs to the form owner and may be immediate or deferred until blur or submit; the Select exposes validity and error presentation without imposing that policy.",
6559
+ "The error trigger uses a 1.5px bold-negative inset stroke so invalid state remains distinguishable from the normal 1px border without changing control geometry.",
6560
+ "An initially empty option set is not an expected Select use case. The no-results state describes a search with no matches, not a source with no choices.",
6561
+ "Use options for a flat list or sections for grouped choices; when sections are present they take precedence.",
6562
+ "The background prop describes the actual parent surface and uses the same surface set as ButtonUnfilled."
6843
6563
  ],
6844
6564
  "responsiveBehavior": [
6845
- "Preserve the fixed compact swatch geometry and let ShellGradientPicker own layout."
6565
+ "Use width fill for form fields and width hug for compact filter bars. Override those defaults only when the owning layout has a clear constraint.",
6566
+ "The popup matches the trigger minimum width, may grow for content, and clamps to the viewport.",
6567
+ "Long option collections scroll inside the popup; virtualization and remote search are not part of this component."
6846
6568
  ],
6847
6569
  "frameworkCaveats": {
6848
6570
  "customElements": [
6849
- "Do not instantiate this internal primitive in consuming applications."
6571
+ "Assign options and sections through JavaScript properties because arrays and objects cannot be represented safely as attributes."
6850
6572
  ],
6851
6573
  "react": [
6852
- "Use DsShellGradientPicker rather than the generated swatch wrapper."
6574
+ "Pass options or sections as wrapper props and handle onDsChange, onDsClear, and onDsOpenChange."
6853
6575
  ],
6854
6576
  "angular": [
6855
- "Use DsShellGradientPicker rather than importing DsShellGradientSwatch."
6577
+ "Import DsSelect and SelectValueAccessor when integrating with Angular Forms; bind options and sections as properties."
6856
6578
  ]
6857
6579
  },
6858
6580
  "references": [
6859
6581
  {
6860
- "label": "Parent picker",
6861
- "path": "src/wc/components/ShellGradientPicker/ShellGradientPicker.tsx"
6582
+ "label": "Storybook examples",
6583
+ "path": "src/wc/components/Select/Select.stories.ts"
6584
+ },
6585
+ {
6586
+ "label": "Selection patterns",
6587
+ "path": "src/docs/SelectionPatterns.mdx"
6862
6588
  }
6863
6589
  ]
6864
6590
  },
6865
6591
  "api": {
6866
6592
  "props": {
6867
- "ariaLabel": {
6868
- "type": "string | null",
6593
+ "activeFill": {
6594
+ "type": "boolean",
6869
6595
  "required": false
6870
6596
  },
6871
- "isInactive": {
6597
+ "allowClear": {
6872
6598
  "type": "boolean",
6873
6599
  "required": false
6874
6600
  },
6875
- "preset": {
6876
- "type": "ShellGradientPreset",
6601
+ "ariaDescribedby": {
6602
+ "type": "string | undefined",
6877
6603
  "required": false
6878
6604
  },
6879
- "selected": {
6880
- "type": "boolean",
6605
+ "ariaLabel": {
6606
+ "type": "string | null",
6881
6607
  "required": false
6882
- }
6608
+ },
6609
+ "ariaLabelledby": {
6610
+ "type": "string | undefined",
6611
+ "required": false
6612
+ },
6613
+ "background": {
6614
+ "type": "SelectBackground | undefined",
6615
+ "required": false
6616
+ },
6617
+ "clearLabel": {
6618
+ "type": "string",
6619
+ "required": false
6620
+ },
6621
+ "disabled": {
6622
+ "type": "boolean",
6623
+ "required": false
6624
+ },
6625
+ "error": {
6626
+ "type": "boolean",
6627
+ "required": false
6628
+ },
6629
+ "errorMessage": {
6630
+ "type": "string | undefined",
6631
+ "required": false
6632
+ },
6633
+ "hasBorder": {
6634
+ "type": "boolean",
6635
+ "required": false
6636
+ },
6637
+ "icon": {
6638
+ "type": "string | undefined",
6639
+ "required": false
6640
+ },
6641
+ "inputId": {
6642
+ "type": "string | undefined",
6643
+ "required": false
6644
+ },
6645
+ "isInactive": {
6646
+ "type": "boolean",
6647
+ "required": false
6648
+ },
6649
+ "isLoading": {
6650
+ "type": "boolean",
6651
+ "required": false
6652
+ },
6653
+ "loadingLabel": {
6654
+ "type": "string",
6655
+ "required": false
6656
+ },
6657
+ "name": {
6658
+ "type": "string | undefined",
6659
+ "required": false
6660
+ },
6661
+ "noResultsText": {
6662
+ "type": "string",
6663
+ "required": false
6664
+ },
6665
+ "open": {
6666
+ "type": "boolean",
6667
+ "required": false
6668
+ },
6669
+ "options": {
6670
+ "type": "SelectOption[]",
6671
+ "required": false
6672
+ },
6673
+ "placeholder": {
6674
+ "type": "string",
6675
+ "required": false
6676
+ },
6677
+ "required": {
6678
+ "type": "boolean",
6679
+ "required": false
6680
+ },
6681
+ "requiredMessage": {
6682
+ "type": "string",
6683
+ "required": false
6684
+ },
6685
+ "searchPlaceholder": {
6686
+ "type": "string",
6687
+ "required": false
6688
+ },
6689
+ "searchable": {
6690
+ "type": "boolean",
6691
+ "required": false
6692
+ },
6693
+ "sections": {
6694
+ "type": "SelectSection[]",
6695
+ "required": false
6696
+ },
6697
+ "size": {
6698
+ "type": "SelectSize",
6699
+ "required": false
6700
+ },
6701
+ "value": {
6702
+ "type": "string",
6703
+ "required": false
6704
+ },
6705
+ "width": {
6706
+ "type": "SelectWidth",
6707
+ "required": false
6708
+ }
6883
6709
  },
6884
6710
  "events": [
6885
6711
  {
6886
- "name": "dsSelect",
6887
- "detail": "ShellGradientPreset"
6712
+ "name": "dsChange",
6713
+ "detail": "string"
6714
+ },
6715
+ {
6716
+ "name": "dsClear",
6717
+ "detail": "void"
6718
+ },
6719
+ {
6720
+ "name": "dsOpenChange",
6721
+ "detail": "boolean"
6888
6722
  }
6889
6723
  ],
6890
6724
  "slots": []
6891
6725
  },
6892
6726
  "exports": {
6893
- "customElement": "ds-shell-gradient-swatch",
6894
- "react": "DsShellGradientSwatch",
6895
- "angular": "DsShellGradientSwatch"
6727
+ "customElement": "ds-select",
6728
+ "react": "DsSelect",
6729
+ "angular": "DsSelect"
6896
6730
  },
6897
6731
  "dependencies": [
6898
6732
  "@ds-mo/ui",
6899
- "@ds-mo/tokens"
6733
+ "@ds-mo/tokens",
6734
+ "@ds-mo/icons"
6900
6735
  ],
6901
- "componentDependencies": []
6736
+ "componentDependencies": [
6737
+ "button-unfilled",
6738
+ "empty-state",
6739
+ "icon",
6740
+ "loader",
6741
+ "text",
6742
+ "tooltip"
6743
+ ]
6902
6744
  },
6903
6745
  {
6904
- "id": "component:ds-shell-mobile-bar",
6905
- "tag": "ds-shell-mobile-bar",
6906
- "name": "shell-mobile-bar",
6907
- "title": "ShellMobileBar",
6908
- "summary": "Persistent mobile shell navigation for Menu, the router-derived current area, Search, Agents, and Inbox.",
6746
+ "id": "component:ds-select-multi",
6747
+ "tag": "ds-select-multi",
6748
+ "name": "select-multi",
6749
+ "title": "SelectMulti",
6750
+ "summary": "Form-associated multi-value select with a persistent trigger label, inline selected count, local search, rich flat options, grouped sections, loading, and clear-all behavior.",
6909
6751
  "intentStatus": "complete",
6910
6752
  "intent": {
6911
- "audience": "specialized",
6912
- "status": "experimental",
6913
- "summary": "Persistent mobile shell navigation for Menu, the router-derived current area, Search, Agents, and Inbox.",
6753
+ "audience": "general",
6754
+ "status": "stable",
6755
+ "summary": "Form-associated multi-value select with a persistent trigger label, inline selected count, local search, rich flat options, grouped sections, loading, and clear-all behavior.",
6914
6756
  "useWhen": [
6915
- "ShellApp is rendering its dedicated below-768px application composition."
6757
+ "The user may choose several independent values from one finite set.",
6758
+ "A compact trigger should summarize selection with the field label and a count.",
6759
+ "The option set benefits from local search, subtext, grouping, or disabled choices.",
6760
+ "The choice set has more than roughly 20 options, comes from a user-managed listing, or represents a large domain where search materially improves retrieval."
6916
6761
  ],
6917
6762
  "avoidWhen": [
6918
- "Rendering desktop or tablet shell chrome.",
6919
- "An arbitrary set of product tabs is required."
6763
+ "Exactly one value may be selected.",
6764
+ "Selected values must remain individually removable as persistent tags outside the popup.",
6765
+ "The choices form a hierarchy with cascading parent selection.",
6766
+ "The customer task benefits more from keeping every choice and checkbox directly visible; choose between SelectMulti and a visible checkbox list from the use-case context rather than a fixed option-count threshold."
6920
6767
  ],
6921
- "commonlyComposedWith": [
6922
- "component:ds-shell-app"
6768
+ "alternatives": [
6769
+ {
6770
+ "when": "Exactly one value may be selected.",
6771
+ "component": "component:ds-select",
6772
+ "reason": "Select owns scalar form value and single-select listbox behavior."
6773
+ },
6774
+ {
6775
+ "when": "The popup contains actions rather than values.",
6776
+ "component": "component:ds-menu",
6777
+ "reason": "Menu uses command semantics and closes according to action-menu expectations."
6778
+ }
6923
6779
  ],
6924
- "patterns": [
6925
- "pattern:application-shell"
6780
+ "commonlyComposedWith": [
6781
+ "component:ds-text",
6782
+ "component:ds-checkbox",
6783
+ "component:ds-empty-state",
6784
+ "component:ds-loader"
6926
6785
  ],
6927
6786
  "accessibility": [
6928
- "Every item keeps a visible label and accessible name.",
6929
- "Only the active destination exposes aria-current; Menu exposes its controlled pane through aria-expanded."
6787
+ "In forms, provide a persistent visible external field label. In a compact filter bar, the trigger's visible persistent label and count may supply the accessible name.",
6788
+ "The popup is a listbox with aria-multiselectable and every option exposes its independent aria-selected state.",
6789
+ "Disabled options expose aria-disabled and are skipped by keyboard navigation and typeahead.",
6790
+ "Keyboard navigation keeps the aria-activedescendant option scrolled into the visible listbox viewport.",
6791
+ "Each row uses a medium-size presentation-only ds-checkbox indicator; multi-select option rows never add a prefix icon alongside it, and the option remains the sole selection semantic and interaction target.",
6792
+ "The trigger keeps its field label visible and appends the current selected count; an explicit aria-label or aria-labelledby remains the authoritative accessible name when supplied.",
6793
+ "Use errorMessage with error so the trigger is described by the rendered alert."
6930
6794
  ],
6931
6795
  "states": [
6932
- "The item order is fixed: Menu, current area, Search, Agents, Inbox.",
6933
- "Reselecting an active destination does not reset its nested state."
6796
+ "Values is a controlled JavaScript array; dsChange emits a new array after each user toggle.",
6797
+ "Required SelectMulti controls begin without an automatic selection and require the user to make an explicit choice.",
6798
+ "Selecting an option keeps the popup open so additional values can be toggled.",
6799
+ "The trigger label stays left-aligned at every width; every option row uses the same leading medium Checkbox indicator. The default control size is md in both forms and filter bars.",
6800
+ "The selected count always follows the persistent label as plain text separated by a centered dot, including for one selection, and counts every selected value even when search or grouping hides it. Never replace the count with selected option names.",
6801
+ "Create sections only for categories that are meaningful to customers, not merely to break a long list into arbitrary chunks.",
6802
+ "When any option supplies subtext, every row uses the same subtext structure and missing values render an em dash. Subtext should disambiguate or add decision-helpful information.",
6803
+ "Option labels stay on one line and truncate when constrained. Option subtext may wrap to at most two lines.",
6804
+ "The optional prefix icon and chevron always use the parent surface's secondary foreground color, including when selection promotes the label and count to primary.",
6805
+ "The shared popup search control stays md at every trigger size, using body-medium text, a 20px icon, and the same internal spacing as a borderless Select trigger. Its container uses menu-item padding on every side and owns a 1px bottom divider that becomes a 1.5px bold-brand stroke while search has focus. Search placeholder text is secondary at rest and quaternary while focused because it becomes decorative once the editable field is active.",
6806
+ "When search contains text, the shared control shows a rounded sm icon-only ButtonUnfilled with the Cross icon and no border. It clears the local term, stays hidden for an empty term, and returns focus to search.",
6807
+ "The shared summary-and-clear footer mirrors the search region's sizing: menu-item padding surrounds an md-height borderless row, and both texts use the same row and label insets as option text. The outer footer owns a 1px top divider.",
6808
+ "An empty filtered list composes the message-only body variant of EmptyState. Keep the default neutral no-results message unless localized product guidance makes the outcome clearer.",
6809
+ "Enable searchable for more than roughly 20 options, user-managed listings, large domains such as addresses, or sets users cannot efficiently scan. Local matching includes option labels, subtext, and section headings; the owner resolves remote data before assigning options.",
6810
+ "When allowClear is enabled, clear-all appears only after at least one value exists. Clearing is valid for optional and required fields; a required field becomes invalid until the user selects again.",
6811
+ "Clear-all emits an empty dsChange and dsClear while preserving useful popup or search focus.",
6812
+ "Loading keeps the trigger visible, marks the control busy, and makes selection interaction temporarily unavailable without presenting the control as inactive.",
6813
+ "SelectMulti has no maximum-selection behavior; every available non-inactive option may be selected.",
6814
+ "Validation timing belongs to the form owner and may be immediate or deferred until blur or submit; the component exposes validity and error presentation without imposing that policy.",
6815
+ "The error trigger uses a 1.5px bold-negative inset stroke so invalid state remains distinguishable from the normal 1px border without changing control geometry.",
6816
+ "An initially empty option set is not an expected SelectMulti use case. The no-results state describes a search with no matches, not a source with no choices.",
6817
+ "Native form submission emits one entry per selected value under the component name.",
6818
+ "Use options for a flat list or sections for grouped choices. Multi-select option contracts intentionally exclude icons because the leading checkbox owns that row zone; hierarchical parent selection is deferred."
6934
6819
  ],
6935
6820
  "responsiveBehavior": [
6936
- "Render only below the mobile breakpoint and preserve safe-area clearance."
6821
+ "Use width fill for form fields and width hug for compact filter bars; the persistent trigger label avoids variable-width selected labels.",
6822
+ "The popup matches the trigger minimum width, may grow for content, and clamps to the viewport.",
6823
+ "Long option collections scroll inside the popup; virtualization and remote search are not part of this version."
6937
6824
  ],
6825
+ "frameworkCaveats": {
6826
+ "customElements": [
6827
+ "Assign values, options, and sections through JavaScript properties; array values cannot be represented safely as attributes."
6828
+ ],
6829
+ "react": [
6830
+ "Pass values, options, and sections as wrapper props and handle onDsChange, onDsClear, and onDsOpenChange."
6831
+ ],
6832
+ "angular": [
6833
+ "Import DsSelectMulti and SelectMultiValueAccessor when integrating with Angular Forms."
6834
+ ]
6835
+ },
6938
6836
  "references": [
6939
6837
  {
6940
- "label": "Storybook",
6941
- "path": "src/wc/components/ShellMobileBar/ShellMobileBar.stories.ts"
6838
+ "label": "Storybook examples",
6839
+ "path": "src/wc/components/SelectMulti/SelectMulti.stories.ts"
6840
+ },
6841
+ {
6842
+ "label": "Selection patterns",
6843
+ "path": "src/docs/SelectionPatterns.mdx"
6942
6844
  }
6943
6845
  ]
6944
6846
  },
6945
6847
  "api": {
6946
6848
  "props": {
6947
- "activeDestination": {
6948
- "type": "ShellMobileDestination",
6849
+ "activeFill": {
6850
+ "type": "boolean",
6949
6851
  "required": false
6950
6852
  },
6951
- "agentsDot": {
6853
+ "allowClear": {
6952
6854
  "type": "boolean",
6953
6855
  "required": false
6954
6856
  },
6955
- "agentsLabel": {
6857
+ "ariaDescribedby": {
6858
+ "type": "string | undefined",
6859
+ "required": false
6860
+ },
6861
+ "ariaLabel": {
6862
+ "type": "string | null",
6863
+ "required": false
6864
+ },
6865
+ "ariaLabelledby": {
6866
+ "type": "string | undefined",
6867
+ "required": false
6868
+ },
6869
+ "background": {
6870
+ "type": "SelectMultiBackground | undefined",
6871
+ "required": false
6872
+ },
6873
+ "clearLabel": {
6956
6874
  "type": "string",
6957
6875
  "required": false
6958
6876
  },
6959
- "currentArea": {
6960
- "type": "PanelNavItem",
6877
+ "disabled": {
6878
+ "type": "boolean",
6961
6879
  "required": false
6962
6880
  },
6963
- "inboxDot": {
6881
+ "error": {
6882
+ "type": "boolean",
6883
+ "required": false
6884
+ },
6885
+ "errorMessage": {
6886
+ "type": "string | undefined",
6887
+ "required": false
6888
+ },
6889
+ "hasBorder": {
6890
+ "type": "boolean",
6891
+ "required": false
6892
+ },
6893
+ "icon": {
6894
+ "type": "string | undefined",
6895
+ "required": false
6896
+ },
6897
+ "inputId": {
6898
+ "type": "string | undefined",
6899
+ "required": false
6900
+ },
6901
+ "isInactive": {
6902
+ "type": "boolean",
6903
+ "required": false
6904
+ },
6905
+ "isLoading": {
6906
+ "type": "boolean",
6907
+ "required": false
6908
+ },
6909
+ "loadingLabel": {
6910
+ "type": "string",
6911
+ "required": false
6912
+ },
6913
+ "name": {
6914
+ "type": "string | undefined",
6915
+ "required": false
6916
+ },
6917
+ "noResultsText": {
6918
+ "type": "string",
6919
+ "required": false
6920
+ },
6921
+ "open": {
6922
+ "type": "boolean",
6923
+ "required": false
6924
+ },
6925
+ "options": {
6926
+ "type": "SelectMultiOption[]",
6927
+ "required": false
6928
+ },
6929
+ "placeholder": {
6930
+ "type": "string",
6931
+ "required": false
6932
+ },
6933
+ "required": {
6934
+ "type": "boolean",
6935
+ "required": false
6936
+ },
6937
+ "requiredMessage": {
6938
+ "type": "string",
6939
+ "required": false
6940
+ },
6941
+ "searchPlaceholder": {
6942
+ "type": "string",
6943
+ "required": false
6944
+ },
6945
+ "searchable": {
6964
6946
  "type": "boolean",
6965
6947
  "required": false
6966
6948
  },
6967
- "inboxLabel": {
6968
- "type": "string",
6949
+ "sections": {
6950
+ "type": "SelectMultiSection[]",
6951
+ "required": false
6952
+ },
6953
+ "selectedLabel": {
6954
+ "type": "string",
6955
+ "required": false
6956
+ },
6957
+ "size": {
6958
+ "type": "SelectMultiSize",
6959
+ "required": false
6960
+ },
6961
+ "values": {
6962
+ "type": "string[]",
6963
+ "required": false
6964
+ },
6965
+ "width": {
6966
+ "type": "SelectMultiWidth",
6967
+ "required": false
6968
+ }
6969
+ },
6970
+ "events": [
6971
+ {
6972
+ "name": "dsChange",
6973
+ "detail": "string[]"
6974
+ },
6975
+ {
6976
+ "name": "dsClear",
6977
+ "detail": "void"
6978
+ },
6979
+ {
6980
+ "name": "dsOpenChange",
6981
+ "detail": "boolean"
6982
+ }
6983
+ ],
6984
+ "slots": []
6985
+ },
6986
+ "exports": {
6987
+ "customElement": "ds-select-multi",
6988
+ "react": "DsSelectMulti",
6989
+ "angular": "DsSelectMulti"
6990
+ },
6991
+ "dependencies": [
6992
+ "@ds-mo/ui",
6993
+ "@ds-mo/tokens",
6994
+ "@ds-mo/icons"
6995
+ ],
6996
+ "componentDependencies": [
6997
+ "button-unfilled",
6998
+ "checkbox",
6999
+ "empty-state",
7000
+ "icon",
7001
+ "loader",
7002
+ "text",
7003
+ "tooltip"
7004
+ ]
7005
+ },
7006
+ {
7007
+ "id": "component:ds-shell-app",
7008
+ "tag": "ds-shell-app",
7009
+ "name": "shell-app",
7010
+ "title": "ShellApp",
7011
+ "summary": "The single required workspace root for standard authenticated application pages, coordinating primary and secondary navigation, tools chrome, responsive composition, content geometry, shared styling, and shell behavior.",
7012
+ "intentStatus": "complete",
7013
+ "intent": {
7014
+ "audience": "specialized",
7015
+ "status": "stable",
7016
+ "summary": "The single required workspace root for standard authenticated application pages, coordinating primary and secondary navigation, tools chrome, responsive composition, content geometry, shared styling, and shell behavior.",
7017
+ "useWhen": [
7018
+ "Building any standard authenticated product or workspace page with CompoMo.",
7019
+ "PanelNav, BarNav, ShellTools, mobile navigation, page content, shared chrome, responsive behavior, and shell shortcuts must be composed as one application frame.",
7020
+ "Future application templates need the supported base-page composition boundary."
7021
+ ],
7022
+ "avoidWhen": [
7023
+ "Building authentication, onboarding, public, marketing, print, error, or intentionally focused full-screen experiences that require a different layout.",
7024
+ "Another ShellApp already exists in the page; applications must render exactly one and must never nest ShellApps.",
7025
+ "Building content inside an existing ShellApp; render the page content rather than another shell."
7026
+ ],
7027
+ "commonlyComposedWith": [
7028
+ "component:ds-panel-nav",
7029
+ "component:ds-bar-nav",
7030
+ "component:ds-panel-tools",
7031
+ "component:ds-shell-tools",
7032
+ "component:ds-mobile-sheet-nav",
7033
+ "component:ds-mobile-header",
7034
+ "component:ds-mobile-bar-nav",
7035
+ "component:ds-shell-page",
7036
+ "component:ds-swatch-picker"
7037
+ ],
7038
+ "patterns": [
7039
+ "pattern:application-shell",
7040
+ "pattern:shell-page"
7041
+ ],
7042
+ "accessibility": [
7043
+ "Keep primary destinations in PanelNav and secondary route sections in BarNav.",
7044
+ "Ensure the default content region contains the page's single main landmark.",
7045
+ "Keep PanelNav, BarNav, and PanelTools-compatible chrome available in desktop and tablet compositions and the persistent mobile bar available below 768px.",
7046
+ "Do not override browser keyboard chords when enabling shell shortcuts.",
7047
+ "Require Search and Help as the minimum PanelTools actions and provide accessible labels for every tool.",
7048
+ "Preserve focus and accessible names across navigation, collapse, overflow, and responsive presentation changes."
7049
+ ],
7050
+ "states": [
7051
+ "Render exactly one ShellApp as the workspace root and never nest it.",
7052
+ "PanelNav, BarNav, and ShellTools are the responsive shell regions; ShellTools contains at least Search and Help even when no additional product tools apply.",
7053
+ "The application router owns the current route, authorization filtering, Dashboard or Settings context, destination collections, section collections, and localized content labels.",
7054
+ "ShellApp propagates navStyle and resolved responsive mode and coordinates layout, gradient alignment, transitions, metrics, shortcuts, and mobile-stage visibility.",
7055
+ "The application controls mobileDestination and mobileSheetNavOpen and keeps router state independent from global tool-surface changes.",
7056
+ "Set gradientPreset to the single resolved global chrome preference: neutral by default, none for solid chrome, or cool, neutral, warm, and fresh for token-based washes.",
7057
+ "The application owns gradient preference persistence, cross-tab synchronization, and server or account precedence; ShellApp owns rendering the resolved preset across authenticated routes.",
7058
+ "Dashboard represents day-to-day operational work while Settings represents administrative and configuration work; route state selects the context.",
7059
+ "Update PanelNav groups, BarNav tabs and heading, navStyle, basePath, and currentUrl atomically from one resolved route state.",
7060
+ "BarNav remains present: it shows route-section tabs when available and the active PanelNav destination label as heading otherwise.",
7061
+ "Render one ShellPage as the default-slot child for each standard routed page; ShellApp owns the content scroller while ShellPage owns page header stickiness and content inset.",
7062
+ "The application filters unauthorized destinations, sections, and tools before passing them into shell components."
7063
+ ],
7064
+ "responsiveBehavior": [
7065
+ "ShellApp owns the fixed system breakpoints and resolves desktop at 1200px and wider, tablet from 768px through 1199px, and mobile below 768px.",
7066
+ "On desktop, PanelNav defaults expanded, permits user collapse or expansion, and respects the locally persisted desktop preference.",
7067
+ "On tablet, ShellApp keeps PanelNav permanently collapsed and prevents user expansion without overwriting the desktop preference.",
7068
+ "On mobile, ShellApp hides and inerts PanelNav and BarNav, uses a solid primary stage, and composes routed ShellPage MobileHeader presentations, MobileSheetNav, ShellTools, and the persistent five-item MobileBarNav.",
7069
+ "Mobile global surfaces conceal and inert the routed workspace without unmounting it, preserving nested routes and scroll state.",
7070
+ "Keep PanelNav width, BarNav height, PanelTools chrome, and main-content origin stable except during intentional responsive or collapse transitions.",
7071
+ "The bottom bar remains visible at all route and tool depths in the foundation release."
7072
+ ],
7073
+ "frameworkCaveats": {
7074
+ "customElements": [
7075
+ "Assign complex navigation and tool collections as JavaScript properties on the slotted components.",
7076
+ "Stamp route-derived nav-style before components connect when deterministic first paint is required."
7077
+ ],
7078
+ "react": [
7079
+ "Use generated wrappers and preserve native slot names for desktop navigation, responsive tools, mobile navigation, and main content.",
7080
+ "Resolve all shell inputs from one router state before rendering the composition."
7081
+ ],
7082
+ "angular": [
7083
+ "Use generated standalone adapters and preserve slot attributes in templates.",
7084
+ "Bind complex inputs as properties and update navigation inputs atomically from one resolved router state.",
7085
+ "Bind both nav-style attributes and properties when deterministic first paint is required."
7086
+ ]
7087
+ },
7088
+ "references": [
7089
+ {
7090
+ "label": "Component guide",
7091
+ "path": "src/wc/components/ShellApp/ShellApp.mdx"
7092
+ },
7093
+ {
7094
+ "label": "Executable Storybook composition",
7095
+ "path": "src/wc/components/ShellApp/ShellApp.stories.ts"
7096
+ },
7097
+ {
7098
+ "label": "Framework integration",
7099
+ "path": "docs/framework-integration.md"
7100
+ },
7101
+ {
7102
+ "label": "Application shell contract",
7103
+ "path": "agent/patterns/application-shell/pattern.agent.json"
7104
+ }
7105
+ ]
7106
+ },
7107
+ "api": {
7108
+ "props": {
7109
+ "gradientPreset": {
7110
+ "type": "ShellGradientPreset",
6969
7111
  "required": false
6970
7112
  },
6971
- "menuLabel": {
6972
- "type": "string",
7113
+ "mobileDestination": {
7114
+ "type": "MobileDestination",
6973
7115
  "required": false
6974
7116
  },
6975
- "navigationExpanded": {
7117
+ "mobileSheetNavOpen": {
6976
7118
  "type": "boolean",
6977
7119
  "required": false
6978
7120
  },
6979
- "searchDot": {
6980
- "type": "boolean",
7121
+ "navStyle": {
7122
+ "type": "NavChromeStyle",
6981
7123
  "required": false
6982
7124
  },
6983
- "searchLabel": {
6984
- "type": "string",
7125
+ "shortcutsEnabled": {
7126
+ "type": "boolean",
6985
7127
  "required": false
6986
7128
  }
6987
7129
  },
6988
7130
  "events": [
6989
7131
  {
6990
- "name": "dsDestinationChange",
6991
- "detail": "ShellMobileBarDestinationDetail"
6992
- },
6993
- {
6994
- "name": "dsNavigationToggle",
6995
- "detail": "boolean"
7132
+ "name": "dsResponsiveModeChange",
7133
+ "detail": "{ mode: ShellResponsiveMode }"
6996
7134
  }
6997
7135
  ],
6998
7136
  "slots": []
6999
7137
  },
7000
7138
  "exports": {
7001
- "customElement": "ds-shell-mobile-bar",
7002
- "react": "DsShellMobileBar",
7003
- "angular": "DsShellMobileBar"
7139
+ "customElement": "ds-shell-app",
7140
+ "react": "DsShellApp",
7141
+ "angular": "DsShellApp"
7004
7142
  },
7005
7143
  "dependencies": [
7006
7144
  "@ds-mo/ui",
7007
- "@ds-mo/tokens",
7008
- "@ds-mo/icons"
7145
+ "@ds-mo/tokens"
7009
7146
  ],
7010
- "componentDependencies": [
7011
- "icon",
7012
- "text"
7013
- ]
7147
+ "componentDependencies": []
7014
7148
  },
7015
7149
  {
7016
- "id": "component:ds-shell-mobile-nav",
7017
- "tag": "ds-shell-mobile-nav",
7018
- "name": "shell-mobile-nav",
7019
- "title": "ShellMobileNav",
7020
- "summary": "Full-height mobile primary navigation pane with local Dashboard and Settings browsing.",
7150
+ "id": "component:ds-shell-gradient-picker",
7151
+ "tag": "ds-shell-gradient-picker",
7152
+ "name": "shell-gradient-picker",
7153
+ "title": "ShellGradientPicker",
7154
+ "summary": "Deprecated compatibility wrapper that maps the fixed ShellApp wash presets into SwatchPicker.",
7021
7155
  "intentStatus": "complete",
7022
7156
  "intent": {
7023
7157
  "audience": "specialized",
7024
- "status": "experimental",
7025
- "summary": "Full-height mobile primary navigation pane with local Dashboard and Settings browsing.",
7158
+ "status": "deprecated",
7159
+ "replacedBy": "component:ds-swatch-picker",
7160
+ "replacementReason": "SwatchPicker now owns the same accessible interaction with a generic option model that supports both flat colors and gradients.",
7161
+ "summary": "Deprecated compatibility wrapper that maps the fixed ShellApp wash presets into SwatchPicker.",
7026
7162
  "useWhen": [
7027
- "The mobile ShellApp Menu control needs to expose the complete primary navigation collection."
7163
+ "Adding the Appearance or Theme section to the application's user or account menu.",
7164
+ "Users must choose the global ShellApp chrome treatment from none, cool, neutral, warm, or fresh."
7028
7165
  ],
7029
7166
  "avoidWhen": [
7030
- "Rendering desktop PanelNav.",
7031
- "Switching local page content."
7167
+ "Choosing semantic intent, page background, chart, content, or brand colors.",
7168
+ "Building an arbitrary gradient editor or allowing custom gradient values.",
7169
+ "A picker already exists for the application; provide exactly one canonical preference location.",
7170
+ "Rendering an individual swatch outside the complete picker."
7171
+ ],
7172
+ "alternatives": [
7173
+ {
7174
+ "when": "The user is selecting the application light, dark, or system color mode.",
7175
+ "component": "component:ds-menu",
7176
+ "reason": "Color mode is a separate appearance preference and should use ordinary menu selection rows."
7177
+ }
7032
7178
  ],
7033
7179
  "commonlyComposedWith": [
7034
7180
  "component:ds-shell-app",
7035
- "component:ds-shell-mobile-bar"
7181
+ "component:ds-menu"
7036
7182
  ],
7037
7183
  "patterns": [
7038
7184
  "pattern:application-shell"
7039
7185
  ],
7040
7186
  "accessibility": [
7041
- "The pane is a named navigation landmark and retains visible labels for every destination.",
7042
- "Escape requests dismissal and opening moves focus to the selected or first available area."
7187
+ "Provide a localized groupLabel that describes the shell appearance choice.",
7188
+ "Treat the presets as one radio group with one Tab stop; Arrow keys, Home, and End move and select within the group.",
7189
+ "Keep the visible compact swatches and their accessible preset names; do not rely on color alone for assistive technology."
7043
7190
  ],
7044
7191
  "states": [
7045
- "Dashboard and Settings change only the collection being browsed.",
7046
- "Area, Help, and Account events express intent while the application owns navigation and product behavior."
7192
+ "Neutral is the default preset; none renders solid shell chrome without a wash.",
7193
+ "Cool, neutral, warm, and fresh use design tokens and automatically adapt to the active light or dark color theme.",
7194
+ "Apply dsChange immediately to ShellApp.gradientPreset and keep the containing account menu open.",
7195
+ "The application owns local persistence, cross-tab synchronization, and server or account preference precedence; the picker owns only selection UI and events.",
7196
+ "Treat the fixed preset union as the only supported values and do not construct custom gradients."
7047
7197
  ],
7048
7198
  "responsiveBehavior": [
7049
- "The pane fills the mobile content stage while the bottom bar remains available."
7199
+ "Keep the compact picker in the user or account appearance menu on supported desktop and tablet shell compositions.",
7200
+ "The future mobile account surface may present the same preference differently."
7050
7201
  ],
7202
+ "frameworkCaveats": {
7203
+ "customElements": [
7204
+ "Listen for dsChange, resolve application preference precedence, and assign the result to the single ShellApp gradientPreset property."
7205
+ ],
7206
+ "react": [
7207
+ "Use the generated wrapper and handle onDsChange without closing the containing account menu."
7208
+ ],
7209
+ "angular": [
7210
+ "Bind value to the resolved preference and handle dsChange to update application state."
7211
+ ]
7212
+ },
7051
7213
  "references": [
7052
7214
  {
7053
- "label": "Storybook",
7054
- "path": "src/wc/components/ShellMobileNav/ShellMobileNav.stories.ts"
7215
+ "label": "Replacement stories",
7216
+ "path": "src/wc/components/SwatchPicker/SwatchPicker.stories.ts"
7217
+ },
7218
+ {
7219
+ "label": "ShellApp gradient contract",
7220
+ "path": "src/wc/components/ShellApp/ShellApp.mdx"
7221
+ },
7222
+ {
7223
+ "label": "Application shell composition",
7224
+ "path": "agent/patterns/application-shell/pattern.agent.json"
7055
7225
  }
7056
7226
  ]
7057
7227
  },
7058
7228
  "api": {
7059
7229
  "props": {
7060
- "accountLabel": {
7061
- "type": "string",
7062
- "required": false
7063
- },
7064
- "browseContext": {
7065
- "type": "NavChromeStyle",
7066
- "required": false
7067
- },
7068
- "currentUrl": {
7069
- "type": "string",
7070
- "required": false
7071
- },
7072
- "dashboardGroups": {
7073
- "type": "PanelNavGroup[]",
7074
- "required": false
7075
- },
7076
- "dashboardLabel": {
7077
- "type": "string",
7078
- "required": false
7079
- },
7080
- "heading": {
7081
- "type": "string",
7082
- "required": false
7083
- },
7084
- "helpLabel": {
7085
- "type": "string",
7086
- "required": false
7087
- },
7088
- "navigationLabel": {
7230
+ "groupLabel": {
7089
7231
  "type": "string",
7090
7232
  "required": false
7091
7233
  },
7092
- "open": {
7093
- "type": "boolean",
7094
- "required": false
7095
- },
7096
- "settingsGroups": {
7097
- "type": "PanelNavGroup[]",
7098
- "required": false
7099
- },
7100
- "settingsLabel": {
7101
- "type": "string",
7234
+ "value": {
7235
+ "type": "ShellGradientPreset",
7102
7236
  "required": false
7103
7237
  }
7104
7238
  },
7105
7239
  "events": [
7106
7240
  {
7107
- "name": "dsAreaSelect",
7108
- "detail": "string"
7109
- },
7110
- {
7111
- "name": "dsAuxiliarySelect",
7112
- "detail": "ShellMobileNavAuxiliaryDetail"
7113
- },
7114
- {
7115
- "name": "dsBrowseContextChange",
7116
- "detail": "NavChromeStyle"
7117
- },
7118
- {
7119
- "name": "dsClose",
7120
- "detail": "void"
7241
+ "name": "dsChange",
7242
+ "detail": "ShellGradientPreset"
7121
7243
  }
7122
7244
  ],
7123
7245
  "slots": []
7124
7246
  },
7125
7247
  "exports": {
7126
- "customElement": "ds-shell-mobile-nav",
7127
- "react": "DsShellMobileNav",
7128
- "angular": "DsShellMobileNav"
7248
+ "customElement": "ds-shell-gradient-picker",
7249
+ "react": "DsShellGradientPicker",
7250
+ "angular": "DsShellGradientPicker"
7129
7251
  },
7130
7252
  "dependencies": [
7131
7253
  "@ds-mo/ui",
7132
- "@ds-mo/tokens",
7133
- "@ds-mo/icons"
7254
+ "@ds-mo/tokens"
7134
7255
  ],
7135
7256
  "componentDependencies": [
7136
- "icon",
7137
- "tab-group",
7138
- "text"
7257
+ "swatch-picker"
7139
7258
  ]
7140
7259
  },
7141
7260
  {
7142
- "id": "component:ds-shell-mobile-section-nav",
7143
- "tag": "ds-shell-mobile-section-nav",
7144
- "name": "shell-mobile-section-nav",
7145
- "title": "ShellMobileSectionNav",
7146
- "summary": "Horizontally scrollable mobile route navigation corresponding to the active area's desktop BarNav.",
7261
+ "id": "component:ds-shell-gradient-swatch",
7262
+ "tag": "ds-shell-gradient-swatch",
7263
+ "name": "shell-gradient-swatch",
7264
+ "title": "ShellGradientSwatch",
7265
+ "summary": "Deprecated internal compatibility component for one legacy ShellApp gradient swatch.",
7147
7266
  "intentStatus": "complete",
7148
7267
  "intent": {
7149
- "audience": "specialized",
7150
- "status": "experimental",
7151
- "summary": "Horizontally scrollable mobile route navigation corresponding to the active area's desktop BarNav.",
7268
+ "audience": "internal",
7269
+ "status": "deprecated",
7270
+ "replacedBy": "component:ds-swatch-picker",
7271
+ "replacementReason": "SwatchPicker renders its option buttons internally so an individually published radio swatch is no longer needed.",
7272
+ "summary": "Deprecated internal compatibility component for one legacy ShellApp gradient swatch.",
7152
7273
  "useWhen": [
7153
- "ShellApp is rendering the below-768px routed workspace and the active area has peer route sections."
7274
+ "Maintaining or extending ShellGradientPicker inside CompoMo."
7154
7275
  ],
7155
7276
  "avoidWhen": [
7156
- "Choices switch local content without navigation; use TabGroup.",
7157
- "Rendering the desktop or tablet secondary navigation; use BarNav."
7277
+ "Building application UI directly; use ShellGradientPicker instead.",
7278
+ "Selecting semantic, brand, chart, page, or arbitrary gradient colors.",
7279
+ "Creating a partial or custom set of shell gradient choices."
7158
7280
  ],
7159
7281
  "alternatives": [
7160
7282
  {
7161
- "when": "The choices switch local content without changing routes.",
7162
- "component": "component:ds-tab-group",
7163
- "reason": "TabGroup owns local view selection."
7283
+ "when": "An application needs the supported global shell appearance control.",
7284
+ "component": "component:ds-swatch-picker",
7285
+ "reason": "SwatchPicker provides the complete radio-group semantics, keyboard behavior, generic previews, and selection event."
7164
7286
  }
7165
7287
  ],
7166
7288
  "commonlyComposedWith": [
7167
- "component:ds-shell-app",
7168
- "component:ds-shell-mobile-bar",
7169
- "component:ds-bar-nav"
7170
- ],
7171
- "patterns": [
7172
- "pattern:application-shell"
7289
+ "component:ds-swatch-picker"
7173
7290
  ],
7174
7291
  "accessibility": [
7175
- "The row is a named navigation landmark and the selected section exposes aria-current.",
7176
- "Disabled route sections remain visible but cannot emit navigation intent."
7292
+ "Keep radio semantics, aria-checked state, and a preset-specific accessible name on the internal button.",
7293
+ "Let ShellGradientPicker manage the roving tab stop and group keyboard navigation.",
7294
+ "Do not expose an unlabeled color-only choice."
7177
7295
  ],
7178
7296
  "states": [
7179
- "The host router owns the current URL and handles dsTabChange.",
7180
- "Detail routes that do not match a section show the active-area heading."
7297
+ "Preset determines the token-based preview; selected determines radio state and selected visuals.",
7298
+ "The selected swatch owns the radio group's single tab stop while ShellGradientPicker coordinates selection and focus movement.",
7299
+ "isInactive disables interaction but does not remove the accessible name."
7181
7300
  ],
7182
7301
  "responsiveBehavior": [
7183
- "The row scrolls horizontally without wrapping and centers the selected section when selection changes."
7302
+ "Preserve the fixed compact swatch geometry and let ShellGradientPicker own layout."
7184
7303
  ],
7185
7304
  "frameworkCaveats": {
7186
7305
  "customElements": [
7187
- "Assign tabs as a JavaScript property and update currentUrl and basePath with router state."
7306
+ "Do not instantiate this internal primitive in consuming applications."
7188
7307
  ],
7189
7308
  "react": [
7190
- "Pass the same BarNavTab array used by the desktop BarNav through the generated React wrapper."
7309
+ "Use DsShellGradientPicker rather than the generated swatch wrapper."
7191
7310
  ],
7192
7311
  "angular": [
7193
- "Import the generated standalone adapter and bind tabs as a property."
7312
+ "Use DsShellGradientPicker rather than importing DsShellGradientSwatch."
7194
7313
  ]
7195
7314
  },
7196
7315
  "references": [
7197
7316
  {
7198
- "label": "Storybook",
7199
- "path": "src/wc/components/ShellMobileSectionNav/ShellMobileSectionNav.stories.ts"
7317
+ "label": "Parent picker",
7318
+ "path": "src/wc/components/ShellGradientPicker/ShellGradientPicker.tsx"
7200
7319
  }
7201
7320
  ]
7202
7321
  },
7203
7322
  "api": {
7204
7323
  "props": {
7205
- "basePath": {
7206
- "type": "string",
7207
- "required": false
7208
- },
7209
- "currentUrl": {
7210
- "type": "string",
7211
- "required": false
7212
- },
7213
- "heading": {
7214
- "type": "string | undefined",
7215
- "required": false
7216
- },
7217
- "navigationLabel": {
7218
- "type": "string",
7324
+ "ariaLabel": {
7325
+ "type": "string | null",
7219
7326
  "required": false
7220
7327
  },
7221
- "tabs": {
7222
- "type": "BarNavTab[]",
7328
+ "isInactive": {
7329
+ "type": "boolean",
7223
7330
  "required": false
7224
7331
  },
7225
- "tabsJson": {
7226
- "type": "string",
7332
+ "preset": {
7333
+ "type": "ShellGradientPreset",
7227
7334
  "required": false
7228
7335
  },
7229
- "value": {
7230
- "type": "string",
7336
+ "selected": {
7337
+ "type": "boolean",
7231
7338
  "required": false
7232
7339
  }
7233
7340
  },
7234
7341
  "events": [
7235
7342
  {
7236
- "name": "dsTabChange",
7237
- "detail": "string"
7343
+ "name": "dsSelect",
7344
+ "detail": "ShellGradientPreset"
7238
7345
  }
7239
7346
  ],
7240
7347
  "slots": []
7241
7348
  },
7242
7349
  "exports": {
7243
- "customElement": "ds-shell-mobile-section-nav",
7244
- "react": "DsShellMobileSectionNav",
7245
- "angular": "DsShellMobileSectionNav"
7350
+ "customElement": "ds-shell-gradient-swatch",
7351
+ "react": "DsShellGradientSwatch",
7352
+ "angular": "DsShellGradientSwatch"
7246
7353
  },
7247
7354
  "dependencies": [
7248
7355
  "@ds-mo/ui",
7249
7356
  "@ds-mo/tokens"
7250
7357
  ],
7251
- "componentDependencies": [
7252
- "text"
7253
- ]
7358
+ "componentDependencies": []
7254
7359
  },
7255
7360
  {
7256
7361
  "id": "component:ds-shell-page",
@@ -7297,7 +7402,7 @@
7297
7402
  ],
7298
7403
  "accessibility": [
7299
7404
  "ShellPage exposes the routed page as the main landmark; render exactly one active ShellPage inside ShellApp.",
7300
- "Provide exactly one BarTitle or BarWorkflow through the header slot so the page has one h1.",
7405
+ "Provide one BarTitle or BarWorkflow through the desktop header slot and one MobileHeader through mobile-header when the page participates in the mobile shell.",
7301
7406
  "Keep loading, empty, validation, error, progress, success, and failure communication in the default product-content slot.",
7302
7407
  "Responsive variant changes preserve the same heading, controls, accessible names, and keyboard focus targets."
7303
7408
  ],
@@ -7306,12 +7411,13 @@
7306
7411
  "headerPresentation=auto selects the matching header variant from headerCapacity and scroll position.",
7307
7412
  "expanded, compact, and constrained are explicit overrides for exceptional layouts and deterministic examples.",
7308
7413
  "contentInset=default supplies standard page gutters; none permits maps, canvases, and other full-bleed content.",
7309
- "The required header slot accepts one BarTitle or BarWorkflow. The default slot owns router output and all page product content."
7414
+ "The header slot accepts one desktop BarTitle or BarWorkflow; mobile-header accepts the corresponding MobileHeader presentation. The default slot owns router output and all page product content."
7310
7415
  ],
7311
7416
  "responsiveBehavior": [
7312
7417
  "The owning application shell resolves viewport and persistent-chrome state into the explicit headerCapacity prop; ShellPage never guesses the cause of reduced width from its own rendered size.",
7313
7418
  "Roomy capacity expands at the top and compacts after scroll; compact capacity stays compact; constrained capacity uses the constrained action layout.",
7314
7419
  "A ShellPage-managed BarTitle remains concealed until headerCapacity is available and its rendered variant matches the resolved presentation, preventing a default-variant flash during route activation.",
7420
+ "responsiveMode=mobile hides and inerts the desktop header, exposes mobile-header, and disables desktop scroll-compaction geometry.",
7315
7421
  "Update headerCapacity synchronously with shell layout state so opening tools or crossing application breakpoints cannot briefly render the wrong presentation.",
7316
7422
  "On roomy pages, the expanded header scrolls upward until its title and action row reaches the compact row position, then snaps variants without moving that shared visual anchor.",
7317
7423
  "Scroll compaction preserves the expanded page flow offset so content never jumps beneath the sticky header.",
@@ -7320,15 +7426,15 @@
7320
7426
  ],
7321
7427
  "frameworkCaveats": {
7322
7428
  "customElements": [
7323
- "Import ShellPage with BarTitle or BarWorkflow, place one header in slot=header, and render route content as default children.",
7429
+ "Import ShellPage with BarTitle or BarWorkflow in slot=header and MobileHeader in slot=mobile-header, then render route content as default children.",
7324
7430
  "Do not set BarTitle.variant while ShellPage owns headerPresentation."
7325
7431
  ],
7326
7432
  "react": [
7327
- "Render DsBarTitle or DsBarWorkflow with slot=header inside DsShellPage and keep routed content as the remaining children.",
7433
+ "Render the desktop header with slot=header and DsMobileHeader with slot=mobile-header inside DsShellPage.",
7328
7434
  "Use contentInset none only for deliberately full-bleed page products."
7329
7435
  ],
7330
7436
  "angular": [
7331
- "Import the generated standalone DsShellPage adapter with DsBarTitle or DsBarWorkflow, preserve slot=header, and place router-outlet in the ShellPage default slot.",
7437
+ "Import the generated standalone DsShellPage adapter with the desktop header and DsMobileHeader, preserve both header slots, and place router-outlet in the default slot.",
7332
7438
  "Do not add another overflow auto wrapper around the routed page."
7333
7439
  ]
7334
7440
  },
@@ -7360,6 +7466,10 @@
7360
7466
  "headerPresentation": {
7361
7467
  "type": "ShellPageHeaderPresentation",
7362
7468
  "required": false
7469
+ },
7470
+ "responsiveMode": {
7471
+ "type": "ShellResponsiveMode",
7472
+ "required": false
7363
7473
  }
7364
7474
  },
7365
7475
  "events": [],
@@ -7404,7 +7514,9 @@
7404
7514
  "commonlyComposedWith": [
7405
7515
  "component:ds-shell-app",
7406
7516
  "component:ds-panel-tool-header",
7407
- "component:ds-shell-mobile-bar"
7517
+ "component:ds-mobile-header",
7518
+ "component:ds-mobile-section-switcher",
7519
+ "component:ds-mobile-bar-nav"
7408
7520
  ],
7409
7521
  "patterns": [
7410
7522
  "pattern:application-shell"
@@ -7412,7 +7524,7 @@
7412
7524
  "accessibility": [
7413
7525
  "Only the active mobile tool view participates in focus or the accessibility tree.",
7414
7526
  "Header Back and application-owned header actions preserve the PanelTools event contract.",
7415
- "Inbox uses TabGroup semantics for Messages, Stacks, and Activity."
7527
+ "Inbox uses the MobileSectionSwitcher popup trigger for Messages, Stacks, and Activity and never relies on a gesture-only interaction."
7416
7528
  ],
7417
7529
  "states": [
7418
7530
  "The application owns open and activeTool and replaces headers when tool depth changes.",
@@ -7421,7 +7533,7 @@
7421
7533
  ],
7422
7534
  "responsiveBehavior": [
7423
7535
  "Desktop and tablet compose PanelTools-compatible rail and drawer chrome.",
7424
- "Mobile renders the active tool across the shell stage and groups available inbox tools in a segmented control."
7536
+ "Mobile renders one centered MobileHeader for every tool and presents Messages, Stacks, and Activity directly as peer section titles without an additional Inbox heading."
7425
7537
  ],
7426
7538
  "frameworkCaveats": {
7427
7539
  "customElements": [
@@ -7534,9 +7646,10 @@
7534
7646
  "@ds-mo/tokens"
7535
7647
  ],
7536
7648
  "componentDependencies": [
7537
- "panel-tool-header",
7649
+ "button-unfilled",
7650
+ "mobile-header",
7538
7651
  "panel-tools",
7539
- "tab-group"
7652
+ "tooltip"
7540
7653
  ]
7541
7654
  },
7542
7655
  {