@ds-mo/ui 14.19.1 → 14.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. package/dist/.package-ready.json +1 -1
  2. package/dist/agent-patterns.json +1 -1
  3. package/dist/agent.json +405 -36
  4. package/dist/angular/ds-chip.d.ts +1 -1
  5. package/dist/angular/ds-chip.js +3 -3
  6. package/dist/angular/ds-filter-menu.d.ts +7 -1
  7. package/dist/angular/ds-filter-menu.js +7 -4
  8. package/dist/angular/ds-input.d.ts +1 -1
  9. package/dist/angular/ds-input.js +3 -3
  10. package/dist/angular/ds-tab-group.d.ts +1 -1
  11. package/dist/angular/ds-tab-group.js +3 -3
  12. package/dist/angular/ds-table-filter.d.ts +7 -1
  13. package/dist/angular/ds-table-filter.js +7 -4
  14. package/dist/angular/ds-table-group.d.ts +29 -0
  15. package/dist/angular/ds-table-group.js +48 -0
  16. package/dist/angular/ds-table-search.d.ts +20 -0
  17. package/dist/angular/ds-table-search.js +49 -0
  18. package/dist/angular/ds-table.d.ts +1 -1
  19. package/dist/angular/ds-table.js +3 -3
  20. package/dist/angular/index.d.ts +1 -1
  21. package/dist/angular/index.js +2 -0
  22. package/dist/angular/proxies.d.ts +2 -0
  23. package/dist/angular/proxies.js +2 -0
  24. package/dist/components/ds-agent-activity.js +1 -1
  25. package/dist/components/ds-agent-questionnaire.js +1 -1
  26. package/dist/components/ds-agent-response.js +1 -1
  27. package/dist/components/ds-agent-source-list.js +1 -1
  28. package/dist/components/ds-agent-tool-call.js +1 -1
  29. package/dist/components/ds-attachment-list.js +1 -1
  30. package/dist/components/ds-badge.js +1 -1
  31. package/dist/components/ds-banner.js +1 -1
  32. package/dist/components/ds-bar-action.js +1 -1
  33. package/dist/components/ds-bar-nav.js +1 -1
  34. package/dist/components/ds-bar-title.js +1 -1
  35. package/dist/components/ds-bar-workflow.js +1 -1
  36. package/dist/components/ds-breadcrumb.js +1 -1
  37. package/dist/components/ds-button-filled.js +1 -1
  38. package/dist/components/ds-button-unfilled.js +1 -1
  39. package/dist/components/ds-card-chart.js +1 -1
  40. package/dist/components/ds-card-overview.js +1 -1
  41. package/dist/components/ds-card-setting.js +1 -1
  42. package/dist/components/ds-chart-legend.js +1 -1
  43. package/dist/components/ds-chart.js +1 -1
  44. package/dist/components/ds-checkbox.js +1 -1
  45. package/dist/components/ds-chip.js +1 -1
  46. package/dist/components/ds-chip.js.map +1 -1
  47. package/dist/components/ds-code-block.js +1 -1
  48. package/dist/components/ds-conversation-list-item.js +1 -1
  49. package/dist/components/ds-conversation-list-section.js +1 -1
  50. package/dist/components/ds-empty-state.js +1 -1
  51. package/dist/components/ds-field.js +1 -1
  52. package/dist/components/ds-filter-menu.js +1 -1
  53. package/dist/components/ds-input.js +1 -1
  54. package/dist/components/ds-markdown.js +1 -1
  55. package/dist/components/ds-menu.js +1 -1
  56. package/dist/components/ds-message-actions.js +1 -1
  57. package/dist/components/ds-message-composer.js +1 -1
  58. package/dist/components/ds-message-scroller.js +1 -1
  59. package/dist/components/ds-message-scroller.js.map +1 -1
  60. package/dist/components/ds-message.js +1 -1
  61. package/dist/components/ds-mobile-bar-nav.js +1 -1
  62. package/dist/components/ds-mobile-header.js +1 -1
  63. package/dist/components/ds-mobile-section-switcher.js +1 -1
  64. package/dist/components/ds-mobile-sheet-nav.js +1 -1
  65. package/dist/components/ds-modal.js +1 -1
  66. package/dist/components/ds-pagination.js +1 -1
  67. package/dist/components/ds-panel-nav.js +1 -1
  68. package/dist/components/ds-panel-sub-nav.js +1 -1
  69. package/dist/components/ds-panel-tool-header.js +1 -1
  70. package/dist/components/ds-panel-tool-search.js +1 -1
  71. package/dist/components/ds-panel-tool-search.js.map +1 -1
  72. package/dist/components/ds-panel-tools.js +1 -1
  73. package/dist/components/ds-paper-texture.js +1 -1
  74. package/dist/components/ds-radio.js +1 -1
  75. package/dist/components/ds-select.js +1 -1
  76. package/dist/components/ds-shell-app.js +1 -1
  77. package/dist/components/ds-shell-page.js +1 -1
  78. package/dist/components/ds-shell-tools.js +1 -1
  79. package/dist/components/ds-slider.js +1 -1
  80. package/dist/components/ds-swatch-picker.js +1 -1
  81. package/dist/components/ds-tab-group.js +1 -1
  82. package/dist/components/ds-table-filter.js +1 -1
  83. package/dist/components/ds-table-filter.js.map +1 -1
  84. package/dist/components/ds-table-group.d.ts +11 -0
  85. package/dist/components/ds-table-group.js +2 -0
  86. package/dist/components/ds-table-group.js.map +1 -0
  87. package/dist/components/ds-table-saved-views.js +1 -1
  88. package/dist/components/ds-table-search.d.ts +11 -0
  89. package/dist/components/ds-table-search.js +2 -0
  90. package/dist/components/ds-table-search.js.map +1 -0
  91. package/dist/components/ds-table-sort.js +1 -1
  92. package/dist/components/ds-table-sort.js.map +1 -1
  93. package/dist/components/ds-table-toolbar.js +1 -1
  94. package/dist/components/ds-table-toolbar.js.map +1 -1
  95. package/dist/components/ds-table.js +1 -1
  96. package/dist/components/ds-table.js.map +1 -1
  97. package/dist/components/ds-tag.js +1 -1
  98. package/dist/components/ds-text.js +1 -1
  99. package/dist/components/ds-toast.js +1 -1
  100. package/dist/components/ds-tooltip-chart.js +1 -1
  101. package/dist/components/ds-tooltip.js +1 -1
  102. package/dist/components/ds-typing-indicator.js +1 -1
  103. package/dist/components/{p-Bf7PZJPT.js → p-5Z4oYuiK.js} +2 -2
  104. package/dist/components/{p-DsgEY6mZ.js → p-6rB0eAda.js} +2 -2
  105. package/dist/components/{p-DZv2g9Pe.js → p-9ykZwPlI.js} +2 -2
  106. package/dist/components/{p-BHhmB9-4.js → p-B0kSlcaw.js} +2 -2
  107. package/dist/components/{p-BmlGeaY8.js → p-B1wMpt1z.js} +2 -2
  108. package/dist/components/p-BEttT0UB.js +2 -0
  109. package/dist/components/p-BEttT0UB.js.map +1 -0
  110. package/dist/components/p-BFit8o0r.js +2 -0
  111. package/dist/components/p-BFit8o0r.js.map +1 -0
  112. package/dist/components/{p-fRDzpfi9.js → p-BXv6RpoF.js} +2 -2
  113. package/dist/components/{p-CFsLF-ts.js → p-BbG7nOcz.js} +2 -2
  114. package/dist/components/{p-vrotWZxt.js → p-Bc_z1UwJ.js} +2 -2
  115. package/dist/components/{p-Bx5BSd6F.js → p-BcxidW9k.js} +2 -2
  116. package/dist/components/{p-BNq9fr9S.js → p-Bd8I2oXN.js} +2 -2
  117. package/dist/components/{p-D-MWvpg6.js → p-Bjq1KP_Y.js} +2 -2
  118. package/dist/components/p-Bjq1KP_Y.js.map +1 -0
  119. package/dist/components/{p-DW5Ita-P.js → p-BnTPuV3x.js} +2 -2
  120. package/dist/components/{p-DW5Ita-P.js.map → p-BnTPuV3x.js.map} +1 -1
  121. package/dist/components/p-BqVXMEJm.js +2 -0
  122. package/dist/components/p-BqVXMEJm.js.map +1 -0
  123. package/dist/components/{p-DdH7b4JF.js → p-CBymzuOO.js} +2 -2
  124. package/dist/components/{p-BjRD57w3.js → p-CE2b5GPu.js} +2 -2
  125. package/dist/components/{p-CRSwNbPk.js → p-CEnoPUn5.js} +2 -2
  126. package/dist/components/p-CFkZSDwI.js +2 -0
  127. package/dist/components/{p-CKtJ6FHM.js.map → p-CFkZSDwI.js.map} +1 -1
  128. package/dist/components/{p-Bb4KnRy0.js → p-CTH3dSYg.js} +2 -2
  129. package/dist/components/{p-1YHFQeI7.js → p-CUL5_8JM.js} +2 -2
  130. package/dist/components/{p-BubgDQlb.js → p-CZ144LS5.js} +2 -2
  131. package/dist/components/{p-B-HsfQOK.js → p-Cd1JnnVK.js} +2 -2
  132. package/dist/components/p-CeKa4VbU.js +2 -0
  133. package/dist/components/{p-Crz606uD.js.map → p-CeKa4VbU.js.map} +1 -1
  134. package/dist/components/{p-Bx1IHqJb.js → p-Cnsvgx1M.js} +2 -2
  135. package/dist/components/{p-BYFS2qWb.js → p-CpeJMKJ5.js} +2 -2
  136. package/dist/components/{p-Cxr0IQjC.js → p-CzbsTZt7.js} +2 -2
  137. package/dist/components/{p-D7v6Na7U.js → p-D36EmETH.js} +2 -2
  138. package/dist/components/{p-DFC0sRM-.js → p-DI8DUozc.js} +2 -2
  139. package/dist/components/{p-DIqT1m2r.js → p-DSy1oOnd.js} +2 -2
  140. package/dist/components/{p-DIqT1m2r.js.map → p-DSy1oOnd.js.map} +1 -1
  141. package/dist/components/{p-DQBT1Jkf.js → p-DbLLH3hr.js} +2 -2
  142. package/dist/components/{p-Drnyq8z7.js → p-Dit6JmAK.js} +2 -2
  143. package/dist/components/{p-caLOcQUK.js → p-DzPtYdXy.js} +2 -2
  144. package/dist/components/{p-Do8wbFff.js → p-XaCYqck3.js} +2 -2
  145. package/dist/components/{p-DKt_8s-U.js → p-Y5_MkCFn.js} +2 -2
  146. package/dist/components/{p-DBYCwq9L.js → p-YDxDyedE.js} +2 -2
  147. package/dist/components/{p-DmWoFSGs.js → p-_C-XRpCB.js} +2 -2
  148. package/dist/components/{p-Demfba7T.js → p-bHnk8t5I.js} +2 -2
  149. package/dist/components/p-hYjmOPCI.js +2 -0
  150. package/dist/components/p-hYjmOPCI.js.map +1 -0
  151. package/dist/components/{p-ChfVRPHw.js → p-pUOA3iDG.js} +2 -2
  152. package/dist/components/p-pnO8tAYB.js +2 -0
  153. package/dist/components/{p-Cp5Hr7Vz.js.map → p-pnO8tAYB.js.map} +1 -1
  154. package/dist/components/{p-B6WQre5D.js → p-pxN8JGEh.js} +2 -2
  155. package/dist/components/p-pxN8JGEh.js.map +1 -0
  156. package/dist/components/{p-BWwiCvep.js → p-rw0ZxIE4.js} +2 -2
  157. package/dist/components/{p-B4wTnsUL.js → p-w9fkkwL2.js} +2 -2
  158. package/dist/components/p-x5u5Ueli.js +2 -0
  159. package/dist/components/{p-BeA6Jv-3.js.map → p-x5u5Ueli.js.map} +1 -1
  160. package/dist/docs/components.json +1400 -44
  161. package/dist/lib/utils/date-filter-value.d.ts +57 -0
  162. package/dist/lib/utils/index.d.ts +2 -0
  163. package/dist/lib/utils/index.js +67 -0
  164. package/dist/lib/utils/index.js.map +3 -3
  165. package/dist/mcp-data/registry/button-filled.json +1 -0
  166. package/dist/mcp-data/registry/button-unfilled.json +1 -0
  167. package/dist/mcp-data/registry/chip.json +39 -2
  168. package/dist/mcp-data/registry/filter-menu.json +134 -14
  169. package/dist/mcp-data/registry/input.json +54 -2
  170. package/dist/mcp-data/registry/panel-tool-search.json +4 -5
  171. package/dist/mcp-data/registry/registry.json +410 -35
  172. package/dist/mcp-data/registry/select.json +1 -0
  173. package/dist/mcp-data/registry/tab-group.json +21 -2
  174. package/dist/mcp-data/registry/table-filter.json +83 -11
  175. package/dist/mcp-data/registry/table-group.json +301 -0
  176. package/dist/mcp-data/registry/table-search.json +343 -0
  177. package/dist/mcp-data/registry/table-sort.json +1 -1
  178. package/dist/mcp-data/registry/table-toolbar.json +7 -6
  179. package/dist/mcp-data/registry/table.json +55 -17
  180. package/dist/react/components.d.ts +2 -0
  181. package/dist/react/components.js +2 -0
  182. package/dist/react/ds-filter-menu.d.ts +2 -1
  183. package/dist/react/ds-filter-menu.js +1 -0
  184. package/dist/react/ds-table-filter.d.ts +2 -1
  185. package/dist/react/ds-table-filter.js +1 -0
  186. package/dist/react/ds-table-group.d.ts +14 -0
  187. package/dist/react/ds-table-group.js +16 -0
  188. package/dist/react/ds-table-search.d.ts +14 -0
  189. package/dist/react/ds-table-search.js +16 -0
  190. package/dist/styles/table.css +46 -0
  191. package/dist/types/components/Chip/Chip.d.ts +5 -0
  192. package/dist/types/components/FilterMenu/FilterMenu.d.ts +46 -1
  193. package/dist/types/components/FilterMenu/filter-menu-calendar.d.ts +13 -0
  194. package/dist/types/components/Input/Input.d.ts +6 -0
  195. package/dist/types/components/TabGroup/TabGroup.d.ts +2 -0
  196. package/dist/types/components/Table/Table.d.ts +6 -0
  197. package/dist/types/components/Table/index.d.ts +1 -1
  198. package/dist/types/components/Table/table-cell-model.d.ts +11 -1
  199. package/dist/types/components/Table/table-highlight.d.ts +12 -0
  200. package/dist/types/components/Table/table-model.d.ts +6 -5
  201. package/dist/types/components/Table/table-render-model.d.ts +1 -1
  202. package/dist/types/components/Table/table-row-view.d.ts +4 -1
  203. package/dist/types/components/Table/table-types.d.ts +22 -4
  204. package/dist/types/components/Table/table-virtual-model.d.ts +2 -0
  205. package/dist/types/components/TableFilter/TableFilter.d.ts +9 -1
  206. package/dist/types/components/TableGroup/TableGroup.d.ts +60 -0
  207. package/dist/types/components/TableSearch/TableSearch.d.ts +56 -0
  208. package/dist/types/components/TableSearch/table-search-model.d.ts +10 -0
  209. package/dist/types/components/TableSearch/table-search-types.d.ts +10 -0
  210. package/dist/types/components.d.ts +410 -8
  211. package/dist/types/utils/choice-list-parts.d.ts +11 -1
  212. package/dist/types/utils/date-filter-value.d.ts +58 -0
  213. package/dist/types/utils/index.d.ts +2 -0
  214. package/dist/types/utils/select-controller.d.ts +1 -1
  215. package/dist/vue/components.d.ts +2 -0
  216. package/dist/vue/components.js +2 -0
  217. package/dist/vue/ds-chip.js +2 -0
  218. package/dist/vue/ds-filter-menu.js +7 -0
  219. package/dist/vue/ds-input.js +3 -0
  220. package/dist/vue/ds-tab-group.js +1 -0
  221. package/dist/vue/ds-table-filter.js +5 -0
  222. package/dist/vue/ds-table-group.d.ts +3 -0
  223. package/dist/vue/ds-table-group.js +20 -0
  224. package/dist/vue/ds-table-search.d.ts +3 -0
  225. package/dist/vue/ds-table-search.js +22 -0
  226. package/dist/vue/ds-table.js +2 -0
  227. package/package.json +1 -1
  228. package/dist/components/p-B6WQre5D.js.map +0 -1
  229. package/dist/components/p-BeA6Jv-3.js +0 -2
  230. package/dist/components/p-CKtJ6FHM.js +0 -2
  231. package/dist/components/p-Cp5Hr7Vz.js +0 -2
  232. package/dist/components/p-CpUXubax.js +0 -2
  233. package/dist/components/p-CpUXubax.js.map +0 -1
  234. package/dist/components/p-Crz606uD.js +0 -2
  235. package/dist/components/p-D-MWvpg6.js.map +0 -1
  236. package/dist/components/p-DA5H_Iq_.js +0 -2
  237. package/dist/components/p-DA5H_Iq_.js.map +0 -1
  238. package/dist/components/p-Djxw2FjZ.js +0 -2
  239. package/dist/components/p-Djxw2FjZ.js.map +0 -1
  240. /package/dist/components/{p-Bf7PZJPT.js.map → p-5Z4oYuiK.js.map} +0 -0
  241. /package/dist/components/{p-DsgEY6mZ.js.map → p-6rB0eAda.js.map} +0 -0
  242. /package/dist/components/{p-DZv2g9Pe.js.map → p-9ykZwPlI.js.map} +0 -0
  243. /package/dist/components/{p-BHhmB9-4.js.map → p-B0kSlcaw.js.map} +0 -0
  244. /package/dist/components/{p-BmlGeaY8.js.map → p-B1wMpt1z.js.map} +0 -0
  245. /package/dist/components/{p-fRDzpfi9.js.map → p-BXv6RpoF.js.map} +0 -0
  246. /package/dist/components/{p-CFsLF-ts.js.map → p-BbG7nOcz.js.map} +0 -0
  247. /package/dist/components/{p-vrotWZxt.js.map → p-Bc_z1UwJ.js.map} +0 -0
  248. /package/dist/components/{p-Bx5BSd6F.js.map → p-BcxidW9k.js.map} +0 -0
  249. /package/dist/components/{p-BNq9fr9S.js.map → p-Bd8I2oXN.js.map} +0 -0
  250. /package/dist/components/{p-DdH7b4JF.js.map → p-CBymzuOO.js.map} +0 -0
  251. /package/dist/components/{p-BjRD57w3.js.map → p-CE2b5GPu.js.map} +0 -0
  252. /package/dist/components/{p-CRSwNbPk.js.map → p-CEnoPUn5.js.map} +0 -0
  253. /package/dist/components/{p-Bb4KnRy0.js.map → p-CTH3dSYg.js.map} +0 -0
  254. /package/dist/components/{p-1YHFQeI7.js.map → p-CUL5_8JM.js.map} +0 -0
  255. /package/dist/components/{p-BubgDQlb.js.map → p-CZ144LS5.js.map} +0 -0
  256. /package/dist/components/{p-B-HsfQOK.js.map → p-Cd1JnnVK.js.map} +0 -0
  257. /package/dist/components/{p-Bx1IHqJb.js.map → p-Cnsvgx1M.js.map} +0 -0
  258. /package/dist/components/{p-BYFS2qWb.js.map → p-CpeJMKJ5.js.map} +0 -0
  259. /package/dist/components/{p-Cxr0IQjC.js.map → p-CzbsTZt7.js.map} +0 -0
  260. /package/dist/components/{p-D7v6Na7U.js.map → p-D36EmETH.js.map} +0 -0
  261. /package/dist/components/{p-DFC0sRM-.js.map → p-DI8DUozc.js.map} +0 -0
  262. /package/dist/components/{p-DQBT1Jkf.js.map → p-DbLLH3hr.js.map} +0 -0
  263. /package/dist/components/{p-Drnyq8z7.js.map → p-Dit6JmAK.js.map} +0 -0
  264. /package/dist/components/{p-caLOcQUK.js.map → p-DzPtYdXy.js.map} +0 -0
  265. /package/dist/components/{p-Do8wbFff.js.map → p-XaCYqck3.js.map} +0 -0
  266. /package/dist/components/{p-DKt_8s-U.js.map → p-Y5_MkCFn.js.map} +0 -0
  267. /package/dist/components/{p-DBYCwq9L.js.map → p-YDxDyedE.js.map} +0 -0
  268. /package/dist/components/{p-DmWoFSGs.js.map → p-_C-XRpCB.js.map} +0 -0
  269. /package/dist/components/{p-Demfba7T.js.map → p-bHnk8t5I.js.map} +0 -0
  270. /package/dist/components/{p-ChfVRPHw.js.map → p-pUOA3iDG.js.map} +0 -0
  271. /package/dist/components/{p-BWwiCvep.js.map → p-rw0ZxIE4.js.map} +0 -0
  272. /package/dist/components/{p-B4wTnsUL.js.map → p-w9fkkwL2.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": "14.19.1",
4
+ "packageVersion": "14.21.0",
5
5
  "kind": "components",
6
6
  "entries": [
7
7
  {
@@ -1766,6 +1766,7 @@
1766
1766
  ],
1767
1767
  "states": [
1768
1768
  "Every size applies one complete control-density recipe across frame height, inline padding, icon zone, text-container inset, gap, and radius.",
1769
+ "Every button has a minimum inline size equal to its resolved height. Short labels therefore form a square control while longer labels continue to hug their content.",
1769
1770
  "Set isInset only when the button is nested inside a same-size control. The default single inset removes 4px overall; insetDepth double removes 8px overall so the parent can add 4px per edge while preserving its outer alignment box. Double inset falls back to single at xs to protect minimum icon geometry.",
1770
1771
  "Use only one filled action per local decision area; render all secondary actions with ButtonUnfilled.",
1771
1772
  "Choose brand or neutral for general commands. Reserve positive, negative, warning, and caution for matching action consequences, and AI, guide, or walkthrough for actions that enter those feature experiences.",
@@ -1980,6 +1981,7 @@
1980
1981
  ],
1981
1982
  "states": [
1982
1983
  "Every size applies one complete control-density recipe across frame height, inline padding, icon zone, text-container inset, gap, and radius.",
1984
+ "Every button has a minimum inline size equal to its resolved height. Short labels therefore form a square control while longer labels continue to hug their content.",
1983
1985
  "Set isInset only when the button is nested inside a same-size control. The default single inset removes 4px overall; insetDepth double removes 8px overall so the parent can add 4px per edge while preserving its outer alignment box. Double inset falls back to single at xs to protect minimum icon geometry.",
1984
1986
  "A true pressed toggle and owner-controlled isActive emphasis share the selected visual treatment, but only pressed supplies toggle semantics and dsChange.",
1985
1987
  "General content UI keeps the selected interaction fill and border for pressed or active emphasis.",
@@ -3049,6 +3051,7 @@
3049
3051
  "The dismiss action is the chip's only interaction, and the parent owns data mutation after dsRemove.",
3050
3052
  "Long labels remain on one line and truncate only when the consuming layout supplies a maximum width; otherwise the chip sizes to its content.",
3051
3053
  "Rounded shape is a visual choice and does not change semantics or interaction.",
3054
+ "isInset opts into reduced outer geometry only when Chip is nested inside a control of the same density. The dismiss button applies the same inset depth again inside the Chip's already-reduced height, and its trailing padding matches the resulting top and bottom space. The default single inset removes 4px overall; insetDepth double removes 8px overall and falls back to single at xs.",
3052
3055
  "Chip is designed only for primary surfaces and has no surface-context API."
3053
3056
  ],
3054
3057
  "responsiveBehavior": [
@@ -3075,10 +3078,18 @@
3075
3078
  },
3076
3079
  "api": {
3077
3080
  "props": {
3081
+ "insetDepth": {
3082
+ "type": "ControlInsetDepth",
3083
+ "required": false
3084
+ },
3078
3085
  "isInactive": {
3079
3086
  "type": "boolean",
3080
3087
  "required": false
3081
3088
  },
3089
+ "isInset": {
3090
+ "type": "boolean",
3091
+ "required": false
3092
+ },
3082
3093
  "label": {
3083
3094
  "type": "string",
3084
3095
  "required": true
@@ -3800,12 +3811,12 @@
3800
3811
  "tag": "ds-filter-menu",
3801
3812
  "name": "filter-menu",
3802
3813
  "title": "FilterMenu",
3803
- "summary": "Controlled two-pane filter select with menu-recipe category navigation, single- and multiple-choice, boolean, and date filters, selected counts, and a clear action.",
3814
+ "summary": "Controlled two-pane filter select with menu-recipe category navigation, local option search for non-date categories, single- and multiple-choice, boolean, semantic relative-date and fixed-range filters, selected counts, and a clear action.",
3804
3815
  "intentStatus": "complete",
3805
3816
  "intent": {
3806
3817
  "audience": "general",
3807
3818
  "status": "stable",
3808
- "summary": "Controlled two-pane filter select with menu-recipe category navigation, single- and multiple-choice, boolean, and date filters, selected counts, and a clear action.",
3819
+ "summary": "Controlled two-pane filter select with menu-recipe category navigation, local option search for non-date categories, single- and multiple-choice, boolean, semantic relative-date and fixed-range filters, selected counts, and a clear action.",
3809
3820
  "useWhen": [
3810
3821
  "A compact trigger must expose several filter families without turning the toolbar into many separate controls.",
3811
3822
  "Users need to move between persistent filter categories while editing the selected category in a second pane."
@@ -3835,16 +3846,23 @@
3835
3846
  "accessibility": [
3836
3847
  "The built-in select trigger exposes combobox semantics with a dialog popup, synchronizes expanded state, holds the pressed interaction wash without changing resting foreground while open, and restores focus after dismissal.",
3837
3848
  "The category pane is a vertical tab list. Arrow Up and Arrow Down wrap, Home and End jump, Arrow Right enters the option pane, and Arrow Left returns to the active category.",
3849
+ "Every non-date category begins with a labelled search field. Arrow Down and Arrow Up enter the first or last visible option, while Left and Right retain native text-caret behavior. Search matches option labels and descriptions without changing selected values.",
3838
3850
  "Escape and outside activation close the popup and restore trigger focus. Tab moves through option controls and closes only when it leaves the popup boundary.",
3851
+ "Date filters expose containerless Range and Relative tabs in a secondary-background header with 4px padding around the 32px medium control. Relative presets use listbox semantics; the range calendar exposes a labelled grid, one tab stop, arrow-key day navigation, Home and End week navigation, and Page Up or Page Down month navigation. After a range start is chosen, pointer hover and keyboard focus preview the possible inclusive range without changing selection semantics.",
3839
3852
  "When an external trigger is inside an open shadow tree, pass its HTMLElement through anchor so outside activation, focus return, and Tab continuation use the composed tree.",
3840
- "The trigger count reports active filter categories. Category counts and the footer report individual selected criteria; none replace visible selected-state indication."
3853
+ "The trigger count reports active filter categories. Multiple-choice category tags report individual selected criteria, while an applied Date category uses a visual dot because its value is singular. The default summary footer announces the total; the categories-clear footer recipe reserves a visually empty category-pane action row and exposes its divider and only Clear when criteria are active."
3841
3854
  ],
3842
3855
  "states": [
3843
- "The application owns filters, values, activeFilterId, and open. Replace controlled objects and arrays after dsChange, dsActiveFilterChange, dsClear, or dsClose.",
3844
- "Single filters return a string, multiple filters return ordered string arrays, boolean filters return a boolean, and date filters return a YYYY-MM-DD string.",
3856
+ "The application owns filters, values, matchModes, activeFilterId, and open. Replace controlled objects and arrays after dsChange, dsMatchModeChange, dsActiveFilterChange, dsClear, or dsClose.",
3857
+ "Single filters return a string, multiple filters return ordered string arrays, boolean filters return a boolean, and date filters return a serializable semantic string.",
3858
+ "Multiple filters expose a right-pane footer reading Limit results to any or all selected. any is the default OR mode. Activating the blue mode word requests the opposite controlled mode through dsMatchModeChange; the application owns the corresponding query semantics.",
3859
+ "Non-date option search is internal, scoped independently per category while the popup remains open, and reset after the popup closes. An unmatched query shows the configurable noResultsText empty state. Date uses its Relative and Range modes instead of option search.",
3860
+ "Date values are serializable semantic strings: relative:<preset> preserves a relative choice for future resolution and range:<start>/<end> preserves fixed inclusive ISO calendar dates. A legacy YYYY-MM-DD value is interpreted as a one-day range.",
3861
+ "Relative presets are Today, Yesterday, and the last 7, 14, 30, 60, or 90 inclusive calendar days. Applications resolve them against their current product date and time-zone policy by using resolveDateFilterRange from @ds-mo/ui/utils.",
3862
+ "Range selection applies the first date immediately as a one-day range; while an end is pending, that selected start retains its bold treatment and hovering or focusing another day paints the rest of the provisional inclusive span faint without emitting a value. A second activation completes an ordered inclusive range and gives both edges the bold treatment. A new activation after completion starts a replacement range.",
3845
3863
  "Selection applies immediately and does not close the popup.",
3846
3864
  "Changing category replaces the option-pane subtree so checkbox and other option visuals mount in their new state instead of transitioning from the previous category's row state.",
3847
- "The trigger reports how many filter categories have selections, while the footer appears when values are selected and reports the total selected criteria."
3865
+ "The trigger reports how many filter categories have selections. footerLayout=summary adds a full-width selected-count footer only while values are selected; footerLayout=categories-clear always reserves the category-pane footer height while keeping its inactive divider hidden, then reveals the divider and only its left-aligned Clear action while values are selected."
3848
3866
  ],
3849
3867
  "responsiveBehavior": [
3850
3868
  "The popup defaults to the large menu-width token and clamps to the nearest data-ds-overlay-boundary rectangle or the viewport fallback.",
@@ -3854,13 +3872,13 @@
3854
3872
  ],
3855
3873
  "frameworkCaveats": {
3856
3874
  "customElements": [
3857
- "Assign filters and values as JavaScript properties after the element is defined."
3875
+ "Assign filters, values, and matchModes as JavaScript properties after the element is defined."
3858
3876
  ],
3859
3877
  "react": [
3860
- "Pass filters and values as controlled props and handle onDsChange, onDsActiveFilterChange, onDsClear, and onDsClose."
3878
+ "Pass filters, values, and matchModes as controlled props and handle onDsChange, onDsMatchModeChange, onDsActiveFilterChange, onDsClear, and onDsClose."
3861
3879
  ],
3862
3880
  "angular": [
3863
- "Use property bindings for filters and values and event bindings for dsChange, dsActiveFilterChange, dsClear, and dsClose."
3881
+ "Use property bindings for filters, values, and matchModes and event bindings for dsChange, dsMatchModeChange, dsActiveFilterChange, dsClear, and dsClose."
3864
3882
  ]
3865
3883
  },
3866
3884
  "references": [
@@ -3920,6 +3938,10 @@
3920
3938
  "type": "FilterMenuFilter[]",
3921
3939
  "required": false
3922
3940
  },
3941
+ "footerLayout": {
3942
+ "type": "FilterMenuFooterLayout",
3943
+ "required": false
3944
+ },
3923
3945
  "hasBorder": {
3924
3946
  "type": "boolean",
3925
3947
  "required": false
@@ -3936,6 +3958,10 @@
3936
3958
  "type": "string | undefined",
3937
3959
  "required": false
3938
3960
  },
3961
+ "matchModes": {
3962
+ "type": "FilterMenuMatchModes",
3963
+ "required": false
3964
+ },
3939
3965
  "menuLabel": {
3940
3966
  "type": "string",
3941
3967
  "required": false
@@ -3944,10 +3970,22 @@
3944
3970
  "type": "string",
3945
3971
  "required": false
3946
3972
  },
3973
+ "noResultsText": {
3974
+ "type": "string",
3975
+ "required": false
3976
+ },
3947
3977
  "open": {
3948
3978
  "type": "boolean",
3949
3979
  "required": false
3950
3980
  },
3981
+ "searchPlaceholder": {
3982
+ "type": "string",
3983
+ "required": false
3984
+ },
3985
+ "showSelectedCount": {
3986
+ "type": "boolean",
3987
+ "required": false
3988
+ },
3951
3989
  "side": {
3952
3990
  "type": "AnchoredSide",
3953
3991
  "required": false
@@ -3994,6 +4032,10 @@
3994
4032
  "name": "dsClose",
3995
4033
  "detail": "void"
3996
4034
  },
4035
+ {
4036
+ "name": "dsMatchModeChange",
4037
+ "detail": "FilterMenuMatchModeChangeDetail"
4038
+ },
3997
4039
  {
3998
4040
  "name": "dsOpenChange",
3999
4041
  "detail": "boolean"
@@ -4013,9 +4055,13 @@
4013
4055
  "@ds-mo/icons"
4014
4056
  ],
4015
4057
  "componentDependencies": [
4058
+ "badge",
4016
4059
  "button-unfilled",
4017
4060
  "checkbox",
4061
+ "empty-state",
4018
4062
  "icon",
4063
+ "input",
4064
+ "tab-group",
4019
4065
  "tag",
4020
4066
  "text",
4021
4067
  "tooltip"
@@ -4196,10 +4242,12 @@
4196
4242
  ],
4197
4243
  "states": [
4198
4244
  "Every size applies one complete control-density recipe across frame height, inline padding, icon zones, text-container inset, gap, and radius; supporting error content follows the shared 4px field flow.",
4199
- "The normal field boundary uses the shared secondary inset border. Focus promotes it to the thicker bold-brand inset stroke, while error uses the thicker bold-negative inset stroke without changing geometry. Set hasBorder to false only in chrome that supplies enough surrounding structure; the control then remains borderless at rest, while focused, and while invalid, with semantics and supporting error copy unchanged.",
4245
+ "The normal field boundary uses the shared secondary inset border. Focus promotes it to the thicker bold-brand inset stroke, while error uses the thicker bold-negative inset stroke without changing geometry. Set hasBorder to false only in chrome that supplies enough surrounding structure; set hasInteractionFill to false when that containing chrome also owns hover and pressed feedback.",
4200
4246
  "Placeholder text is secondary at rest and quaternary while the editable field is focused because it becomes decorative once typing begins. Single-line placeholder and entered value text truncate with an ellipsis when the field is narrower than its content.",
4201
4247
  "Entered values use the parent surface's primary foreground; prefix icons, suffix content, and resting placeholder text use its secondary foreground.",
4202
4248
  "Search fields show a standard borderless CrossCircle icon action only while they contain a value. Clearing emits the empty value and restores focus to the native field.",
4249
+ "Search fields disable browser autocomplete history, automatic capitalization, autocorrection, and spellchecking by default so browser-owned suggestions do not compete with product-owned results. Consumers can explicitly provide autoComplete when a different native history behavior is required.",
4250
+ "Search fields used with owned result sets forward aria-controls and aria-activedescendant to the native field so keyboard focus can remain in the query while assistive technology tracks the active result.",
4203
4251
  "The suffix slot is for compact units or decorations. The optional leading icon is decorative and does not replace the field label.",
4204
4252
  "Use autoComplete, inputMode, and enterKeyHint to provide browser and virtual-keyboard hints without changing the value's semantic type.",
4205
4253
  "Number fields preserve native spinbutton semantics, keyboard stepping, and min/max constraint behavior while dsChange continues to report the native string value. Two borderless inset chevron actions split the available inner height, disable independently at their numeric bound, and restore focus to the spinbutton after pointer activation.",
@@ -4240,6 +4288,14 @@
4240
4288
  },
4241
4289
  "api": {
4242
4290
  "props": {
4291
+ "ariaActiveDescendant": {
4292
+ "type": "string | undefined",
4293
+ "required": false
4294
+ },
4295
+ "ariaControls": {
4296
+ "type": "string | undefined",
4297
+ "required": false
4298
+ },
4243
4299
  "ariaDescribedby": {
4244
4300
  "type": "string | undefined",
4245
4301
  "required": false
@@ -4288,6 +4344,10 @@
4288
4344
  "type": "boolean",
4289
4345
  "required": false
4290
4346
  },
4347
+ "hasInteractionFill": {
4348
+ "type": "boolean",
4349
+ "required": false
4350
+ },
4291
4351
  "icon": {
4292
4352
  "type": "string | undefined",
4293
4353
  "required": false
@@ -6677,13 +6737,12 @@
6677
6737
  },
6678
6738
  "dependencies": [
6679
6739
  "@ds-mo/ui",
6680
- "@ds-mo/tokens",
6681
- "@ds-mo/icons"
6740
+ "@ds-mo/tokens"
6682
6741
  ],
6683
6742
  "componentDependencies": [
6684
6743
  "button-unfilled",
6685
6744
  "divider",
6686
- "icon",
6745
+ "input",
6687
6746
  "text",
6688
6747
  "tooltip"
6689
6748
  ]
@@ -7524,6 +7583,7 @@
7524
7583
  "checkbox",
7525
7584
  "empty-state",
7526
7585
  "icon",
7586
+ "input",
7527
7587
  "loader",
7528
7588
  "text",
7529
7589
  "tooltip"
@@ -8797,6 +8857,7 @@
8797
8857
  "A missing, empty, inactive, or unknown selected value is invalid when enabled tabs exist; the component does not choose a fallback selection.",
8798
8858
  "Selection is singular and follows keyboard focus.",
8799
8859
  "Width follows the shared control contract: hug keeps the track content-sized, while fill occupies the parent width and distributes available space equally across selectable segments; dividers remain fixed-width separators.",
8860
+ "hasContainer defaults to true. Set it to false only when a parent surface owns the track background and boundary; the outer fill, border, and inset disappear while selected-pill, interaction, focus, density, and keyboard behavior remain unchanged.",
8800
8861
  "Small, medium, and large use the shared 24px, 32px, and 40px control-density recipes for the outer track. Each segment uses the same-size inset recipe at 20px, 28px, and 36px while preserving that density's typography, icon, gap, and label metrics.",
8801
8862
  "Use one consistent content variant across every selectable tab in a group.",
8802
8863
  "Omitted background is for primary and secondary surfaces; pass the faint context explicitly on faint surfaces.",
@@ -8841,6 +8902,10 @@
8841
8902
  "type": "TabBackground | undefined",
8842
8903
  "required": false
8843
8904
  },
8905
+ "hasContainer": {
8906
+ "type": "boolean",
8907
+ "required": false
8908
+ },
8844
8909
  "size": {
8845
8910
  "type": "TabGroupSize",
8846
8911
  "required": false
@@ -8888,12 +8953,12 @@
8888
8953
  "tag": "ds-table",
8889
8954
  "name": "table",
8890
8955
  "title": "Table",
8891
- "summary": "Semantic, controlled data table with durable visual primitives for cell geometry, grouping, sorting, multi-selection, sticky overflow, incremental loading, top-level pagination, and optional row virtualization.",
8956
+ "summary": "Semantic, controlled data table with durable visual primitives for cell geometry, wrapping multiple-Tag cells, grouping, sorting, multi-selection, sticky overflow, incremental loading, top-level pagination, and optional row virtualization.",
8892
8957
  "intentStatus": "complete",
8893
8958
  "intent": {
8894
8959
  "audience": "general",
8895
8960
  "status": "stable",
8896
- "summary": "Semantic, controlled data table with durable visual primitives for cell geometry, grouping, sorting, multi-selection, sticky overflow, incremental loading, top-level pagination, and optional row virtualization.",
8961
+ "summary": "Semantic, controlled data table with durable visual primitives for cell geometry, wrapping multiple-Tag cells, grouping, sorting, multi-selection, sticky overflow, incremental loading, top-level pagination, and optional row virtualization.",
8897
8962
  "useWhen": [
8898
8963
  "A structured dataset needs native row and column relationships, optional one-level grouping, or comparable values across records.",
8899
8964
  "An application needs controlled sorting, loaded-row selection, infinite loading, pagination, virtual row recycling, or opted-in table-owned data-mode and column controls while retaining ownership of the data query, catalog, and persistence.",
@@ -8928,15 +8993,16 @@
8928
8993
  "The rendered structure uses a native table, caption, column headers, row groups, and data cells; keep the caption non-empty. The native caption remains visually hidden as the table's accessible name. When caption visibility is enabled, a 48px header bar renders as component chrome outside the data scrollport. It defaults to a presentational caption title that does not duplicate the accessible name. Application-owned labeled controls supplied through the single named header slot replace that fallback and share one horizontal caption overflow row with table-owned actions inside the component-owned 8px inset. Table caption buttons keep pressed interaction paint without physically scaling. When columnCustomizer is enabled, the table adds a trailing Customize control named Customize table. Its label uses regular weight and its resting foreground remains neutral when hidden or reordered columns differ from the catalog default. The control is icon-label at typical widths and the icon-only Table menu button below 900px, where a tooltip preserves the Customize label. The always-icon-only table-variant control also exposes its label through a tooltip. Otherwise the header slot receives the complete content width.",
8929
8994
  "The data-mode switcher is the shared Menu of the table's supported infinite, pagination, and virtual modes. It uses an Ellipses trigger. The switcher is the final caption-bar action; when the column customizer is also present, a decorative vertical divider separates the two controls. dataMode remains controlled, and the application responds to change intent by supplying the matching records, pagination state, loading behavior, and query consequences. Escape, dismissal, and selection return focus to the trigger.",
8930
8995
  "The column customizer is the shared Menu of switch rows, not a table-owned dialog. Data columns can be shown, hidden, and reordered. Action columns and the selection checkbox never appear in the menu. The last remaining visible data column cannot be hidden, but it stays focusable so it can still be reordered. Escape and outside click restore focus to the trigger. Persistence stays in the application.",
8931
- "Sorting controls remain buttons inside column headers and expose the table's one controlled member-row sort through aria-sort. ds-table-sort in the toolbar trailing cluster is the matching menu of Data and Direction sections; it emits the same dsSortChange shape so header clicks and menu choices stay in sync. Grouping never adds a second sort indicator or header control; the application supplies groups in its fixed product order. Optional column help underlines the header label with the shared dotted decoration and shows ds-tooltip from that label; it does not add a second header control or replace the column name.",
8996
+ "Sorting controls remain buttons inside column headers and expose the table's one controlled member-row sort through aria-sort. ds-table-sort in the toolbar trailing cluster is the matching menu of Data and Direction sections; it emits the same dsSortChange shape so header clicks and menu choices stay in sync. Grouping never adds a second sort indicator or header control; ds-table-group controls the grouping data point and ascending or descending group-section order while the application supplies the resulting groups. Optional column help underlines the header label with the shared dotted decoration and shows ds-tooltip from that label; it does not add a second header control or replace the column name.",
8932
8997
  "Selection controls expose checkbox semantics and explicit row names; select-all affects selectable loaded rows only and preserves selected identities outside the loaded window. In virtual mode the supplied in-memory rows are that loaded set, including rows whose DOM is recycled. When grouping is active with multi-selection, each group section header also exposes a checkbox that selects or clears that group's selectable loaded rows.",
8933
8998
  "Interactive rows are focusable as native rows, activate with Enter or Space, and do not steal activation from their nested selection, action, overflow-menu, or primary-text link controls.",
8934
8999
  "Scrollable table regions become keyboard focusable and named only when overflow exists.",
8935
9000
  "Incremental loading, newly appended row counts, failures, and end-of-results transitions are announced through a polite status region without replacing visible state. In grouped tables, announcements name the independently loading group.",
9001
+ "Applications may pass their controlled literal search terms through highlightTerms after applying their own filtering. When TableSearch scopes the query, pass the same selected field identities through highlightFieldIds. A compound column maps its ordered headerSegments to primary, secondary-run, and tertiary-run data points; simple columns map their column ID to every owned text track. With no highlightFieldIds every text track remains eligible. Matching text is rendered with semantic mark elements, so the emphasis is identifiable independently of its faint-brand background and bold-brand foreground. Highlight markup preserves source order, the cell's complete accessible text, and does not create extra announcements.",
8936
9002
  "Static and infinite tables may show an optional result summary footer when displayedCount and totalCount are finite. Virtual mode shows a total-only summary and ignores displayedCount. Pagination mode instead renders a named Pagination control with a compact selected-size total, vertical divider, and page position; range changes are announced independently with complete phrasing. Unmodified Left and Right Arrow request the adjacent page while focus is inside a paginated table or on a containing page scroller that owns it; editable fields, choice controls, sliders, open menus, and modified key combinations retain their own keyboard behavior. A table-owned footer slot can replace summary copy, while footer-leading and footer-trailing remain available in the same compact-bar anatomy. Nested dialog footers are ignored."
8937
9003
  ],
8938
9004
  "states": [
8939
- "Columns, rows, groups, grouping, sorting, selected row IDs, collapsed group IDs, hiddenColumnIds, columnOrder, dataMode, pagination, displayedCount, totalCount, and incremental-loading state are controlled inputs. Events communicate intent and never mutate those inputs. The optional header is one composable table-local surface: the component owns its 48px chrome, 8px inset on every side, and sticky placement while the application owns the leading slot's internal layout, controls, labels, filtering behavior, and action handling. Opting into dataModeSwitcher and columnCustomizer adds their trailing Menu triggers and requires caption visibility. When both are present, Customize precedes a decorative divider and the data-mode trigger remains the final action. The Customize trigger keeps one stable label and neutral resting foreground whether or not hiddenColumnIds or columnOrder differ from the catalog default; the configured state remains visible inside the Menu. The table closes one trailing Menu before opening the other. The footer retains its compact-bar composition: application-owned leading status sits left while a controlled result summary or Pagination aligns right, before any trailing action. Content-sized tables remain natural for sparse or fixed-count results. height bounds the complete header, frame, and footer composition. fitViewport reserves the compact-state composition height in the nearest vertical scrollport while growing the visible table into that reservation as surrounding page chrome collapses.",
9005
+ "Columns, rows, groups, grouping, sorting, selected row IDs, collapsed group IDs, highlightTerms, highlightFieldIds, hiddenColumnIds, columnOrder, dataMode, pagination, displayedCount, totalCount, and incremental-loading state are controlled inputs. Events communicate intent and never mutate those inputs. The optional header is one composable table-local surface: the component owns its 48px chrome, 8px inset on every side, and sticky placement while the application owns the leading slot's internal layout, controls, labels, filtering behavior, and action handling. highlightTerms only marks matching table-owned text and never filters rows, changes query semantics, or highlights Tag labels. highlightFieldIds optionally narrows that marking to matching column IDs or compound header-segment sort keys. Opting into dataModeSwitcher and columnCustomizer adds their trailing Menu triggers and requires caption visibility. When both are present, Customize precedes a decorative divider and the data-mode trigger remains the final action. The Customize trigger keeps one stable label and neutral resting foreground whether or not hiddenColumnIds or columnOrder differ from the catalog default; the configured state remains visible inside the Menu. The table closes one trailing Menu before opening the other. The footer retains its compact-bar composition: application-owned leading status sits left while a controlled result summary or Pagination aligns right, before any trailing action. Content-sized tables remain natural for sparse or fixed-count results. height bounds the complete header, frame, and footer composition. fitViewport reserves the compact-state composition height in the nearest vertical scrollport while growing the visible table into that reservation as surrounding page chrome collapses.",
8940
9006
  "Grouping supports one level. The application supplies groups in a fixed product-defined order and supplies ordered member rows independently. Group section headers show an emphasized text-body-medium label followed by a middle dot and plain secondary loaded progress, for example Critical · 50 of 166. The loaded value comes from the supplied member rows and the total comes from totalCount. A localized countLabel total phrase remains available for the complete assistive progress announcement. Virtual mode shows totals only, for example Critical · 166, because there is no loaded window. Groups may declare an optional intent (brand, neutral, negative, warning, caution, positive) that paints an LTR gradient from the faint intent surface at the label edge into faint neutral at the trailing edge, plus a bold intent title color. Neutral groups remain solid faint neutral. Section separators are painted inside that viewport-width surface so translucent border tokens composite with each intent background. Internal sections keep their separators; a collapsed or empty section header yields its separator only when it is the table's final rendered item. A trailing visually neutral icon-only ButtonUnfilled uses the 24px md double-inset action recipe and toggles controlled collapsedGroupIds, showing ChevronUp while expanded and ChevronDown while collapsed. While any group is expanded, a ChevronDownUp action uses the xs sort-control recipe widened to a table-owned 24px lane and collapses every group. It appears at the inline-end edge of the trailing column declared with kind action when one exists; otherwise a button-hugging 24px by 16px medium-elevation surface floats at the visible scrollport's header edge so the action remains reachable while member columns scroll beneath it. With stickyHeader enabled, each contained section uses its one real section row as a native sticky header inside its real row-group boundary. The browser therefore owns pinning, push-off, scrolling, and resize layout in one pass without a duplicated lane, active-section state, transforms, or scroll-time geometry. Shared grid tracks retain exact header and member-cell alignment. The section surface also stays pinned to the visible horizontal scrollport and spans the smaller of the visible viewport or table width. Virtual grouped tables flatten headers and members into that same scrollport; expanding a section never introduces an inner scroller.",
8941
9007
  "When columnCustomizer is false, columns render in catalog order. When it is true, columns remains the catalog: hiddenColumnIds and columnOrder control visibility and data-column sequence, action columns stay last, cannot be hidden, and remain absent from the customizer Menu, and dsColumnsConfigChange reports the next hidden ids and data-column order without mutating those inputs. The customizer Menu live-applies show/hide and data-column reorder. The table does not persist preferences.",
8942
9008
  "An active member sort toggles only between ascending and descending; activating a different sortable label moves the one sorting state to that key. Applications may still clear the controlled sort state explicitly. Grouping does not introduce another interactive direction.",
@@ -8946,7 +9012,7 @@
8946
9012
  "When pagination enables Fit to page on a bounded table, the table proposes the number of complete top-level rows that fit below its column header. Grouped tables count group headers only; member rows never affect capacity. Selecting Fit captures that numeric snapshot. A changed fitIdentity requests one fresh snapshot for a new query shape, while viewport resizing alone does not change the active controlled page size.",
8947
9013
  "Rows opt into complete-row activation with interactive and emit dsRowActivate without owning navigation. Selection paints through the shared selected ::before layer; interactive hover and press paint through the shared ::after layer.",
8948
9014
  "Row selection owns the single sticky start lane. One explicitly sized application column can own the sticky end lane, or the start lane when selection is absent. Each sticky boundary owns one fixed divider and a row-clipped directional shadow that paints into the adjacent scrolling columns only while more inline content remains beyond that edge.",
8949
- "Cells accept scalar content, standard primary-and-secondary or dual-primary text primitives, declarative Tag, icon-only, icon-and-text, 16:9 Image, or ButtonUnfilled Action content, or explicit Empty and Blank absence values. Text objects may declare an optional href (and target) on the primary track only; the table renders a native anchor with the shared brand text-action treatment when the URL is safe, and leaves scalars unlinked. Standard secondary copy defaults to the secondary foreground and may declare a semantic Text color when the application data carries intent; an optional tertiary track uses the same subdued body-small recipe as secondary. Secondary and tertiary may also be a short list of colorable runs, rendered on one line with the table's middle-dot separator. Dual-primary copy keeps both tracks primary unless explicitly colored and does not gain a tertiary track. Body data cells share 8px outer padding; header and group rows keep their own geometry. Text tracks, including Empty, keep 4px inline padding so copy lines up with column-header labels; Tag and icon-only tracks stay on the 8px cell chrome alone. Icon-and-text cells (`kind: 'icon-text'`) place one md prefix icon beside the same copy stack as a text cell. The icon slot takes 2px padding on every side, then a 2px flex gap before the copy; text-track padding stays on the copy. Omit iconLabel when the glyph is decorative. 20px content (body-medium text, md icon, and the row checkbox) sits in a 24px track so it stays optically aligned with 24px Tag and Action content. Single-track text, selection, tag-only, icon-only, icon-and-text, Action, Empty, Blank, and 1-track Image cells resolve a 40px base contract while two-track cells grow to 62px and three-track cells grow to 84px. Tracks stack with a 2px gap. Wrapping primary on a 1-track cell uses that same rhythm: two wrapped lines share the 62px row and three wrapped lines share the 84px row. Wrapping secondary keeps primary on the first track and consumes later tracks: two secondary lines share the 84px row and three secondary lines share a 106px fourth track. Keep the same track count in every row of a table or group when those rows should share one height. Tag cells use the inset Tag recipe: md double-inset is a 24px control for tag-only and tag-with-text, while text-with-tag uses sm single-inset at 20px so the second-track pill fills the body-small slot. Action cells primarily use an icon-only Ellipses treatment, render a 24px small ButtonUnfilled, default to unbordered, and emit row, column, and action identities through dsCellAction. When an action cell declares items, that Ellipses trigger opens the shared ds-menu for commands, dividers, inactive rows, and destructive rows instead of emitting on click; choosing a command emits dsCellAction with that item's actionId. Omit items to keep a single-shot control. Image cells declare tracks 1, 2, or 3 so the 16:9 bordered preview fills that body-row content box (cell height minus 8px padding) and the column hugs the resulting width; omit tracks for the 1-track recipe, and keep image tracks aligned with the other cells in the table or group. Image cells fall back to an accessible placeholder when no source is supplied. Empty means the data applies but has no value and renders an em dash with localized assistive text; Blank means the data is not applicable and renders no content. Nullish values remain backward-compatible Empty values. Stable type and variant hooks keep every cell family independently styleable.",
9015
+ "Cells accept scalar content, standard primary-and-secondary or dual-primary text primitives, declarative Tag, wrapping multiple-Tag content, icon-only, icon-and-text, 16:9 Image, or ButtonUnfilled Action content, or explicit Empty and Blank absence values. Text objects may declare an optional href (and target) on the primary track only; the table renders a native anchor with the shared brand text-action treatment when the URL is safe, and leaves scalars unlinked. Standard secondary copy defaults to the secondary foreground and may declare a semantic Text color when the application data carries intent; an optional tertiary track uses the same subdued body-small recipe as secondary. Secondary and tertiary may also be a short list of colorable runs, rendered on one line with the table's middle-dot separator. Dual-primary copy keeps both tracks primary unless explicitly colored and does not gain a tertiary track. Body data cells share 8px outer padding; header and group rows keep their own geometry. Text tracks, including Empty, keep 4px inline padding so copy lines up with column-header labels; Tag and icon-only tracks stay on the 8px cell chrome alone. Icon-and-text cells (`kind: 'icon-text'`) place one md prefix icon beside the same copy stack as a text cell. The icon slot takes 2px padding on every side, then a 2px flex gap before the copy; text-track padding stays on the copy. Omit iconLabel when the glyph is decorative. 20px content (body-medium text, md icon, and the row checkbox) sits in a 24px track so it stays optically aligned with 24px Tag and Action content. Single-track text, selection, tag-only, icon-only, icon-and-text, Action, Empty, Blank, and 1-track Image cells resolve a 40px base contract while two-track cells grow to 62px and three-track cells grow to 84px. Every later track adds 22px, so four tracks resolve to 106px, five to 128px, and the sequence may continue. Tracks stack with a 2px gap. Wrapping primary on a 1-track cell uses that same rhythm: two wrapped lines share the 62px row and three wrapped lines share the 84px row. Wrapping secondary keeps primary on the first track and consumes later tracks: two secondary lines share the 84px row and three secondary lines share a 106px fourth track. Keep the same track count in every row of a table or group when those rows should share one height. Tag cells use the inset Tag recipe: md double-inset is a 24px control for tag-only and tag-with-text, while text-with-tag uses sm single-inset at 20px so the second-track pill fills the body-small slot. Multiple-Tag cells use `kind: 'tags'`, a positive `tracks` count, and small single-inset Tags that wrap naturally at the column edge. Their 2px block inset creates the 24px first track and each later wrapped line adds a 20px track plus the shared 2px gap. The tallest cell establishes the native row height, so all sibling cells match even at four, five, or more tracks; virtual tables use the declared count as the initial estimate and measure responsive wrapping after paint. Action cells primarily use an icon-only Ellipses treatment, render a 24px small ButtonUnfilled, default to unbordered, and emit row, column, and action identities through dsCellAction. When an action cell declares items, that Ellipses trigger opens the shared ds-menu for commands, dividers, inactive rows, and destructive rows instead of emitting on click; choosing a command emits dsCellAction with that item's actionId. Omit items to keep a single-shot control. Image cells declare tracks 1, 2, or 3 so the 16:9 bordered preview fills that body-row content box (cell height minus 8px padding) and the column hugs the resulting width; omit tracks for the 1-track recipe, and keep image tracks aligned with the other cells in the table or group. Image cells fall back to an accessible placeholder when no source is supplied. Empty means the data applies but has no value and renders an em dash with localized assistive text; Blank means the data is not applicable and renders no content. Nullish values remain backward-compatible Empty values. Stable type, variant, and track-count hooks keep every cell family independently styleable.",
8950
9016
  "The public @ds-mo/ui/table.css export is the authoritative zero-specificity visual recipe. Override its --ds-table-* properties or target its stable element classes for product-specific styling."
8951
9017
  ],
8952
9018
  "responsiveBehavior": [
@@ -8955,14 +9021,14 @@
8955
9021
  "stickyHeader follows the active vertical scroll owner: a maxHeight, height, or fitViewport table keeps its native header and group sections inside one bounded table scrollport, while a document-flow table retains a semantic native header and renders a sticky control header whose columns follow the body's native inline scroll timeline. Consumers set --ds-table-sticky-header-offset when page chrome occupies an unbounded document scrollport edge. When the 48px table header bar is visible, it sticks at that external offset and the column header stacks immediately below it.",
8956
9022
  "fitViewport uses viewportInsetBlockStart and viewportInsetBlockEnd to describe compact surrounding chrome and page gutters relative to the nearest vertical scroll owner. Before the table reaches that compact position, its host reserves the eventual height while the visible composition grows and vertical input remains owned by the outer page. Once settled, the internal table viewport becomes the vertical scroll owner. Bounded grouped tables use browser-native sticky section rows inside real block row-group boundaries, so scroll and resize do not run component JavaScript or trigger reactive section swaps. Document-flow tables retain the synchronized visual lane required by their separate horizontal scrollport.",
8957
9023
  "Without maxHeight the table grows the document and automatic lazy loading observes the browser viewport. Horizontal scrolling chains vertical wheel and trackpad movement to the page instead of trapping it.",
8958
- "Explicit column sizes establish the horizontal overflow width; unsized columns share remaining space. Set imageTracks on an image column to derive its fixed width from the matching 1-, 2-, or 3-track 16:9 image geometry plus table cell padding instead of copying a numeric width.",
9024
+ "Explicit column sizes establish the horizontal overflow width; unsized columns share remaining space. When every visible data column is explicitly sized, one internal presentational spacer absorbs unused inline space without stretching the final data column and collapses to zero when those widths introduce horizontal overflow. The spacer sits before trailing action and sticky-end lanes so those controls remain at the visible edge. Set imageTracks on an image column to derive its fixed width from the matching 1-, 2-, or 3-track 16:9 image geometry plus table cell padding instead of copying a numeric width.",
8959
9025
  "Prefer the named xs through xl column sizes, which resolve through TokoMo's table-column width tokens; numeric pixel sizes remain an escape hatch for exceptional application-owned widths.",
8960
- "Column headers use one 32px geometry. Body rows use a 40px single-track minimum with shared 8px cell padding; additional tracks grow downward. Image previews fill the same content box as their declared track count. The second text track and the third text track share one subdued body-small recipe so line 3 lines up with line 2.",
9026
+ "Column headers use one 32px geometry. Body rows use a 40px single-track minimum with shared 8px cell padding; every additional track adds 22px and grows the complete native row so sibling cells match. Image previews fill the same content box as their declared track count. Wrapping multiple-Tag cells may declare any positive track count. The second text track and the third text track share one subdued body-small recipe so line 3 lines up with line 2.",
8961
9027
  "Long content truncates to one line by default. Hover (or keyboard-focus a primary link) shows the omitted value in one table-owned tooltip when that track overflows. maxLines 2 or 3 wrap onto the named 2-track and 3-track row heights, then ellipsize with the same tooltip. wrap: true remains unlimited and does not show a truncation tooltip. Wrapping 1-track primary occupies the named 2-track and 3-track row heights instead of a private line-height scale. Wrapping secondary on a 2-track cell occupies the named 3-track row and a 106px fourth track for three lines."
8962
9028
  ],
8963
9029
  "frameworkCaveats": {
8964
9030
  "customElements": [
8965
- "Assign columns, rows, groups, grouping, sort, selectedRowIds, collapsedGroupIds, hiddenColumnIds, columnOrder, pagination, displayedCount, and totalCount through JavaScript properties rather than HTML attribute strings.",
9031
+ "Assign columns, rows, groups, grouping, sort, selectedRowIds, collapsedGroupIds, highlightTerms, highlightFieldIds, hiddenColumnIds, columnOrder, pagination, displayedCount, and totalCount through JavaScript properties rather than HTML attribute strings.",
8966
9032
  "dataMode=virtual recycles row DOM over the supplied in-memory rows or groups and requires height, maxHeight, or fitViewport. It does not fetch or paginate.",
8967
9033
  "When an action cell supplies items, the table opens one shared ds-menu from the Ellipses trigger; dsCellAction fires for the selected command, not for opening or closing the menu.",
8968
9034
  "When columnCustomizer is enabled, the Table trigger opens the same shared ds-menu of reorderable switch rows; toggling a switch or reordering a row emits dsColumnsConfigChange and does not close the menu.",
@@ -9119,6 +9185,14 @@
9119
9185
  "type": "string[]",
9120
9186
  "required": false
9121
9187
  },
9188
+ "highlightFieldIds": {
9189
+ "type": "string[]",
9190
+ "required": false
9191
+ },
9192
+ "highlightTerms": {
9193
+ "type": "string[]",
9194
+ "required": false
9195
+ },
9122
9196
  "infiniteModeLabel": {
9123
9197
  "type": "string",
9124
9198
  "required": false
@@ -9303,15 +9377,15 @@
9303
9377
  "tag": "ds-table-filter",
9304
9378
  "name": "table-filter",
9305
9379
  "title": "TableFilter",
9306
- "summary": "Standard table-toolbar Filter control that owns the shared trigger, filter menu UI, accessible defaults, and compact-caption behavior while the application controls data and values.",
9380
+ "summary": "Standard table-toolbar Filter control that owns the shared trigger, searchable non-date filter options, accessible defaults, and compact-caption behavior while the application controls data and values.",
9307
9381
  "intentStatus": "complete",
9308
9382
  "intent": {
9309
9383
  "audience": "general",
9310
9384
  "status": "stable",
9311
- "summary": "Standard table-toolbar Filter control that owns the shared trigger, filter menu UI, accessible defaults, and compact-caption behavior while the application controls data and values.",
9385
+ "summary": "Standard table-toolbar Filter control that owns the shared trigger, searchable non-date filter options, accessible defaults, and compact-caption behavior while the application controls data and values.",
9312
9386
  "useWhen": [
9313
9387
  "A table toolbar should expose the standard singular Filter control and shared filter-menu interaction.",
9314
- "A product supplies filter definitions and controlled values but should not recreate the toolbar trigger, selected count, category navigation, or responsive treatment."
9388
+ "A product supplies filter definitions and controlled values but should not recreate the toolbar trigger, category navigation, or responsive treatment."
9315
9389
  ],
9316
9390
  "avoidWhen": [
9317
9391
  "Filtering is unrelated to a table or structured result set; use ds-filter-menu directly.",
@@ -9338,11 +9412,15 @@
9338
9412
  "accessibility": [
9339
9413
  "The trigger is an icon-label combobox named Filter table unless a product aria-label supplies the table context. Compact caption widths preserve that accessible name after the visible label and chevron are omitted.",
9340
9414
  "The popup retains ds-filter-menu category navigation, option semantics, focus entry, dismissal, and focus return, and aligns its start edge with the trigger.",
9341
- "Localize label, menuLabel, categoriesLabel, and clearLabel together so visible and accessible wording remains consistent."
9415
+ "Localize label, menuLabel, categoriesLabel, clearLabel, searchPlaceholder, and noResultsText together so visible and accessible wording remains consistent."
9342
9416
  ],
9343
9417
  "states": [
9344
- "filters, values, and activeFilterId are controlled. dsChange, dsClear, and dsActiveFilterChange report intent without changing those inputs; the application applies query consequences and returns replacement values.",
9345
- "The visible trigger label defaults to singular Filter and appends the selected criterion count. The trigger uses resting secondary chrome at typical widths; active criteria promote only the visible label, without redefining generic button active semantics.",
9418
+ "filters, values, matchModes, and activeFilterId are controlled. dsChange, dsMatchModeChange, dsClear, and dsActiveFilterChange report intent without changing those inputs; the application applies query consequences and returns replacement values.",
9419
+ "The visible trigger label stays singular Filter without appending an active-count suffix. Active criteria promote only the visible label from secondary to primary, matching the other table caption controls without redefining generic button active semantics.",
9420
+ "The popup reserves a visually empty footer row inside the category pane for every state. Active criteria reveal its divider and only a left-aligned Clear action, without adding popup height or showing redundant selected-count copy; the option pane retains its full column.",
9421
+ "Every multiple-choice category exposes a right-pane footer where the blue any or all word toggles its controlled match mode. any is the default OR mode; the application applies the requested mode to its query.",
9422
+ "Every non-date category exposes a 40px secondary-background search header that filters its displayed option labels and descriptions without changing controlled filter values. Date retains only its Relative and Range header.",
9423
+ "Date categories use the shared compact-header Range and Relative experience. Persist relative values semantically and resolve them from the product's current date whenever rows or saved views are applied.",
9346
9424
  "Popup visibility follows the same mutable open and dsOpenChange contract as ds-filter-menu."
9347
9425
  ],
9348
9426
  "responsiveBehavior": [
@@ -9351,13 +9429,13 @@
9351
9429
  ],
9352
9430
  "frameworkCaveats": {
9353
9431
  "customElements": [
9354
- "Assign filters, values, and activeFilterId as JavaScript properties. Replace controlled values in response to dsChange and dsClear."
9432
+ "Assign filters, values, matchModes, and activeFilterId as JavaScript properties. Replace controlled values and modes in response to dsChange, dsMatchModeChange, and dsClear."
9355
9433
  ],
9356
9434
  "react": [
9357
- "Keep filters and values in application state and replace values from the typed dsChange and dsClear events."
9435
+ "Keep filters, values, and matchModes in application state and replace them from the typed dsChange, dsMatchModeChange, and dsClear events."
9358
9436
  ],
9359
9437
  "angular": [
9360
- "Import the generated DsTableFilter adapter, bind filters and values, and handle dsChange, dsClear, and dsActiveFilterChange."
9438
+ "Import the generated DsTableFilter adapter, bind filters, values, and matchModes, and handle dsChange, dsMatchModeChange, dsClear, and dsActiveFilterChange."
9361
9439
  ]
9362
9440
  },
9363
9441
  "references": [
@@ -9397,14 +9475,26 @@
9397
9475
  "type": "string",
9398
9476
  "required": false
9399
9477
  },
9478
+ "matchModes": {
9479
+ "type": "FilterMenuMatchModes",
9480
+ "required": false
9481
+ },
9400
9482
  "menuLabel": {
9401
9483
  "type": "string | null",
9402
9484
  "required": false
9403
9485
  },
9486
+ "noResultsText": {
9487
+ "type": "string",
9488
+ "required": false
9489
+ },
9404
9490
  "open": {
9405
9491
  "type": "boolean",
9406
9492
  "required": false
9407
9493
  },
9494
+ "searchPlaceholder": {
9495
+ "type": "string",
9496
+ "required": false
9497
+ },
9408
9498
  "values": {
9409
9499
  "type": "FilterMenuValues",
9410
9500
  "required": false
@@ -9431,6 +9521,10 @@
9431
9521
  "name": "dsClose",
9432
9522
  "detail": "void"
9433
9523
  },
9524
+ {
9525
+ "name": "dsMatchModeChange",
9526
+ "detail": "FilterMenuMatchModeChangeDetail"
9527
+ },
9434
9528
  {
9435
9529
  "name": "dsOpenChange",
9436
9530
  "detail": "boolean"
@@ -9452,6 +9546,138 @@
9452
9546
  "filter-menu"
9453
9547
  ]
9454
9548
  },
9549
+ {
9550
+ "id": "component:ds-table-group",
9551
+ "tag": "ds-table-group",
9552
+ "name": "table-group",
9553
+ "title": "TableGroup",
9554
+ "summary": "Two-panel toolbar control for choosing one table grouping data point and the ascending or descending order of its group sections.",
9555
+ "intentStatus": "complete",
9556
+ "intent": {
9557
+ "audience": "general",
9558
+ "status": "stable",
9559
+ "summary": "Two-panel toolbar control for choosing one table grouping data point and the ascending or descending order of its group sections.",
9560
+ "useWhen": [
9561
+ "A table toolbar needs explicit control of one grouping level and its section order.",
9562
+ "Grouping data-point labels differ from compact table-header labels."
9563
+ ],
9564
+ "avoidWhen": [
9565
+ "The table is not groupable.",
9566
+ "The application expects the component to rearrange rows or create group sections internally."
9567
+ ],
9568
+ "alternatives": [
9569
+ {
9570
+ "when": "The choice is one submitted form value with no dependent order pane.",
9571
+ "component": "component:ds-select",
9572
+ "reason": "Select owns form-value semantics rather than table grouping state."
9573
+ }
9574
+ ],
9575
+ "commonlyComposedWith": [
9576
+ "component:ds-table",
9577
+ "component:ds-table-toolbar",
9578
+ "component:ds-table-filter",
9579
+ "component:ds-table-sort"
9580
+ ],
9581
+ "patterns": [
9582
+ "pattern:menu-trigger"
9583
+ ],
9584
+ "accessibility": [
9585
+ "The trigger opens a named non-modal dialog. Data and Order are independently named single-selection listboxes.",
9586
+ "Up and Down move within the focused pane. Right moves from Data to Order when a group is active, Left returns to the selected Data row, and Escape closes the dialog and restores trigger focus.",
9587
+ "The right pane remains present before a group is active as one complete empty state without the Order heading, and explains that a group must be selected."
9588
+ ],
9589
+ "states": [
9590
+ "options and grouping are controlled. dsGroupChange reports a complete TableGroupingState and dsClear requests null grouping without mutating either input.",
9591
+ "Selecting a new data point starts its order at ascending. Re-selecting the active data point preserves its direction.",
9592
+ "Selecting a data point or direction applies immediately and leaves the dialog open so the other pane can be changed."
9593
+ ],
9594
+ "responsiveBehavior": [
9595
+ "Use in the trailing region of ds-table-toolbar.",
9596
+ "The trigger uses the shared caption-control button behavior and becomes icon-only in compact named table containers.",
9597
+ "Both panes remain present and their choice lists scroll within the collision-constrained popup."
9598
+ ],
9599
+ "frameworkCaveats": {
9600
+ "customElements": [
9601
+ "Assign options and grouping as JavaScript properties and replace grouping from dsGroupChange or dsClear."
9602
+ ],
9603
+ "react": [
9604
+ "Keep grouping in application state and replace it from dsGroupChange; set it to null from dsClear."
9605
+ ],
9606
+ "angular": [
9607
+ "Import the generated DsTableGroup adapter and bind options and grouping as properties."
9608
+ ]
9609
+ },
9610
+ "references": [
9611
+ {
9612
+ "label": "Review states",
9613
+ "path": "src/wc/components/TableGroup/TableGroup.stories.ts"
9614
+ },
9615
+ {
9616
+ "label": "Toolbar composition owner",
9617
+ "path": "src/wc/components/TableToolbar/TableToolbar.agent.json"
9618
+ }
9619
+ ]
9620
+ },
9621
+ "api": {
9622
+ "props": {
9623
+ "ariaLabel": {
9624
+ "type": "string | null",
9625
+ "required": false
9626
+ },
9627
+ "clearLabel": {
9628
+ "type": "string",
9629
+ "required": false
9630
+ },
9631
+ "emptyMessage": {
9632
+ "type": "string",
9633
+ "required": false
9634
+ },
9635
+ "grouping": {
9636
+ "type": "TableGroupingState | null",
9637
+ "required": false
9638
+ },
9639
+ "open": {
9640
+ "type": "boolean",
9641
+ "required": false
9642
+ },
9643
+ "options": {
9644
+ "type": "TableGroupOption[]",
9645
+ "required": false
9646
+ }
9647
+ },
9648
+ "events": [
9649
+ {
9650
+ "name": "dsClear",
9651
+ "detail": "void"
9652
+ },
9653
+ {
9654
+ "name": "dsGroupChange",
9655
+ "detail": "TableGroupingState"
9656
+ },
9657
+ {
9658
+ "name": "dsOpenChange",
9659
+ "detail": "boolean"
9660
+ }
9661
+ ],
9662
+ "slots": []
9663
+ },
9664
+ "exports": {
9665
+ "customElement": "ds-table-group",
9666
+ "react": "DsTableGroup",
9667
+ "vue": "DsTableGroup",
9668
+ "angular": "DsTableGroup"
9669
+ },
9670
+ "dependencies": [
9671
+ "@ds-mo/ui",
9672
+ "@ds-mo/tokens"
9673
+ ],
9674
+ "componentDependencies": [
9675
+ "button-unfilled",
9676
+ "empty-state",
9677
+ "input",
9678
+ "text"
9679
+ ]
9680
+ },
9455
9681
  {
9456
9682
  "id": "component:ds-table-saved-views",
9457
9683
  "tag": "ds-table-saved-views",
@@ -9600,6 +9826,148 @@
9600
9826
  "select"
9601
9827
  ]
9602
9828
  },
9829
+ {
9830
+ "id": "component:ds-table-search",
9831
+ "tag": "ds-table-search",
9832
+ "name": "table-search",
9833
+ "title": "TableSearch",
9834
+ "summary": "Controlled table-search editor with slash-invoked field scoping, removable inset field Chips, and an input-focused listbox keyboard model.",
9835
+ "intentStatus": "complete",
9836
+ "intent": {
9837
+ "audience": "general",
9838
+ "status": "stable",
9839
+ "summary": "Controlled table-search editor with slash-invoked field scoping, removable inset field Chips, and an input-focused listbox keyboard model.",
9840
+ "useWhen": [
9841
+ "A data-table search needs optional field-specific scopes without replacing the application's filtering logic.",
9842
+ "People should be able to add one or more searchable data points through a slash command while continuing to type one free-text query."
9843
+ ],
9844
+ "avoidWhen": [
9845
+ "A plain global text search is sufficient; use Input with type search.",
9846
+ "The choices are persistent filters with independent values; use TableFilter or Select instead.",
9847
+ "The component is expected to inspect records, build a search index, or filter rows internally."
9848
+ ],
9849
+ "commonlyComposedWith": [
9850
+ "component:ds-table",
9851
+ "component:ds-table-toolbar",
9852
+ "component:ds-chip",
9853
+ "component:ds-button-unfilled",
9854
+ "component:ds-icon"
9855
+ ],
9856
+ "accessibility": [
9857
+ "The native search input remains the one Tab stop and exposes combobox, expanded, controls, and active-descendant relationships to the field listbox.",
9858
+ "Typing slash opens the field listbox without inserting slash into the table query. Text typed while it is open filters data points by complete label, Up and Down change the active match, Enter selects it, Escape closes it, and Left and Right retain native text-cursor behavior because focus never leaves the input. Backspace edits the field-picker query first and closes the listbox when that query is empty.",
9859
+ "The query disables browser autocomplete history, automatic capitalization, autocorrection, and spellchecking so browser-owned suggestions never obscure the product-owned field menu or table results.",
9860
+ "Selected field Chips have individually labeled remove actions and are also described by the search input. Polite announcements report additions, removals, and clearing without duplicating the visible query.",
9861
+ "The slash suffix is a labeled double-inset md button excluded from sequential keyboard navigation; the search input exposes the same action through aria-keyshortcuts and its description.",
9862
+ "The clear action removes both free text and every selected field. It restores focus to the search input; each Chip's own remove action remains scoped to that field."
9863
+ ],
9864
+ "states": [
9865
+ "value and selectedFieldIds are controlled. columns supplies the same table catalog used by Table and TableSort; dataLabel provides the complete out-of-context name while header and header segment label may remain compact. dsChange reports query edits, dsFieldsChange reports the next ordered field identities, and dsClear reports a complete clear. The component never filters rows or mutates consumer inputs.",
9866
+ "The field menu excludes already-selected identities and closes after one selection. Typing slash again reopens the remaining fields so multiple scopes can be added.",
9867
+ "Selected scopes render as neutral md Chips using the double-inset recipe so they remain 24px high inside the 32px md search control and each can be removed directly.",
9868
+ "Backspace edits a non-empty field-picker query, then closes the open slash listbox when that query is empty. When the table query is empty and the listbox is already closed, the next Backspace removes the last selected field. Ordinary Backspace edits table query text when the listbox is closed.",
9869
+ "Duplicate, blank, and unknown field identities are ignored for presentation. Selected fields preserve the consumer's order.",
9870
+ "Inactive search leaves the tab order, closes the field listbox, and does not emit query or field changes."
9871
+ ],
9872
+ "responsiveBehavior": [
9873
+ "The control fills the available inline size supplied by the table toolbar search slot. Selected Chips and the editable query share one horizontal editor lane so the md control does not grow vertically.",
9874
+ "The field popup enters the top layer, aligns its first choice cell with the search control, flips or clamps to the viewport or nearest overlay boundary, and scrolls internally when its catalog is taller than available space.",
9875
+ "Long selected field labels truncate inside their Chips while the input remains available at the inline end of the editor lane. Both suffix actions resolve to the same 24px height as selected Chips. Clear follows the standard md Input recipe—a non-inset sm icon button—while slash is a double-inset md label button. Slash remains rightmost; when query text exposes Clear, a vertical divider separates the two actions."
9876
+ ],
9877
+ "frameworkCaveats": {
9878
+ "customElements": [
9879
+ "Assign columns and selectedFieldIds through JavaScript properties and replace controlled values from dsChange and dsFieldsChange.",
9880
+ "Keep field IDs aligned with the application search index; the component treats IDs as opaque values."
9881
+ ],
9882
+ "react": [
9883
+ "Pass new array references for columns and selectedFieldIds and update controlled state from onDsChange and onDsFieldsChange."
9884
+ ],
9885
+ "angular": [
9886
+ "Import DsTableSearch, bind columns, selectedFieldIds, and value, then update application signals from dsChange and dsFieldsChange."
9887
+ ]
9888
+ },
9889
+ "references": [
9890
+ {
9891
+ "label": "Storybook interaction states",
9892
+ "path": "src/wc/components/TableSearch/TableSearch.stories.ts"
9893
+ },
9894
+ {
9895
+ "label": "Toolbar composition owner",
9896
+ "path": "src/wc/components/TableToolbar/TableToolbar.agent.json"
9897
+ }
9898
+ ]
9899
+ },
9900
+ "api": {
9901
+ "props": {
9902
+ "ariaLabel": {
9903
+ "type": "string",
9904
+ "required": false
9905
+ },
9906
+ "clearLabel": {
9907
+ "type": "string",
9908
+ "required": false
9909
+ },
9910
+ "columns": {
9911
+ "type": "TableColumn[]",
9912
+ "required": false
9913
+ },
9914
+ "fieldMenuLabel": {
9915
+ "type": "string",
9916
+ "required": false
9917
+ },
9918
+ "isInactive": {
9919
+ "type": "boolean",
9920
+ "required": false
9921
+ },
9922
+ "placeholder": {
9923
+ "type": "string",
9924
+ "required": false
9925
+ },
9926
+ "selectedFieldIds": {
9927
+ "type": "string[]",
9928
+ "required": false
9929
+ },
9930
+ "value": {
9931
+ "type": "string",
9932
+ "required": false
9933
+ }
9934
+ },
9935
+ "events": [
9936
+ {
9937
+ "name": "dsChange",
9938
+ "detail": "string"
9939
+ },
9940
+ {
9941
+ "name": "dsClear",
9942
+ "detail": "void"
9943
+ },
9944
+ {
9945
+ "name": "dsFieldsChange",
9946
+ "detail": "TableSearchFieldsChangeDetail"
9947
+ }
9948
+ ],
9949
+ "slots": []
9950
+ },
9951
+ "exports": {
9952
+ "customElement": "ds-table-search",
9953
+ "react": "DsTableSearch",
9954
+ "vue": "DsTableSearch",
9955
+ "angular": "DsTableSearch"
9956
+ },
9957
+ "dependencies": [
9958
+ "@ds-mo/ui",
9959
+ "@ds-mo/tokens",
9960
+ "@ds-mo/icons"
9961
+ ],
9962
+ "componentDependencies": [
9963
+ "button-unfilled",
9964
+ "chip",
9965
+ "divider",
9966
+ "empty-state",
9967
+ "icon",
9968
+ "text"
9969
+ ]
9970
+ },
9603
9971
  {
9604
9972
  "id": "component:ds-table-sort",
9605
9973
  "tag": "ds-table-sort",
@@ -9740,6 +10108,7 @@
9740
10108
  "component:ds-divider",
9741
10109
  "component:ds-input",
9742
10110
  "component:ds-table-filter",
10111
+ "component:ds-table-group",
9743
10112
  "component:ds-select",
9744
10113
  "component:ds-table-sort",
9745
10114
  "component:ds-button-unfilled"
@@ -9753,24 +10122,24 @@
9753
10122
  "states": [
9754
10123
  "The component owns layout only. It never mutates slotted control props, values, menus, loading, persistence, or consequences. Use ds-table-saved-views and ds-table-filter when those interactions need the shared CompoMo behavior while application data and persistence remain external.",
9755
10124
  "Buttons in the toolbar keep their hover and pressed interaction paint without physically scaling, so pointer feedback does not disturb the stable caption geometry.",
9756
- "The start cluster is followed by a decorative vertical divider, then Search, optional leading controls, and one trailing action cluster. The start cluster and divider hide when nothing is projected. Search is a dedicated slot that hides when nothing is projected. Empty leading or trailing clusters add no placeholder chrome. Search is the only toolbar region that shrinks; all action controls retain their control geometry and align directly before the table-owned actions.",
10125
+ "The start cluster is followed by a decorative vertical divider, then Search, optional leading controls, and one trailing action cluster. The start cluster and divider hide when nothing is projected. Search is a dedicated slot that hides when nothing is projected and grows to consume available row space. Empty leading or trailing clusters add no placeholder chrome. Search is the only toolbar region that grows and shrinks; all action controls retain their control geometry and align directly before the table-owned actions.",
9757
10126
  "Column customizer and data-mode switching stay table-owned caption actions. Do not recreate those menus in the toolbar. When slotted into a table header, the table caption owns overflow for the complete toolbar and table-owned action row."
9758
10127
  ],
9759
10128
  "responsiveBehavior": [
9760
10129
  "The start cluster, search, trailing Filter/Sort/Group, and table caption trailing actions stay on one line. Saved views hug their current trigger content up to the compact menu-width token rather than reserving that full width; long names truncate while the dirty dot stays visible. Filter, Sort, and Group triggers cap at the same token, and Sort and Group popups keep that compact menu-width floor. A standalone toolbar owns its horizontal scrolling; inside a table, the complete caption row is the single overflow owner so table-owned actions never remain pinned over scrolling toolbar controls.",
9761
- "Inside a named ds-table container narrower than 900px, Search retains its standard maximum width and flexes smaller only when the complete row needs space. ds-table-filter and ds-table-sort omit their labels and chevrons, and Group controls explicitly opted into collapseLabel become icon-only; each exposes its label through a hover and keyboard-focus tooltip. Empty leading and trailing slot groups do not add spacing. Active filtering or grouping promotes the prefix icon to primary. Sort keeps resting secondary chrome. Table-owned Customize also becomes the icon-only Table menu button at that width with the same tooltip behavior.",
10130
+ "Search consumes the row space left between fixed control groups and flexes smaller when the complete row needs space. Inside a named ds-table container narrower than 900px, ds-table-filter, ds-table-group, and ds-table-sort omit their labels and chevrons; each exposes its label through a hover and keyboard-focus tooltip. Empty leading and trailing slot groups do not add spacing. Active filtering promotes its prefix icon to primary. Group and Sort keep resting secondary chrome. Table-owned Customize also becomes the icon-only Table menu button at that width with the same tooltip behavior.",
9762
10131
  "The scrollbar is visually suppressed without removing touch, trackpad, mouse-wheel, or keyboard scrolling from the overflow container.",
9763
10132
  "Trailing controls remain grouped after leading controls; the toolbar does not collapse controls into an application-specific overflow menu."
9764
10133
  ],
9765
10134
  "frameworkCaveats": {
9766
10135
  "customElements": [
9767
- "Project saved views through slot=start, search through slot=search, additional left-side middle controls through slot=leading, and ds-table-filter, Group, and ds-table-sort through slot=trailing. Set collapseLabel on the Group control and provide contextual accessible names when Table controls is insufficient."
10136
+ "Project saved views through slot=start, search through slot=search, additional left-side middle controls through slot=leading, and ds-table-filter, ds-table-group, and ds-table-sort through slot=trailing. Provide contextual accessible names when Table controls is insufficient."
9768
10137
  ],
9769
10138
  "react": [
9770
- "Set slot=start, slot=search, slot=leading, or slot=trailing on each child control. Use ds-table-filter for the standard Filter recipe, opt Group into collapseLabel, and keep values and event handlers in the application."
10139
+ "Set slot=start, slot=search, slot=leading, or slot=trailing on each child control. Use ds-table-filter and ds-table-group for the standard Filter and Group recipes, and keep values and event handlers in the application."
9771
10140
  ],
9772
10141
  "angular": [
9773
- "Set slot=start, slot=search, slot=leading, or slot=trailing on each child control, use DsTableFilter for the standard Filter recipe, opt Group into collapseLabel, and import the generated adapters."
10142
+ "Set slot=start, slot=search, slot=leading, or slot=trailing on each child control, use DsTableFilter and DsTableGroup for the standard Filter and Group recipes, and import the generated adapters."
9774
10143
  ]
9775
10144
  },
9776
10145
  "references": [