@ds-mo/ui 15.1.1 → 15.3.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 (414) hide show
  1. package/dist/.package-ready.json +1 -1
  2. package/dist/agent-patterns.json +4 -4
  3. package/dist/agent.json +711 -48
  4. package/dist/angular/ds-card-setting.d.ts +1 -1
  5. package/dist/angular/ds-card-setting.js +3 -3
  6. package/dist/angular/ds-input-time.d.ts +1 -1
  7. package/dist/angular/ds-input-time.js +3 -3
  8. package/dist/angular/ds-input.d.ts +5 -1
  9. package/dist/angular/ds-input.js +10 -4
  10. package/dist/angular/ds-map-cluster-marker.d.ts +18 -0
  11. package/dist/angular/ds-map-cluster-marker.js +43 -0
  12. package/dist/angular/ds-map-entity-marker.d.ts +18 -0
  13. package/dist/angular/ds-map-entity-marker.js +43 -0
  14. package/dist/angular/ds-radio-tile.d.ts +15 -0
  15. package/dist/angular/ds-radio-tile.js +43 -0
  16. package/dist/angular/ds-setting-row.d.ts +18 -0
  17. package/dist/angular/ds-setting-row.js +42 -0
  18. package/dist/angular/ds-slider.d.ts +1 -1
  19. package/dist/angular/ds-slider.js +3 -3
  20. package/dist/angular/ds-textarea.d.ts +1 -1
  21. package/dist/angular/ds-textarea.js +3 -3
  22. package/dist/angular/ds-time-picker.d.ts +1 -1
  23. package/dist/angular/ds-time-picker.js +3 -3
  24. package/dist/angular/index.d.ts +1 -1
  25. package/dist/angular/index.js +4 -0
  26. package/dist/angular/number-value-accessor.d.ts +9 -0
  27. package/dist/angular/number-value-accessor.js +39 -0
  28. package/dist/angular/proxies.d.ts +4 -0
  29. package/dist/angular/proxies.js +4 -0
  30. package/dist/angular/radio-value-accessor.d.ts +1 -1
  31. package/dist/angular/radio-value-accessor.js +2 -2
  32. package/dist/angular/select-value-accessor.d.ts +1 -1
  33. package/dist/angular/select-value-accessor.js +2 -2
  34. package/dist/angular/text-value-accessor.d.ts +1 -1
  35. package/dist/angular/text-value-accessor.js +2 -2
  36. package/dist/components/ds-agent-activity.js +1 -1
  37. package/dist/components/ds-agent-questionnaire.js +1 -1
  38. package/dist/components/ds-agent-response.js +1 -1
  39. package/dist/components/ds-agent-source-list.js +1 -1
  40. package/dist/components/ds-agent-tool-call.js +1 -1
  41. package/dist/components/ds-attachment-list.js +1 -1
  42. package/dist/components/ds-badge.js +1 -1
  43. package/dist/components/ds-banner.js +1 -1
  44. package/dist/components/ds-bar-action.js +1 -1
  45. package/dist/components/ds-bar-nav.js +1 -1
  46. package/dist/components/ds-bar-page-title.js +1 -1
  47. package/dist/components/ds-bar-title.js +1 -1
  48. package/dist/components/ds-bar-workflow.js +1 -1
  49. package/dist/components/ds-breadcrumb.js +1 -1
  50. package/dist/components/ds-button-filled.js +1 -1
  51. package/dist/components/ds-button-inverted.js +1 -1
  52. package/dist/components/ds-button-unfilled.js +1 -1
  53. package/dist/components/ds-calendar.js +1 -1
  54. package/dist/components/ds-card-action-center.js +1 -1
  55. package/dist/components/ds-card-chart.js +1 -1
  56. package/dist/components/ds-card-navigation.js +1 -1
  57. package/dist/components/ds-card-overview.js +1 -1
  58. package/dist/components/ds-card-setting.js +1 -1
  59. package/dist/components/ds-card-setting.js.map +1 -1
  60. package/dist/components/ds-card-settings-scope.js +1 -1
  61. package/dist/components/ds-chart-legend.js +1 -1
  62. package/dist/components/ds-chart.js +1 -1
  63. package/dist/components/ds-checkbox.js +1 -1
  64. package/dist/components/ds-chip.js +1 -1
  65. package/dist/components/ds-code-block.js +1 -1
  66. package/dist/components/ds-conversation-list-item.js +1 -1
  67. package/dist/components/ds-conversation-list-section.js +1 -1
  68. package/dist/components/ds-conversation-list.js +1 -1
  69. package/dist/components/ds-data-customize.js +1 -1
  70. package/dist/components/ds-data-customize.js.map +1 -1
  71. package/dist/components/ds-data-filter.js +1 -1
  72. package/dist/components/ds-data-filter.js.map +1 -1
  73. package/dist/components/ds-data-group.js +1 -1
  74. package/dist/components/ds-data-preferences.js +1 -1
  75. package/dist/components/ds-data-preferences.js.map +1 -1
  76. package/dist/components/ds-data-saved-views.js +1 -1
  77. package/dist/components/ds-data-saved-views.js.map +1 -1
  78. package/dist/components/ds-data-search.js +1 -1
  79. package/dist/components/ds-data-search.js.map +1 -1
  80. package/dist/components/ds-data-sort.js +1 -1
  81. package/dist/components/ds-data-toolbar.js +1 -1
  82. package/dist/components/ds-empty-state.js +1 -1
  83. package/dist/components/ds-field.js +1 -1
  84. package/dist/components/ds-filter-menu.js +1 -1
  85. package/dist/components/ds-input-date.js +1 -1
  86. package/dist/components/ds-input-date.js.map +1 -1
  87. package/dist/components/ds-input-time.js +1 -1
  88. package/dist/components/ds-input-time.js.map +1 -1
  89. package/dist/components/ds-input.js +1 -1
  90. package/dist/components/ds-map-cluster-marker.d.ts +11 -0
  91. package/dist/components/ds-map-cluster-marker.js +2 -0
  92. package/dist/components/ds-map-cluster-marker.js.map +1 -0
  93. package/dist/components/ds-map-entity-marker.d.ts +11 -0
  94. package/dist/components/ds-map-entity-marker.js +2 -0
  95. package/dist/components/ds-map-entity-marker.js.map +1 -0
  96. package/dist/components/ds-markdown.js +1 -1
  97. package/dist/components/ds-menu.js +1 -1
  98. package/dist/components/ds-message-actions.js +1 -1
  99. package/dist/components/ds-message-bubble.js +1 -1
  100. package/dist/components/ds-message-bubble.js.map +1 -1
  101. package/dist/components/ds-message-composer.js +1 -1
  102. package/dist/components/ds-message-scroller.js +1 -1
  103. package/dist/components/ds-message.js +1 -1
  104. package/dist/components/ds-mobile-bar-nav.js +1 -1
  105. package/dist/components/ds-mobile-header.js +1 -1
  106. package/dist/components/ds-mobile-section-switcher.js +1 -1
  107. package/dist/components/ds-mobile-sheet-nav.js +1 -1
  108. package/dist/components/ds-modal.js +1 -1
  109. package/dist/components/ds-pagination.js +1 -1
  110. package/dist/components/ds-panel-nav.js +1 -1
  111. package/dist/components/ds-panel-sub-nav.js +1 -1
  112. package/dist/components/ds-panel-tool-header.js +1 -1
  113. package/dist/components/ds-panel-tool-search.js +1 -1
  114. package/dist/components/ds-panel-tool-search.js.map +1 -1
  115. package/dist/components/ds-panel-tools.js +1 -1
  116. package/dist/components/ds-paper-texture.js +1 -1
  117. package/dist/components/ds-radio-tile.d.ts +11 -0
  118. package/dist/components/ds-radio-tile.js +2 -0
  119. package/dist/components/ds-radio-tile.js.map +1 -0
  120. package/dist/components/ds-radio.js +1 -1
  121. package/dist/components/ds-score.js +1 -1
  122. package/dist/components/ds-scroll-overlay.js +1 -1
  123. package/dist/components/ds-select.js +1 -1
  124. package/dist/components/ds-setting-row.d.ts +11 -0
  125. package/dist/components/ds-setting-row.js +2 -0
  126. package/dist/components/ds-setting-row.js.map +1 -0
  127. package/dist/components/ds-shell-app.js +1 -1
  128. package/dist/components/ds-shell-page.js +1 -1
  129. package/dist/components/ds-shell-tools.js +1 -1
  130. package/dist/components/ds-skeleton.js +1 -1
  131. package/dist/components/ds-slider.js +1 -1
  132. package/dist/components/ds-slider.js.map +1 -1
  133. package/dist/components/ds-swatch-picker.js +1 -1
  134. package/dist/components/ds-switch.js +1 -1
  135. package/dist/components/ds-tab-group.js +1 -1
  136. package/dist/components/ds-table.js +1 -1
  137. package/dist/components/ds-table.js.map +1 -1
  138. package/dist/components/ds-tag.js +1 -1
  139. package/dist/components/ds-text.js +1 -1
  140. package/dist/components/ds-textarea.js +1 -1
  141. package/dist/components/ds-textarea.js.map +1 -1
  142. package/dist/components/ds-time-picker.js +1 -1
  143. package/dist/components/ds-toast.js +1 -1
  144. package/dist/components/ds-tooltip-chart.js +1 -1
  145. package/dist/components/ds-tooltip.js +1 -1
  146. package/dist/components/ds-typing-indicator.js +1 -1
  147. package/dist/components/{p-etifxiDc.js → p-3bsypMrY.js} +2 -2
  148. package/dist/components/{p-Bm7rqs3C.js → p-AM_ht6Im.js} +2 -2
  149. package/dist/components/{p-Bm7rqs3C.js.map → p-AM_ht6Im.js.map} +1 -1
  150. package/dist/components/{p-Bn8I7iw6.js → p-AmT4GlhM.js} +2 -2
  151. package/dist/components/{p-FIBCluwV.js → p-B-HOVYoH.js} +2 -2
  152. package/dist/components/{p-CmexIVnE.js → p-B7QEpaMe.js} +2 -2
  153. package/dist/components/{p-CUcUHwI3.js → p-B7bXN-vf.js} +2 -2
  154. package/dist/components/p-BHI4LcGK.js +2 -0
  155. package/dist/components/p-BHI4LcGK.js.map +1 -0
  156. package/dist/components/{p-BhJXmuRA.js → p-BSuMDPaV.js} +2 -2
  157. package/dist/components/{p-0FYD2bev.js → p-BU1B6NW8.js} +2 -2
  158. package/dist/components/{p-Do2FJd1y.js → p-BVwg5XVz.js} +2 -2
  159. package/dist/components/{p-CYzFfFcH.js → p-BXSHN1OK.js} +2 -2
  160. package/dist/components/{p-ljbw3UMZ.js → p-BYJtvRQm.js} +2 -2
  161. package/dist/components/{p-CzIpquvw.js → p-Bh1Fx0aW.js} +2 -2
  162. package/dist/components/{p-CiJ1WR11.js → p-Bm3KWMe4.js} +2 -2
  163. package/dist/components/{p-DVINzOoK.js → p-Bo7GxFBh.js} +2 -2
  164. package/dist/components/{p-8yBdCXCn.js → p-BsM37Prt.js} +2 -2
  165. package/dist/components/p-Bu4OmhKK.js +2 -0
  166. package/dist/components/{p-CdGXzRP8.js.map → p-Bu4OmhKK.js.map} +1 -1
  167. package/dist/components/{p-DpoTwJAR.js → p-BugKaVWc.js} +2 -2
  168. package/dist/components/p-C-c8SJ00.js +2 -0
  169. package/dist/components/p-C-c8SJ00.js.map +1 -0
  170. package/dist/components/{p-Bpd6YCo4.js → p-C3-dcROG.js} +2 -2
  171. package/dist/components/p-C4VeD49U.js +2 -0
  172. package/dist/components/{p-BKZdqJQB.js.map → p-C4VeD49U.js.map} +1 -1
  173. package/dist/components/{p-CNxvnQ6A.js → p-CCpJT31M.js} +2 -2
  174. package/dist/components/p-CCpJT31M.js.map +1 -0
  175. package/dist/components/{p-Dzndkdx5.js → p-CI7c9kp-.js} +2 -2
  176. package/dist/components/{p-CdgOLWX9.js → p-CJD0kLeV.js} +2 -2
  177. package/dist/components/{p-BeNa6tw5.js → p-C_gJD8l3.js} +2 -2
  178. package/dist/components/{p-DwbcNDJF.js → p-Cihjy4WY.js} +2 -2
  179. package/dist/components/{p-BgQMEHRa.js → p-Co5MiPNa.js} +2 -2
  180. package/dist/components/{p-CD4DZPy_.js → p-CrL9wxZg.js} +2 -2
  181. package/dist/components/{p-CGidq1iC.js → p-CuwopElg.js} +2 -2
  182. package/dist/components/p-CwUXroLs.js +2 -0
  183. package/dist/components/{p-etg-Uk1u.js.map → p-CwUXroLs.js.map} +1 -1
  184. package/dist/components/{p-Cqc2U1ZQ.js → p-CzQ_JF6A.js} +2 -2
  185. package/dist/components/{p-BciTtTwx.js → p-CztB8Pbq.js} +2 -2
  186. package/dist/components/{p-BciTtTwx.js.map → p-CztB8Pbq.js.map} +1 -1
  187. package/dist/components/{p-ZhP2tVmM.js → p-D0KD-Nr_.js} +2 -2
  188. package/dist/components/{p-DOAybCp0.js → p-DCLRAH5i.js} +2 -2
  189. package/dist/components/{p-Dn9QHL4O.js → p-DFkw6wrS.js} +2 -2
  190. package/dist/components/{p-D1vQGJzc.js → p-DHapI2sf.js} +2 -2
  191. package/dist/components/p-DQPzqcYR.js +2 -0
  192. package/dist/components/p-DQPzqcYR.js.map +1 -0
  193. package/dist/components/{p-DHICPS4n.js → p-DWmYCOKz.js} +2 -2
  194. package/dist/components/p-DX2RyZba.js +2 -0
  195. package/dist/components/{p-C-3YqeTb.js.map → p-DX2RyZba.js.map} +1 -1
  196. package/dist/components/{p-vfCu7XSc.js → p-DZ58Sg5a.js} +2 -2
  197. package/dist/components/{p-D0y7Sja6.js → p-Dcn1eDVt.js} +2 -2
  198. package/dist/components/{p-E5W27Fu_.js → p-DcrdyDRw.js} +2 -2
  199. package/dist/components/p-DhKvqh5G.js +2 -0
  200. package/dist/components/p-DhKvqh5G.js.map +1 -0
  201. package/dist/components/p-Fkkd3gMB.js +2 -0
  202. package/dist/components/{p-DEW7r0U9.js.map → p-Fkkd3gMB.js.map} +1 -1
  203. package/dist/components/{p-xdmJCPCg.js → p-Gb-vTuXr.js} +2 -2
  204. package/dist/components/p-TVkFIMXz.js +2 -0
  205. package/dist/components/p-TVkFIMXz.js.map +1 -0
  206. package/dist/components/p-cuZva5tl.js +2 -0
  207. package/dist/components/{p-Dw9sE6Iw.js.map → p-cuZva5tl.js.map} +1 -1
  208. package/dist/components/p-fYZK3zqM.js +2 -0
  209. package/dist/components/{p-C6xVxqOn.js.map → p-fYZK3zqM.js.map} +1 -1
  210. package/dist/components/{p-CiH4GG6r.js → p-iGNHXFZA.js} +2 -2
  211. package/dist/components/{p-5URekSny.js → p-lADW-TI8.js} +2 -2
  212. package/dist/components/{p-D922f6Tb.js → p-p_MwknM3.js} +2 -2
  213. package/dist/components/{p-Dfs98tpL.js → p-tJaC01aE.js} +2 -2
  214. package/dist/components/{p-B_jdoM7e.js → p-z8L-YMi3.js} +2 -2
  215. package/dist/docs/components.json +1909 -44
  216. package/dist/framework/angular.d.ts +1 -0
  217. package/dist/framework/angular.js +1 -0
  218. package/dist/lint/index.js +1 -1
  219. package/dist/mcp-data/registry/agent-activity.json +2 -2
  220. package/dist/mcp-data/registry/agent-questionnaire.json +2 -2
  221. package/dist/mcp-data/registry/agent-response.json +2 -2
  222. package/dist/mcp-data/registry/agent-source-list.json +2 -2
  223. package/dist/mcp-data/registry/agent-tool-call.json +2 -2
  224. package/dist/mcp-data/registry/attachment-list.json +2 -2
  225. package/dist/mcp-data/registry/avatar.json +2 -2
  226. package/dist/mcp-data/registry/badge.json +2 -2
  227. package/dist/mcp-data/registry/banner.json +2 -2
  228. package/dist/mcp-data/registry/bar-action.json +2 -2
  229. package/dist/mcp-data/registry/bar-nav.json +2 -2
  230. package/dist/mcp-data/registry/bar-page-title.json +2 -2
  231. package/dist/mcp-data/registry/bar-title.json +4 -4
  232. package/dist/mcp-data/registry/bar-workflow.json +2 -2
  233. package/dist/mcp-data/registry/breadcrumb.json +2 -2
  234. package/dist/mcp-data/registry/button-filled.json +2 -2
  235. package/dist/mcp-data/registry/button-inverted.json +2 -2
  236. package/dist/mcp-data/registry/button-unfilled.json +2 -2
  237. package/dist/mcp-data/registry/calendar.json +2 -2
  238. package/dist/mcp-data/registry/card-action-center.json +2 -2
  239. package/dist/mcp-data/registry/card-chart.json +2 -2
  240. package/dist/mcp-data/registry/card-navigation.json +2 -2
  241. package/dist/mcp-data/registry/card-overview.json +2 -2
  242. package/dist/mcp-data/registry/card-setting.json +36 -15
  243. package/dist/mcp-data/registry/card-settings-scope.json +2 -2
  244. package/dist/mcp-data/registry/chart-legend.json +2 -2
  245. package/dist/mcp-data/registry/chart.json +2 -2
  246. package/dist/mcp-data/registry/checkbox.json +2 -2
  247. package/dist/mcp-data/registry/chip.json +2 -2
  248. package/dist/mcp-data/registry/code-block.json +2 -2
  249. package/dist/mcp-data/registry/conversation-list-item.json +2 -2
  250. package/dist/mcp-data/registry/conversation-list-section.json +2 -2
  251. package/dist/mcp-data/registry/conversation-list.json +2 -2
  252. package/dist/mcp-data/registry/data-customize.json +3 -3
  253. package/dist/mcp-data/registry/data-filter.json +2 -2
  254. package/dist/mcp-data/registry/data-group.json +2 -2
  255. package/dist/mcp-data/registry/data-preferences.json +2 -2
  256. package/dist/mcp-data/registry/data-saved-views.json +2 -2
  257. package/dist/mcp-data/registry/data-search.json +2 -2
  258. package/dist/mcp-data/registry/data-sort.json +2 -2
  259. package/dist/mcp-data/registry/data-toolbar.json +2 -2
  260. package/dist/mcp-data/registry/divider.json +2 -2
  261. package/dist/mcp-data/registry/empty-state.json +27 -14
  262. package/dist/mcp-data/registry/field.json +6 -5
  263. package/dist/mcp-data/registry/filter-menu.json +2 -2
  264. package/dist/mcp-data/registry/icon.json +2 -2
  265. package/dist/mcp-data/registry/input-date.json +2 -2
  266. package/dist/mcp-data/registry/input-time.json +26 -7
  267. package/dist/mcp-data/registry/input.json +265 -15
  268. package/dist/mcp-data/registry/loader.json +2 -2
  269. package/dist/mcp-data/registry/map-cluster-marker.json +263 -0
  270. package/dist/mcp-data/registry/map-entity-marker.json +321 -0
  271. package/dist/mcp-data/registry/markdown.json +2 -2
  272. package/dist/mcp-data/registry/menu.json +2 -2
  273. package/dist/mcp-data/registry/message-actions.json +2 -2
  274. package/dist/mcp-data/registry/message-bubble.json +2 -2
  275. package/dist/mcp-data/registry/message-composer.json +2 -2
  276. package/dist/mcp-data/registry/message-scroller.json +2 -2
  277. package/dist/mcp-data/registry/message.json +2 -2
  278. package/dist/mcp-data/registry/mobile-bar-nav.json +2 -2
  279. package/dist/mcp-data/registry/mobile-header.json +2 -2
  280. package/dist/mcp-data/registry/mobile-section-switcher.json +2 -2
  281. package/dist/mcp-data/registry/mobile-sheet-nav.json +2 -2
  282. package/dist/mcp-data/registry/modal.json +2 -2
  283. package/dist/mcp-data/registry/pagination.json +2 -2
  284. package/dist/mcp-data/registry/panel-nav.json +2 -2
  285. package/dist/mcp-data/registry/panel-sub-nav.json +2 -2
  286. package/dist/mcp-data/registry/panel-tool-header.json +2 -2
  287. package/dist/mcp-data/registry/panel-tool-search.json +2 -2
  288. package/dist/mcp-data/registry/panel-tools.json +2 -2
  289. package/dist/mcp-data/registry/paper-texture.json +2 -2
  290. package/dist/mcp-data/registry/radio-tile.json +398 -0
  291. package/dist/mcp-data/registry/radio.json +2 -2
  292. package/dist/mcp-data/registry/registry.json +724 -49
  293. package/dist/mcp-data/registry/score.json +2 -2
  294. package/dist/mcp-data/registry/scroll-overlay.json +2 -2
  295. package/dist/mcp-data/registry/select.json +2 -2
  296. package/dist/mcp-data/registry/setting-row.json +213 -0
  297. package/dist/mcp-data/registry/shell-app.json +3 -3
  298. package/dist/mcp-data/registry/shell-page.json +5 -5
  299. package/dist/mcp-data/registry/shell-tools.json +2 -2
  300. package/dist/mcp-data/registry/skeleton.json +2 -2
  301. package/dist/mcp-data/registry/slider.json +32 -12
  302. package/dist/mcp-data/registry/swatch-picker.json +2 -2
  303. package/dist/mcp-data/registry/switch.json +2 -2
  304. package/dist/mcp-data/registry/tab-group.json +2 -2
  305. package/dist/mcp-data/registry/table.json +5 -5
  306. package/dist/mcp-data/registry/tag.json +2 -2
  307. package/dist/mcp-data/registry/text.json +2 -2
  308. package/dist/mcp-data/registry/textarea.json +72 -5
  309. package/dist/mcp-data/registry/time-picker.json +28 -9
  310. package/dist/mcp-data/registry/toast.json +2 -2
  311. package/dist/mcp-data/registry/tooltip-chart.json +2 -2
  312. package/dist/mcp-data/registry/tooltip.json +2 -2
  313. package/dist/mcp-data/registry/typing-indicator.json +2 -2
  314. package/dist/react/components.d.ts +4 -0
  315. package/dist/react/components.js +4 -0
  316. package/dist/react/ds-input.d.ts +2 -0
  317. package/dist/react/ds-input.js +2 -0
  318. package/dist/react/ds-map-cluster-marker.d.ts +12 -0
  319. package/dist/react/ds-map-cluster-marker.js +12 -0
  320. package/dist/react/ds-map-entity-marker.d.ts +12 -0
  321. package/dist/react/ds-map-entity-marker.js +12 -0
  322. package/dist/react/ds-radio-tile.d.ts +12 -0
  323. package/dist/react/ds-radio-tile.js +12 -0
  324. package/dist/react/ds-setting-row.d.ts +12 -0
  325. package/dist/react/ds-setting-row.js +12 -0
  326. package/dist/types/components/CardSetting/CardSetting.d.ts +5 -3
  327. package/dist/types/components/CardSetting/index.d.ts +1 -1
  328. package/dist/types/components/EmptyState/EmptyState.d.ts +3 -0
  329. package/dist/types/components/Field/Field.d.ts +4 -0
  330. package/dist/types/components/Input/Input.d.ts +50 -1
  331. package/dist/types/components/InputTime/InputTime.d.ts +3 -0
  332. package/dist/types/components/MapClusterMarker/MapClusterMarker.d.ts +19 -0
  333. package/dist/types/components/MapEntityMarker/MapEntityMarker.d.ts +26 -0
  334. package/dist/types/components/RadioTile/RadioTile.d.ts +40 -0
  335. package/dist/types/components/RadioTile/index.d.ts +2 -0
  336. package/dist/types/components/SettingRow/SettingRow.d.ts +18 -0
  337. package/dist/types/components/Slider/Slider.d.ts +8 -1
  338. package/dist/types/components/Slider/index.d.ts +1 -1
  339. package/dist/types/components/Textarea/Textarea.d.ts +12 -0
  340. package/dist/types/components/TimePicker/TimePicker.d.ts +4 -0
  341. package/dist/types/components.d.ts +627 -11
  342. package/dist/types/utils/text-constraints.d.ts +20 -0
  343. package/dist/vue/components.d.ts +4 -0
  344. package/dist/vue/components.js +4 -0
  345. package/dist/vue/ds-card-setting.js +1 -0
  346. package/dist/vue/ds-input-time.js +1 -0
  347. package/dist/vue/ds-input.js +17 -0
  348. package/dist/vue/ds-map-cluster-marker.d.ts +3 -0
  349. package/dist/vue/ds-map-cluster-marker.js +14 -0
  350. package/dist/vue/ds-map-entity-marker.d.ts +3 -0
  351. package/dist/vue/ds-map-entity-marker.js +17 -0
  352. package/dist/vue/ds-radio-tile.d.ts +3 -0
  353. package/dist/vue/ds-radio-tile.js +24 -0
  354. package/dist/vue/ds-setting-row.d.ts +3 -0
  355. package/dist/vue/ds-setting-row.js +14 -0
  356. package/dist/vue/ds-slider.d.ts +1 -1
  357. package/dist/vue/ds-slider.js +2 -1
  358. package/dist/vue/ds-textarea.js +4 -0
  359. package/dist/vue/ds-time-picker.js +1 -0
  360. package/package.json +5 -5
  361. package/dist/components/p-0qY_HDId.js +0 -2
  362. package/dist/components/p-0qY_HDId.js.map +0 -1
  363. package/dist/components/p-BKZdqJQB.js +0 -2
  364. package/dist/components/p-C-3YqeTb.js +0 -2
  365. package/dist/components/p-C6xVxqOn.js +0 -2
  366. package/dist/components/p-CNxvnQ6A.js.map +0 -1
  367. package/dist/components/p-CdGXzRP8.js +0 -2
  368. package/dist/components/p-DEW7r0U9.js +0 -2
  369. package/dist/components/p-DVOjjuXc.js +0 -2
  370. package/dist/components/p-DVOjjuXc.js.map +0 -1
  371. package/dist/components/p-Di5FH7eh.js +0 -2
  372. package/dist/components/p-Di5FH7eh.js.map +0 -1
  373. package/dist/components/p-Dw9sE6Iw.js +0 -2
  374. package/dist/components/p-etg-Uk1u.js +0 -2
  375. package/dist/components/p-xtGGIZmU.js +0 -2
  376. package/dist/components/p-xtGGIZmU.js.map +0 -1
  377. /package/dist/components/{p-etifxiDc.js.map → p-3bsypMrY.js.map} +0 -0
  378. /package/dist/components/{p-Bn8I7iw6.js.map → p-AmT4GlhM.js.map} +0 -0
  379. /package/dist/components/{p-FIBCluwV.js.map → p-B-HOVYoH.js.map} +0 -0
  380. /package/dist/components/{p-CmexIVnE.js.map → p-B7QEpaMe.js.map} +0 -0
  381. /package/dist/components/{p-CUcUHwI3.js.map → p-B7bXN-vf.js.map} +0 -0
  382. /package/dist/components/{p-BhJXmuRA.js.map → p-BSuMDPaV.js.map} +0 -0
  383. /package/dist/components/{p-0FYD2bev.js.map → p-BU1B6NW8.js.map} +0 -0
  384. /package/dist/components/{p-Do2FJd1y.js.map → p-BVwg5XVz.js.map} +0 -0
  385. /package/dist/components/{p-CYzFfFcH.js.map → p-BXSHN1OK.js.map} +0 -0
  386. /package/dist/components/{p-ljbw3UMZ.js.map → p-BYJtvRQm.js.map} +0 -0
  387. /package/dist/components/{p-CzIpquvw.js.map → p-Bh1Fx0aW.js.map} +0 -0
  388. /package/dist/components/{p-CiJ1WR11.js.map → p-Bm3KWMe4.js.map} +0 -0
  389. /package/dist/components/{p-DVINzOoK.js.map → p-Bo7GxFBh.js.map} +0 -0
  390. /package/dist/components/{p-8yBdCXCn.js.map → p-BsM37Prt.js.map} +0 -0
  391. /package/dist/components/{p-DpoTwJAR.js.map → p-BugKaVWc.js.map} +0 -0
  392. /package/dist/components/{p-Bpd6YCo4.js.map → p-C3-dcROG.js.map} +0 -0
  393. /package/dist/components/{p-Dzndkdx5.js.map → p-CI7c9kp-.js.map} +0 -0
  394. /package/dist/components/{p-CdgOLWX9.js.map → p-CJD0kLeV.js.map} +0 -0
  395. /package/dist/components/{p-BeNa6tw5.js.map → p-C_gJD8l3.js.map} +0 -0
  396. /package/dist/components/{p-DwbcNDJF.js.map → p-Cihjy4WY.js.map} +0 -0
  397. /package/dist/components/{p-BgQMEHRa.js.map → p-Co5MiPNa.js.map} +0 -0
  398. /package/dist/components/{p-CD4DZPy_.js.map → p-CrL9wxZg.js.map} +0 -0
  399. /package/dist/components/{p-CGidq1iC.js.map → p-CuwopElg.js.map} +0 -0
  400. /package/dist/components/{p-Cqc2U1ZQ.js.map → p-CzQ_JF6A.js.map} +0 -0
  401. /package/dist/components/{p-ZhP2tVmM.js.map → p-D0KD-Nr_.js.map} +0 -0
  402. /package/dist/components/{p-DOAybCp0.js.map → p-DCLRAH5i.js.map} +0 -0
  403. /package/dist/components/{p-Dn9QHL4O.js.map → p-DFkw6wrS.js.map} +0 -0
  404. /package/dist/components/{p-D1vQGJzc.js.map → p-DHapI2sf.js.map} +0 -0
  405. /package/dist/components/{p-DHICPS4n.js.map → p-DWmYCOKz.js.map} +0 -0
  406. /package/dist/components/{p-vfCu7XSc.js.map → p-DZ58Sg5a.js.map} +0 -0
  407. /package/dist/components/{p-D0y7Sja6.js.map → p-Dcn1eDVt.js.map} +0 -0
  408. /package/dist/components/{p-E5W27Fu_.js.map → p-DcrdyDRw.js.map} +0 -0
  409. /package/dist/components/{p-xdmJCPCg.js.map → p-Gb-vTuXr.js.map} +0 -0
  410. /package/dist/components/{p-CiH4GG6r.js.map → p-iGNHXFZA.js.map} +0 -0
  411. /package/dist/components/{p-5URekSny.js.map → p-lADW-TI8.js.map} +0 -0
  412. /package/dist/components/{p-D922f6Tb.js.map → p-p_MwknM3.js.map} +0 -0
  413. /package/dist/components/{p-Dfs98tpL.js.map → p-tJaC01aE.js.map} +0 -0
  414. /package/dist/components/{p-B_jdoM7e.js.map → p-z8L-YMi3.js.map} +0 -0
@@ -52,7 +52,8 @@
52
52
  "The default four visible rows can be changed with rows; rows is clamped to at least one.",
53
53
  "Vertical resizing is enabled by default and can be disabled when the surrounding layout owns the field height.",
54
54
  "Size changes typography and inset spacing without changing the authored row count.",
55
- "Border, focus, error, placeholder, inactive, hover, and pressed treatments follow the same shared recipes as Input. When hasBorder is false, supporting error copy insets to the text origin rather than the resting border box."
55
+ "Border, focus, error, placeholder, inactive, hover, and pressed treatments follow the same shared recipes as Input. When hasBorder is false, supporting error copy insets to the text origin rather than the resting border box.",
56
+ "Length constraints validate typed and programmatic text. Excess content is retained with an error by default; restrict mode enforces the maximum during editing. A character count appears below the field, right of supporting text or left when no supporting text exists."
56
57
  ],
57
58
  "responsiveBehavior": [
58
59
  "Textarea fills its parent by default and follows the width supplied by Field or the form layout.",
@@ -241,6 +242,31 @@
241
242
  "required": false,
242
243
  "mutable": false
243
244
  },
245
+ "lengthBehavior": {
246
+ "type": "'error' | 'restrict'",
247
+ "resolvedType": "\"error\" | \"restrict\"",
248
+ "attribute": "length-behavior",
249
+ "default": "'error'",
250
+ "required": false,
251
+ "mutable": false,
252
+ "description": "Error preserves extra text; restrict uses the browser's hard input limit."
253
+ },
254
+ "maxLength": {
255
+ "type": "number | undefined",
256
+ "resolvedType": "number | undefined",
257
+ "attribute": "max-length",
258
+ "required": false,
259
+ "mutable": false,
260
+ "description": "Maximum text length. A visible counter accompanies this constraint by default."
261
+ },
262
+ "minLength": {
263
+ "type": "number | undefined",
264
+ "resolvedType": "number | undefined",
265
+ "attribute": "min-length",
266
+ "required": false,
267
+ "mutable": false,
268
+ "description": "Minimum non-empty text length, in native UTF-16 code units."
269
+ },
244
270
  "name": {
245
271
  "type": "string | undefined",
246
272
  "resolvedType": "string | undefined",
@@ -298,6 +324,14 @@
298
324
  "mutable": false,
299
325
  "description": "Visible text rows before the field scrolls."
300
326
  },
327
+ "showCharacterCount": {
328
+ "type": "boolean",
329
+ "resolvedType": "boolean",
330
+ "attribute": "show-character-count",
331
+ "default": "true",
332
+ "required": false,
333
+ "mutable": false
334
+ },
301
335
  "size": {
302
336
  "type": "TextareaSize",
303
337
  "resolvedType": "\"lg\" | \"md\" | \"sm\" | \"xs\"",
@@ -472,6 +506,31 @@
472
506
  "required": false,
473
507
  "mutable": false
474
508
  },
509
+ "lengthBehavior": {
510
+ "type": "'error' | 'restrict'",
511
+ "resolvedType": "\"error\" | \"restrict\"",
512
+ "attribute": "length-behavior",
513
+ "default": "'error'",
514
+ "required": false,
515
+ "mutable": false,
516
+ "description": "Error preserves extra text; restrict uses the browser's hard input limit."
517
+ },
518
+ "maxLength": {
519
+ "type": "number | undefined",
520
+ "resolvedType": "number | undefined",
521
+ "attribute": "max-length",
522
+ "required": false,
523
+ "mutable": false,
524
+ "description": "Maximum text length. A visible counter accompanies this constraint by default."
525
+ },
526
+ "minLength": {
527
+ "type": "number | undefined",
528
+ "resolvedType": "number | undefined",
529
+ "attribute": "min-length",
530
+ "required": false,
531
+ "mutable": false,
532
+ "description": "Minimum non-empty text length, in native UTF-16 code units."
533
+ },
475
534
  "name": {
476
535
  "type": "string | undefined",
477
536
  "resolvedType": "string | undefined",
@@ -529,6 +588,14 @@
529
588
  "mutable": false,
530
589
  "description": "Visible text rows before the field scrolls."
531
590
  },
591
+ "showCharacterCount": {
592
+ "type": "boolean",
593
+ "resolvedType": "boolean",
594
+ "attribute": "show-character-count",
595
+ "default": "true",
596
+ "required": false,
597
+ "mutable": false
598
+ },
532
599
  "size": {
533
600
  "type": "TextareaSize",
534
601
  "resolvedType": "\"lg\" | \"md\" | \"sm\" | \"xs\"",
@@ -608,8 +675,8 @@
608
675
  },
609
676
  "peerDependencies": {
610
677
  "required": [
611
- "@ds-mo/tokens ^6.5.1",
612
- "@ds-mo/icons ^8.1.0"
678
+ "@ds-mo/tokens ^6.5.2",
679
+ "@ds-mo/icons ^8.1.1"
613
680
  ],
614
681
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
615
682
  }
@@ -625,12 +692,12 @@
625
692
  "files": [
626
693
  {
627
694
  "path": "src/wc/components/Textarea/Textarea.css",
628
- "content": "@import '../../utils/interaction-fill.css';\n@import '../../utils/focus-ring.css';\n@import '../../utils/control-inactive.css';\n@import '../../utils/radius.css';\n@import '../../utils/control-density.css';\n@import '../../utils/control-width.css';\n@import '../../utils/field-stack.css';\n@import '../../utils/typography.css';\n@import '../../utils/forced-colors.css';\n\n:host(.textarea-host) {\n display: inline-flex;\n --ds-textarea-fg: var(--color-foreground-primary);\n --ds-textarea-placeholder: var(--color-foreground-secondary);\n --ds-textarea-placeholder-active: var(--color-foreground-quaternary);\n --ds-textarea-border: var(--color-border-secondary);\n}\n\n:host(.ds-control-width--fill),\n:host(.ds-control-width--fill) .textarea-control {\n width: 100%;\n}\n\n.textarea-control {\n display: flex;\n box-sizing: border-box;\n min-width: 0;\n overflow: hidden;\n background: transparent;\n border: none;\n border-radius: var(--ds-control-radius, var(--dimension-radius-025));\n color: var(--ds-textarea-fg);\n}\n\n.textarea-control--resizable {\n padding-block-end: var(--dimension-space-025);\n padding-inline-end: var(--dimension-space-025);\n}\n\n.textarea-control--bordered {\n --ds-interaction-border-width: var(--dimension-stroke-width-012);\n --ds-interaction-border-color: var(--ds-textarea-border);\n}\n\n.textarea-control--error {\n --ds-interaction-border-width: var(--dimension-stroke-width-018);\n --ds-interaction-border-color: var(--color-border-bold-negative);\n}\n\n.textarea-control--bordered:focus-within:not(.textarea-control--error) {\n --ds-interaction-border-width: var(--dimension-stroke-width-018);\n --ds-interaction-border-color: var(--color-border-bold-brand);\n}\n\n:host(.ds-control-inactive) .textarea-control::after {\n background: transparent;\n}\n\n.native-textarea {\n position: relative;\n z-index: 2;\n box-sizing: border-box;\n min-width: 0;\n width: 100%;\n padding-block: var(--ds-control-padding-inline, var(--dimension-space-075));\n padding-inline: calc(\n var(--ds-control-padding-inline, var(--dimension-space-075)) +\n var(--ds-control-label-inset, var(--dimension-space-025))\n );\n background: transparent;\n border: none;\n border-radius: inherit;\n outline: none;\n color: var(--ds-textarea-fg);\n font-family: inherit;\n -webkit-appearance: none;\n appearance: none;\n}\n\n.native-textarea--resize-vertical {\n resize: vertical;\n}\n\n.native-textarea--resize-none {\n resize: none;\n}\n\n.native-textarea:disabled {\n cursor: not-allowed;\n}\n\n.native-textarea:read-only:not(:disabled) {\n cursor: default;\n}\n\n.native-textarea::placeholder {\n color: var(--ds-textarea-placeholder);\n}\n\n.native-textarea:focus::placeholder {\n color: var(--ds-textarea-placeholder-active);\n}\n\n.error-text {\n width: 100%;\n}\n\n@media (forced-colors: active) {\n .textarea-control--bordered:focus-within:not(.textarea-control--error)::after {\n outline-color: var(--ds-forced-color-selected);\n }\n\n .textarea-control--error::after {\n outline-style: dashed;\n }\n}\n",
695
+ "content": "@import '../../utils/text-field-support.css';\n@import '../../utils/interaction-fill.css';\n@import '../../utils/focus-ring.css';\n@import '../../utils/control-inactive.css';\n@import '../../utils/radius.css';\n@import '../../utils/control-density.css';\n@import '../../utils/control-width.css';\n@import '../../utils/field-stack.css';\n@import '../../utils/typography.css';\n@import '../../utils/forced-colors.css';\n\n:host(.textarea-host) {\n display: inline-flex;\n --ds-textarea-fg: var(--color-foreground-primary);\n --ds-textarea-placeholder: var(--color-foreground-secondary);\n --ds-textarea-placeholder-active: var(--color-foreground-quaternary);\n --ds-textarea-border: var(--color-border-secondary);\n}\n\n:host(.ds-control-width--fill),\n:host(.ds-control-width--fill) .textarea-control {\n width: 100%;\n}\n\n.textarea-control {\n display: flex;\n box-sizing: border-box;\n min-width: 0;\n overflow: hidden;\n background: transparent;\n border: none;\n border-radius: var(--ds-control-radius, var(--dimension-radius-025));\n color: var(--ds-textarea-fg);\n}\n\n.textarea-control--resizable {\n padding-block-end: var(--dimension-space-025);\n padding-inline-end: var(--dimension-space-025);\n}\n\n.textarea-control--bordered {\n --ds-interaction-border-width: var(--dimension-stroke-width-012);\n --ds-interaction-border-color: var(--ds-textarea-border);\n}\n\n.textarea-control--error {\n --ds-interaction-border-width: var(--dimension-stroke-width-018);\n --ds-interaction-border-color: var(--color-border-bold-negative);\n}\n\n.textarea-control--bordered:focus-within:not(.textarea-control--error) {\n --ds-interaction-border-width: var(--dimension-stroke-width-018);\n --ds-interaction-border-color: var(--color-border-bold-brand);\n}\n\n:host(.ds-control-inactive) .textarea-control::after {\n background: transparent;\n}\n\n.native-textarea {\n position: relative;\n z-index: 2;\n box-sizing: border-box;\n min-width: 0;\n width: 100%;\n padding-block: var(--ds-control-padding-inline, var(--dimension-space-075));\n padding-inline: calc(\n var(--ds-control-padding-inline, var(--dimension-space-075)) +\n var(--ds-control-label-inset, var(--dimension-space-025))\n );\n background: transparent;\n border: none;\n border-radius: inherit;\n outline: none;\n color: var(--ds-textarea-fg);\n font-family: inherit;\n -webkit-appearance: none;\n appearance: none;\n}\n\n.native-textarea--resize-vertical {\n resize: vertical;\n}\n\n.native-textarea--resize-none {\n resize: none;\n}\n\n.native-textarea:disabled {\n cursor: not-allowed;\n}\n\n.native-textarea:read-only:not(:disabled) {\n cursor: default;\n}\n\n.native-textarea::placeholder {\n color: var(--ds-textarea-placeholder);\n}\n\n.native-textarea:focus::placeholder {\n color: var(--ds-textarea-placeholder-active);\n}\n\n.error-text {\n width: 100%;\n}\n\n@media (forced-colors: active) {\n .textarea-control--bordered:focus-within:not(.textarea-control--error)::after {\n outline-color: var(--ds-forced-color-selected);\n }\n\n .textarea-control--error::after {\n outline-style: dashed;\n }\n}\n",
629
696
  "type": "registry:ui"
630
697
  },
631
698
  {
632
699
  "path": "src/wc/components/Textarea/Textarea.tsx",
633
- "content": "import {\n AttachInternals,\n Component,\n Element,\n Event,\n EventEmitter,\n Method,\n Prop,\n State,\n Watch,\n h,\n Host,\n} from '@stencil/core';\nimport {\n controlWidthClass,\n CONTROL_TEXT_VARIANT,\n DEFAULT_REQUIRED_MESSAGE,\n restoreStringFormState,\n setFormControlValue,\n setRequiredValidity,\n type ControlWidth,\n} from '../../utils';\n\nexport type TextareaSize = 'lg' | 'md' | 'sm' | 'xs';\nexport type TextareaWidth = ControlWidth;\nexport type TextareaResize = 'vertical' | 'none';\n\nlet idCounter = 0;\n\n@Component({\n tag: 'ds-textarea',\n styleUrl: 'Textarea.css',\n scoped: true,\n formAssociated: true,\n})\nexport class Textarea {\n @Element() el!: HTMLElement;\n @AttachInternals() internals!: ElementInternals;\n\n private generatedId = `ds-textarea-${++idCounter}`;\n private errorId = `${this.generatedId}-error`;\n\n @Prop({ mutable: true }) value: string = '';\n @Prop({ reflect: true }) name: string | undefined;\n @Prop({ reflect: true }) form: string | undefined;\n @Prop({ reflect: true }) disabled: boolean = false;\n /** Keeps the value focusable and submittable while preventing edits. */\n @Prop({ reflect: true }) readOnly: boolean = false;\n @Prop({ reflect: true }) required: boolean = false;\n @Prop() requiredMessage: string = DEFAULT_REQUIRED_MESSAGE;\n @Prop() placeholder: string | undefined;\n /** Visible text rows before the field scrolls. */\n @Prop() rows: number = 4;\n /** Whether the user can resize the field vertically. */\n @Prop() resize: TextareaResize = 'vertical';\n /** Native browser autofill hint. */\n @Prop({ attribute: 'autocomplete' }) autoComplete: string | undefined;\n /** Preferred virtual keyboard without changing the value semantics. */\n @Prop({ attribute: 'inputmode' }) inputMode: string = '';\n /** Preferred virtual-keyboard action label. */\n @Prop({ attribute: 'enterkeyhint' }) enterKeyHint: string = '';\n /** Whether the browser should check spelling and grammar. */\n @Prop({ attribute: 'spellcheck' }) spellCheck: boolean = true;\n /** Control density for typography and inset spacing. */\n @Prop() size: TextareaSize = 'md';\n /** Width fit — fill the parent (default) or hug the available content. */\n @Prop() width: TextareaWidth = 'fill';\n /** Show the standard inset border, including focused and invalid strokes. */\n @Prop() hasBorder: boolean = true;\n /** Show the standard hover and pressed fill when the field is not embedded in interactive chrome. */\n @Prop() hasInteractionFill: boolean = true;\n @Prop() isInactive: boolean = false;\n @Prop() autoFocus: boolean = false;\n @Prop() error: boolean = false;\n @Prop() errorMessage: string | undefined;\n /** Associates the internal textarea with an external <label>. */\n @Prop() inputId: string | undefined;\n @Prop({ attribute: 'aria-label' }) ariaLabel: string | null = null;\n @Prop({ attribute: 'aria-labelledby' }) ariaLabelledby: string | undefined;\n @Prop({ attribute: 'aria-describedby' }) ariaDescribedby: string | undefined;\n\n @Event() dsChange!: EventEmitter<string>;\n\n private initialValue = '';\n private textareaEl?: HTMLTextAreaElement;\n @State() private formDisabled = false;\n @State() private focused = false;\n @State() private touched = false;\n\n componentWillLoad() {\n this.initialValue = this.value;\n this.syncFormValue();\n }\n\n @Watch('value')\n @Watch('disabled')\n @Watch('isInactive')\n @Watch('required')\n syncFormValue() {\n const inactive = this.isInactive || this.disabled || this.formDisabled;\n setFormControlValue(this.internals, this.value, { inactive });\n const missing = this.required && !inactive && this.value.length === 0;\n setRequiredValidity(this.internals, missing, this.requiredMessage);\n }\n\n formDisabledCallback(disabled: boolean) {\n this.formDisabled = disabled;\n this.syncFormValue();\n }\n\n formResetCallback() {\n this.value = this.initialValue;\n }\n\n formStateRestoreCallback(state: string | File | FormData | null) {\n this.value = restoreStringFormState(state);\n }\n\n @Method()\n async setFocus() {\n this.textareaEl?.focus();\n }\n\n private handleInput = (event: Event) => {\n this.value = (event.target as HTMLTextAreaElement).value;\n this.dsChange.emit(this.value);\n };\n\n private handleFocus = () => {\n this.focused = true;\n };\n\n private handleBlur = () => {\n this.focused = false;\n this.touched = true;\n };\n\n render() {\n const inputId = this.inputId ?? this.generatedId;\n const inactive = this.isInactive || this.disabled || this.formDisabled;\n const filled = this.value.length > 0;\n const dirty = this.value !== this.initialValue;\n const showError = this.error && Boolean(this.errorMessage);\n const textVariant = CONTROL_TEXT_VARIANT[this.size];\n const rows = Number.isFinite(this.rows) ? Math.max(1, Math.floor(this.rows)) : 4;\n const describedBy =\n [this.ariaDescribedby, showError ? this.errorId : undefined].filter(Boolean).join(' ') ||\n undefined;\n\n return (\n <Host\n class={{\n 'textarea-host': true,\n 'ds-field-stack': true,\n 'ds-field-stack--supporting-inset': !this.hasBorder,\n 'ds-control-inactive': inactive,\n [`ds-control--${this.size}`]: true,\n ...controlWidthClass(this.width),\n }}\n data-disabled={inactive ? '' : undefined}\n data-readonly={this.readOnly ? '' : undefined}\n data-required={this.required ? '' : undefined}\n data-invalid={this.error ? '' : undefined}\n data-filled={filled ? '' : undefined}\n data-focused={this.focused ? '' : undefined}\n data-dirty={dirty ? '' : undefined}\n data-touched={this.touched ? '' : undefined}\n >\n <div\n class={{\n 'textarea-control': true,\n 'textarea-control--resizable': this.resize === 'vertical',\n 'textarea-control--bordered': this.hasBorder,\n 'textarea-control--error': this.hasBorder && this.error,\n 'ds-interaction-fill': this.hasInteractionFill,\n [`ds-control--${this.size}`]: true,\n }}\n >\n <textarea\n ref={element => {\n this.textareaEl = element;\n }}\n id={inputId}\n value={this.value}\n placeholder={this.placeholder}\n rows={rows}\n disabled={inactive}\n readOnly={this.readOnly}\n required={this.required}\n autoFocus={this.autoFocus}\n autoComplete={this.autoComplete}\n inputMode={this.inputMode || undefined}\n enterKeyHint={this.enterKeyHint || undefined}\n spellcheck={this.spellCheck}\n class={`native-textarea native-textarea--resize-${this.resize} ds-text--${textVariant.replace('text-', '')} ds-text--regular ds-interaction-fill__content`}\n aria-label={this.ariaLabel}\n aria-labelledby={this.ariaLabelledby}\n aria-describedby={describedBy}\n aria-invalid={this.error ? 'true' : undefined}\n onInput={this.handleInput}\n onFocus={this.handleFocus}\n onBlur={this.handleBlur}\n />\n </div>\n {showError && (\n <ds-text\n class=\"error-text\"\n as=\"div\"\n variant=\"text-body-small\"\n color=\"negative\"\n textId={this.errorId}\n role=\"alert\"\n >\n {this.errorMessage}\n </ds-text>\n )}\n </Host>\n );\n }\n}\n",
700
+ "content": "import {\n AttachInternals,\n Component,\n Element,\n Event,\n EventEmitter,\n Method,\n Prop,\n State,\n Watch,\n h,\n Host,\n} from '@stencil/core';\nimport {\n controlWidthClass,\n CONTROL_TEXT_VARIANT,\n DEFAULT_REQUIRED_MESSAGE,\n restoreStringFormState,\n setFormControlValue,\n type ControlWidth,\n} from '../../utils';\n\nimport { lengthLimit, textConstraintValidity } from '../../utils/text-constraints';\n\nexport type TextareaSize = 'lg' | 'md' | 'sm' | 'xs';\nexport type TextareaWidth = ControlWidth;\nexport type TextareaResize = 'vertical' | 'none';\n\nlet idCounter = 0;\n\n@Component({\n tag: 'ds-textarea',\n styleUrl: 'Textarea.css',\n scoped: true,\n formAssociated: true,\n})\nexport class Textarea {\n @Element() el!: HTMLElement;\n @AttachInternals() internals!: ElementInternals;\n\n private generatedId = `ds-textarea-${++idCounter}`;\n private errorId = `${this.generatedId}-error`;\n\n @Prop({ mutable: true }) value: string = '';\n @Prop({ reflect: true }) name: string | undefined;\n @Prop({ reflect: true }) form: string | undefined;\n @Prop({ reflect: true }) disabled: boolean = false;\n /** Keeps the value focusable and submittable while preventing edits. */\n @Prop({ reflect: true }) readOnly: boolean = false;\n @Prop({ reflect: true }) required: boolean = false;\n @Prop() requiredMessage: string = DEFAULT_REQUIRED_MESSAGE;\n /** Minimum non-empty text length, in native UTF-16 code units. */\n @Prop() minLength: number | undefined;\n /** Maximum text length. A visible counter accompanies this constraint by default. */\n @Prop() maxLength: number | undefined;\n /** Error preserves extra text; restrict uses the browser's hard input limit. */\n @Prop() lengthBehavior: 'error' | 'restrict' = 'error';\n @Prop() showCharacterCount: boolean = true;\n @Prop() placeholder: string | undefined;\n /** Visible text rows before the field scrolls. */\n @Prop() rows: number = 4;\n /** Whether the user can resize the field vertically. */\n @Prop() resize: TextareaResize = 'vertical';\n /** Native browser autofill hint. */\n @Prop({ attribute: 'autocomplete' }) autoComplete: string | undefined;\n /** Preferred virtual keyboard without changing the value semantics. */\n @Prop({ attribute: 'inputmode' }) inputMode: string = '';\n /** Preferred virtual-keyboard action label. */\n @Prop({ attribute: 'enterkeyhint' }) enterKeyHint: string = '';\n /** Whether the browser should check spelling and grammar. */\n @Prop({ attribute: 'spellcheck' }) spellCheck: boolean = true;\n /** Control density for typography and inset spacing. */\n @Prop() size: TextareaSize = 'md';\n /** Width fit — fill the parent (default) or hug the available content. */\n @Prop() width: TextareaWidth = 'fill';\n /** Show the standard inset border, including focused and invalid strokes. */\n @Prop() hasBorder: boolean = true;\n /** Show the standard hover and pressed fill when the field is not embedded in interactive chrome. */\n @Prop() hasInteractionFill: boolean = true;\n @Prop() isInactive: boolean = false;\n @Prop() autoFocus: boolean = false;\n @Prop() error: boolean = false;\n @Prop() errorMessage: string | undefined;\n /** Associates the internal textarea with an external <label>. */\n @Prop() inputId: string | undefined;\n @Prop({ attribute: 'aria-label' }) ariaLabel: string | null = null;\n @Prop({ attribute: 'aria-labelledby' }) ariaLabelledby: string | undefined;\n @Prop({ attribute: 'aria-describedby' }) ariaDescribedby: string | undefined;\n\n @Event() dsChange!: EventEmitter<string>;\n\n @State() private constraintMessage = '';\n @State() private submitted = false;\n private get managedByField(): boolean {\n return Boolean(this.el.closest('ds-field'));\n }\n private get visibleConstraintMessage(): string {\n return this.touched ||\n this.submitted ||\n (this.maxLength !== undefined && this.value.length > this.maxLength)\n ? this.constraintMessage\n : '';\n }\n private get hasCounter(): boolean {\n return this.showCharacterCount && lengthLimit(this.maxLength) !== undefined;\n }\n\n private initialValue = '';\n private textareaEl?: HTMLTextAreaElement;\n @State() private formDisabled = false;\n @State() private focused = false;\n @State() private touched = false;\n\n componentWillLoad() {\n this.initialValue = this.value;\n this.syncFormValue();\n }\n\n @Watch('value')\n @Watch('disabled')\n @Watch('isInactive')\n @Watch('required')\n @Watch('readOnly')\n @Watch('minLength')\n @Watch('maxLength')\n @Watch('requiredMessage')\n syncFormValue() {\n const inactive = this.isInactive || this.disabled || this.formDisabled;\n setFormControlValue(this.internals, this.value, { inactive });\n const validity =\n inactive || this.readOnly ? { flags: {}, message: '' } : textConstraintValidity(this);\n this.constraintMessage = validity.message;\n this.internals.setValidity(validity.flags, validity.message);\n }\n\n formDisabledCallback(disabled: boolean) {\n this.formDisabled = disabled;\n this.syncFormValue();\n }\n\n formResetCallback() {\n this.value = this.initialValue;\n this.touched = false;\n this.submitted = false;\n }\n\n formStateRestoreCallback(state: string | File | FormData | null) {\n this.value = restoreStringFormState(state);\n }\n\n @Method()\n async setFocus() {\n this.textareaEl?.focus();\n }\n\n private handleInput = (event: Event) => {\n this.value = (event.target as HTMLTextAreaElement).value;\n this.dsChange.emit(this.value);\n };\n\n private handleFocus = () => {\n this.focused = true;\n };\n\n private handleBlur = () => {\n this.focused = false;\n this.touched = true;\n };\n\n render() {\n const inputId = this.inputId ?? this.generatedId;\n const inactive = this.isInactive || this.disabled || this.formDisabled;\n const filled = this.value.length > 0;\n const dirty = this.value !== this.initialValue;\n const message =\n this.error && this.errorMessage ? this.errorMessage : this.visibleConstraintMessage;\n const invalid = this.error || Boolean(this.visibleConstraintMessage);\n const showError = Boolean(message) && !this.managedByField;\n const showCounter = this.hasCounter && !this.managedByField;\n const textVariant = CONTROL_TEXT_VARIANT[this.size];\n const rows = Number.isFinite(this.rows) ? Math.max(1, Math.floor(this.rows)) : 4;\n const describedBy =\n [\n this.ariaDescribedby,\n showError ? this.errorId : undefined,\n showCounter ? `${this.generatedId}-count` : undefined,\n ]\n .filter(Boolean)\n .join(' ') || undefined;\n\n return (\n <Host\n class={{\n 'textarea-host': true,\n 'ds-field-stack': true,\n 'ds-field-stack--supporting-inset': !this.hasBorder,\n 'ds-control-inactive': inactive,\n [`ds-control--${this.size}`]: true,\n ...controlWidthClass(this.width),\n }}\n data-disabled={inactive ? '' : undefined}\n data-readonly={this.readOnly ? '' : undefined}\n data-required={this.required ? '' : undefined}\n data-invalid={invalid ? '' : undefined}\n data-constraint-message={this.visibleConstraintMessage || undefined}\n data-character-count={this.hasCounter ? String(this.value.length) : undefined}\n data-character-limit={this.hasCounter ? String(lengthLimit(this.maxLength)) : undefined}\n onInvalid={() => {\n this.submitted = true;\n }}\n data-filled={filled ? '' : undefined}\n data-focused={this.focused ? '' : undefined}\n data-dirty={dirty ? '' : undefined}\n data-touched={this.touched ? '' : undefined}\n >\n <div\n class={{\n 'textarea-control': true,\n 'textarea-control--resizable': this.resize === 'vertical',\n 'textarea-control--bordered': this.hasBorder,\n 'textarea-control--error': this.hasBorder && invalid,\n 'ds-interaction-fill': this.hasInteractionFill,\n [`ds-control--${this.size}`]: true,\n }}\n >\n <textarea\n ref={element => {\n this.textareaEl = element;\n }}\n id={inputId}\n value={this.value}\n placeholder={this.placeholder}\n rows={rows}\n disabled={inactive}\n readOnly={this.readOnly}\n required={this.required}\n minLength={lengthLimit(this.minLength)}\n maxLength={this.lengthBehavior === 'restrict' ? lengthLimit(this.maxLength) : undefined}\n autoFocus={this.autoFocus}\n autoComplete={this.autoComplete}\n inputMode={this.inputMode || undefined}\n enterKeyHint={this.enterKeyHint || undefined}\n spellcheck={this.spellCheck}\n class={`native-textarea native-textarea--resize-${this.resize} ds-text--${textVariant.replace('text-', '')} ds-text--regular ds-interaction-fill__content`}\n aria-label={this.ariaLabel}\n aria-labelledby={this.ariaLabelledby}\n aria-describedby={describedBy}\n aria-invalid={invalid ? 'true' : undefined}\n onInput={this.handleInput}\n onFocus={this.handleFocus}\n onBlur={this.handleBlur}\n />\n </div>\n {(showError || showCounter) && (\n <div class=\"text-field-support\">\n {showError && (\n <ds-text\n class=\"error-text\"\n as=\"div\"\n variant=\"text-body-small\"\n color=\"negative\"\n textId={this.errorId}\n role=\"alert\"\n >\n {message}\n </ds-text>\n )}\n {showCounter && (\n <ds-text\n as=\"span\"\n class=\"text-field-count\"\n variant=\"text-body-small\"\n color={invalid ? 'negative' : 'secondary'}\n textId={`${this.generatedId}-count`}\n >\n {this.value.length}/{lengthLimit(this.maxLength)}\n </ds-text>\n )}\n </div>\n )}\n </Host>\n );\n }\n}\n",
634
701
  "type": "registry:ui"
635
702
  }
636
703
  ]
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
3
3
  "name": "time-picker",
4
4
  "title": "TimePicker",
5
- "description": "Bounded 12-hour clock lists for choosing hour, minute, and AM/PM, reused by form time fields.",
5
+ "description": "Bounded 12- or 24-hour clock lists for choosing hour, minute, and AM/PM, reused by form time fields.",
6
6
  "type": "registry:ui",
7
7
  "meta": {
8
8
  "library": "@ds-mo/ui",
@@ -13,7 +13,7 @@
13
13
  "intent": {
14
14
  "audience": "general",
15
15
  "status": "stable",
16
- "summary": "Bounded 12-hour clock lists for choosing hour, minute, and AM/PM, reused by form time fields.",
16
+ "summary": "Bounded 12- or 24-hour clock lists for choosing hour, minute, and AM/PM, reused by form time fields.",
17
17
  "useWhen": [
18
18
  "A user picks a clock time from hour, minute, and AM/PM lists.",
19
19
  "A time field needs 32px clock tiles that match calendar day geometry and the shared choice-list selected treatment."
@@ -41,13 +41,14 @@
41
41
  ],
42
42
  "accessibility": [
43
43
  "Hour, minute, and AM/PM are separate labelled listboxes without visible column headings. Each list keeps one tab stop on the selected option.",
44
- "Arrow keys move to the next or previous option and stop at the first and last values; they do not wrap. Home and End jump to those ends. Left and Right move between columns and stop at Hour and AM/PM.",
44
+ "Arrow keys move to the next or previous option and stop at the first and last values; they do not wrap. Home and End jump to those ends. Left and Right move between columns and stop at the first and last visible columns.",
45
45
  "Inactive pickers disable every option. Optional min and max times disable combinations outside that inclusive bound."
46
46
  ],
47
47
  "states": [
48
48
  "Selected hour, minute, and period tiles use the shared interaction-fill selected wash and primary text. Resting tiles use secondary text on a transparent 32px square.",
49
- "Lists are finite. Hour runs 1 through 12, minutes follow the step, and AM/PM has two values. Scrolling and keyboard movement stop at those ends instead of looping.",
50
- "An empty value highlights 12:00 AM so the lists have a resting selection without inventing a second empty state."
49
+ "Lists are finite. Hours follow the selected clock format, minutes follow the step, and the twelve-hour period list has two values. Scrolling and keyboard movement stop at those ends instead of looping.",
50
+ "An empty value highlights 12:00 AM so the lists have a resting selection without inventing a second empty state.",
51
+ "The default twelve-hour presentation includes AM/PM. Twenty-four-hour presentation uses hours 00–23 and omits the period column; both keep HH:MM form values and the same time bounds."
51
52
  ],
52
53
  "responsiveBehavior": [
53
54
  "The three columns fill the width supplied by the owner. Tile size, 4px gaps, and the seven-tile list viewport are owned here; the owner supplies the popup or pane width."
@@ -91,6 +92,15 @@
91
92
  "mutable": false,
92
93
  "description": "Move keyboard focus into the hour list after the picker is rendered."
93
94
  },
95
+ "hourFormat": {
96
+ "type": "'12' | '24'",
97
+ "resolvedType": "\"12\" | \"24\"",
98
+ "attribute": "hour-format",
99
+ "default": "'12'",
100
+ "required": false,
101
+ "mutable": false,
102
+ "description": "Display 12-hour lists with AM/PM or a 24-hour clock. Stored values remain HH:MM."
103
+ },
94
104
  "isInactive": {
95
105
  "type": "boolean",
96
106
  "resolvedType": "boolean",
@@ -159,6 +169,15 @@
159
169
  "mutable": false,
160
170
  "description": "Move keyboard focus into the hour list after the picker is rendered."
161
171
  },
172
+ "hourFormat": {
173
+ "type": "'12' | '24'",
174
+ "resolvedType": "\"12\" | \"24\"",
175
+ "attribute": "hour-format",
176
+ "default": "'12'",
177
+ "required": false,
178
+ "mutable": false,
179
+ "description": "Display 12-hour lists with AM/PM or a 24-hour clock. Stored values remain HH:MM."
180
+ },
162
181
  "isInactive": {
163
182
  "type": "boolean",
164
183
  "resolvedType": "boolean",
@@ -243,8 +262,8 @@
243
262
  },
244
263
  "peerDependencies": {
245
264
  "required": [
246
- "@ds-mo/tokens ^6.5.1",
247
- "@ds-mo/icons ^8.1.0"
265
+ "@ds-mo/tokens ^6.5.2",
266
+ "@ds-mo/icons ^8.1.1"
248
267
  ],
249
268
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
250
269
  }
@@ -260,12 +279,12 @@
260
279
  "files": [
261
280
  {
262
281
  "path": "src/wc/components/TimePicker/TimePicker.css",
263
- "content": "@import '../../utils/radius.css';\n@import '../../utils/control-density.css';\n@import '../../utils/focus-ring.css';\n@import '../../utils/interaction-fill.css';\n@import '../../utils/forced-colors.css';\n\n:host {\n display: flex;\n min-height: 0;\n flex-direction: column;\n}\n\n.time-picker {\n display: grid;\n grid-template-columns: repeat(3, minmax(var(--dimension-size-400), 1fr));\n column-gap: var(--dimension-space-050);\n min-width: calc(\n (var(--dimension-size-400) * 3) + (var(--dimension-space-050) * 2) +\n (var(--ds-time-picker-padding, var(--dimension-space-100)) * 2)\n );\n padding: var(--ds-time-picker-padding, var(--dimension-space-100));\n}\n\n.time-picker__column {\n display: flex;\n min-width: 0;\n flex-direction: column;\n}\n\n.time-picker__list {\n display: flex;\n flex-direction: column;\n gap: var(--dimension-space-050);\n max-height: calc((var(--dimension-size-400) * 7) + (var(--dimension-space-050) * 6));\n overflow-x: hidden;\n overflow-y: auto;\n overscroll-behavior: contain;\n}\n\n.time-picker-tile {\n appearance: none;\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n min-width: 0;\n width: 100%;\n height: var(--dimension-size-400);\n padding: 0;\n border: 0;\n border-radius: var(--dimension-radius-025);\n background: transparent;\n color: var(--color-foreground-primary);\n cursor: default;\n}\n\n.time-picker-tile:disabled {\n cursor: not-allowed;\n}\n",
282
+ "content": "@import '../../utils/radius.css';\n@import '../../utils/control-density.css';\n@import '../../utils/focus-ring.css';\n@import '../../utils/interaction-fill.css';\n@import '../../utils/forced-colors.css';\n\n:host {\n display: flex;\n min-height: 0;\n flex-direction: column;\n}\n\n.time-picker {\n display: grid;\n grid-template-columns: repeat(3, minmax(var(--dimension-size-400), 1fr));\n column-gap: var(--dimension-space-050);\n min-width: calc(\n (var(--dimension-size-400) * 3) + (var(--dimension-space-050) * 2) +\n (var(--ds-time-picker-padding, var(--dimension-space-100)) * 2)\n );\n padding: var(--ds-time-picker-padding, var(--dimension-space-100));\n}\n\n.time-picker__column {\n display: flex;\n min-width: 0;\n flex-direction: column;\n}\n\n.time-picker__list {\n display: flex;\n flex-direction: column;\n gap: var(--dimension-space-050);\n max-height: calc((var(--dimension-size-400) * 7) + (var(--dimension-space-050) * 6));\n overflow-x: hidden;\n overflow-y: auto;\n overscroll-behavior: contain;\n}\n\n.time-picker-tile {\n appearance: none;\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n min-width: 0;\n width: 100%;\n height: var(--dimension-size-400);\n padding: 0;\n border: 0;\n border-radius: var(--dimension-radius-025);\n background: transparent;\n color: var(--color-foreground-primary);\n cursor: default;\n}\n\n.time-picker-tile:disabled {\n cursor: not-allowed;\n}\n\n.time-picker--24 {\n grid-template-columns: repeat(2, minmax(var(--dimension-size-400), 1fr));\n min-width: calc(\n var(--dimension-size-400) * 2 + var(--dimension-space-050) +\n var(--ds-time-picker-padding, var(--dimension-space-100)) * 2\n );\n}\n",
264
283
  "type": "registry:ui"
265
284
  },
266
285
  {
267
286
  "path": "src/wc/components/TimePicker/TimePicker.tsx",
268
- "content": "import {\n Component,\n Element,\n Event,\n EventEmitter,\n Method,\n Prop,\n Watch,\n h,\n Host,\n} from '@stencil/core';\nimport {\n CLOCK_HOURS,\n CLOCK_PERIODS,\n clockMinuteStep,\n clockMinutes,\n isClockTimeStepAligned,\n isClockTimeOutOfRange,\n joinClockTime,\n splitClockTime,\n stepBoundedIndex,\n type ClockPeriod,\n type ClockTimeParts,\n} from '../../utils';\n\ntype TimePickerColumn = 'hour' | 'minute' | 'period';\n\n@Component({\n tag: 'ds-time-picker',\n styleUrl: 'TimePicker.css',\n scoped: true,\n})\nexport class TimePicker {\n @Element() el!: HTMLElement;\n\n /** Clock value as `HH:MM`. */\n @Prop() value: string = '';\n @Prop() min: string | undefined;\n @Prop() max: string | undefined;\n /** Native time step in seconds. Defaults to minutes (`60`). */\n @Prop() step: string | number = 60;\n @Prop() isInactive: boolean = false;\n /** Move keyboard focus into the hour list after the picker is rendered. */\n @Prop() autoFocus: boolean = false;\n\n @Event() dsChange!: EventEmitter<string>;\n\n componentDidLoad() {\n this.scrollSelectedIntoView();\n if (this.autoFocus) void this.setFocus();\n }\n\n @Watch('value')\n onValueChange() {\n this.scrollSelectedIntoView();\n }\n\n @Method()\n async setFocus() {\n this.focusColumn('hour', CLOCK_HOURS);\n }\n\n private parts(): ClockTimeParts {\n return splitClockTime(this.value) ?? { hour12: 12, minute: 0, period: 'AM' };\n }\n\n private minutes(): number[] {\n const minimum = this.min ? splitClockTime(this.min) : null;\n return clockMinutes(clockMinuteStep(this.step), minimum?.minute ?? 0);\n }\n\n private isDisabledTime(iso: string): boolean {\n if (this.isInactive) return true;\n return (\n isClockTimeOutOfRange(iso, this.min, this.max) ||\n !isClockTimeStepAligned(iso, this.step, this.min)\n );\n }\n\n private optionParts(\n column: TimePickerColumn,\n value: number | ClockPeriod\n ): Partial<ClockTimeParts> {\n return column === 'hour'\n ? { hour12: value as number }\n : column === 'minute'\n ? { minute: value as number }\n : { period: value as ClockPeriod };\n }\n\n private isDisabledPart(column: TimePickerColumn, next: Partial<ClockTimeParts>): boolean {\n if (this.isInactive) return true;\n\n const current = { ...this.parts(), ...next };\n const hours: ReadonlyArray<number> = column === 'hour' ? [current.hour12] : CLOCK_HOURS;\n const minutes: ReadonlyArray<number> = column === 'minute' ? [current.minute] : this.minutes();\n const periods: ReadonlyArray<ClockPeriod> =\n column === 'period' ? [current.period] : CLOCK_PERIODS;\n\n return !hours.some(hour =>\n minutes.some(minute =>\n periods.some(\n period => !this.isDisabledTime(joinClockTime({ hour12: hour, minute, period }))\n )\n )\n );\n }\n\n private orderedValues<T>(current: T, values: ReadonlyArray<T>): T[] {\n return [current, ...values.filter(value => value !== current)];\n }\n\n private commit(column: TimePickerColumn, next: Partial<ClockTimeParts>) {\n const current = { ...this.parts(), ...next };\n const hours =\n column === 'hour' ? [current.hour12] : this.orderedValues(current.hour12, CLOCK_HOURS);\n const minutes =\n column === 'minute' ? [current.minute] : this.orderedValues(current.minute, this.minutes());\n const periods =\n column === 'period' ? [current.period] : this.orderedValues(current.period, CLOCK_PERIODS);\n\n for (const hour of hours) {\n for (const minute of minutes) {\n for (const period of periods) {\n const iso = joinClockTime({ hour12: hour, minute, period });\n if (!this.isDisabledTime(iso)) {\n this.dsChange.emit(iso);\n return;\n }\n }\n }\n }\n }\n\n private optionEl(column: TimePickerColumn, value: number | ClockPeriod): HTMLElement | null {\n return this.el.querySelector<HTMLElement>(`[data-${column}-option=\"${value}\"]`);\n }\n\n private scrollSelectedIntoView() {\n const parts = this.parts();\n this.optionEl('hour', parts.hour12)?.scrollIntoView({ block: 'nearest' });\n this.optionEl('minute', parts.minute)?.scrollIntoView({ block: 'nearest' });\n this.optionEl('period', parts.period)?.scrollIntoView({ block: 'nearest' });\n }\n\n private focusOption(column: TimePickerColumn, value: number | ClockPeriod) {\n requestAnimationFrame(() => {\n this.optionEl(column, value)?.focus();\n });\n }\n\n private focusValue(\n column: TimePickerColumn,\n values: ReadonlyArray<number | ClockPeriod>\n ): number | ClockPeriod | undefined {\n const current = this.parts();\n const currentValue =\n column === 'hour' ? current.hour12 : column === 'minute' ? current.minute : current.period;\n if (!this.isDisabledPart(column, this.optionParts(column, currentValue))) return currentValue;\n return values.find(value => !this.isDisabledPart(column, this.optionParts(column, value)));\n }\n\n private focusColumn(column: TimePickerColumn, values: ReadonlyArray<number | ClockPeriod>): void {\n const value = this.focusValue(column, values);\n if (value !== undefined) this.optionEl(column, value)?.focus();\n }\n\n private handleColumnKeyDown = (\n event: KeyboardEvent,\n column: TimePickerColumn,\n values: ReadonlyArray<number | ClockPeriod>,\n current: number | ClockPeriod\n ) => {\n const columns: TimePickerColumn[] = ['hour', 'minute', 'period'];\n const columnIndex = columns.indexOf(column);\n if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {\n const nextColumn =\n columns[stepBoundedIndex(columnIndex, event.key === 'ArrowLeft' ? -1 : 1, columns.length)];\n if (!nextColumn || nextColumn === column) {\n event.preventDefault();\n return;\n }\n event.preventDefault();\n const nextValues =\n nextColumn === 'hour'\n ? CLOCK_HOURS\n : nextColumn === 'minute'\n ? this.minutes()\n : CLOCK_PERIODS;\n const nextValue = this.focusValue(nextColumn, nextValues);\n if (nextValue !== undefined) this.focusOption(nextColumn, nextValue);\n return;\n }\n\n let offset: number | null = null;\n if (event.key === 'ArrowUp') offset = -1;\n else if (event.key === 'ArrowDown') offset = 1;\n else if (event.key === 'Home' || event.key === 'End') offset = 0;\n if (offset === null) return;\n event.preventDefault();\n let next: number | ClockPeriod | undefined;\n if (event.key === 'Home') {\n next = values.find(value => !this.isDisabledPart(column, this.optionParts(column, value)));\n } else if (event.key === 'End') {\n for (let index = values.length - 1; index >= 0; index -= 1) {\n const value = values[index];\n if (value !== undefined && !this.isDisabledPart(column, this.optionParts(column, value))) {\n next = value;\n break;\n }\n }\n } else {\n const direction = offset;\n let index = values.indexOf(current);\n if (index < 0) index = direction > 0 ? -1 : values.length;\n for (\n let candidate = index + direction;\n candidate >= 0 && candidate < values.length;\n candidate += direction\n ) {\n const value = values[candidate];\n if (value !== undefined && !this.isDisabledPart(column, this.optionParts(column, value))) {\n next = value;\n break;\n }\n }\n }\n if (next === undefined) return;\n this.focusOption(column, next);\n };\n\n private renderTile(\n column: TimePickerColumn,\n value: number | ClockPeriod,\n selected: boolean,\n focused: boolean,\n label: string,\n values: ReadonlyArray<number | ClockPeriod>\n ) {\n const next = this.optionParts(column, value);\n const disabled = this.isDisabledPart(column, next);\n return (\n <button\n type=\"button\"\n role=\"option\"\n data-hour-option={column === 'hour' ? String(value) : undefined}\n data-minute-option={column === 'minute' ? String(value) : undefined}\n data-period-option={column === 'period' ? String(value) : undefined}\n class={{\n 'time-picker-tile': true,\n 'time-picker-tile--selected': selected,\n 'ds-focus-ring-inset': true,\n 'ds-interaction-fill': !disabled,\n 'ds-interaction-fill--selected': selected && !disabled,\n }}\n disabled={disabled}\n aria-selected={selected ? 'true' : 'false'}\n tabIndex={focused ? 0 : -1}\n onClick={() => this.commit(column, next)}\n onKeyDown={event => this.handleColumnKeyDown(event, column, values, value)}\n >\n <ds-text\n class=\"ds-interaction-fill__content\"\n as=\"span\"\n variant=\"text-body-medium\"\n color={selected ? 'primary' : 'secondary'}\n >\n {label}\n </ds-text>\n </button>\n );\n }\n\n render() {\n const parts = this.parts();\n const minutes = this.minutes();\n const minuteValues = minutes.includes(parts.minute)\n ? minutes\n : [...minutes, parts.minute].sort((a, b) => a - b);\n const hourFocus = this.focusValue('hour', CLOCK_HOURS);\n const minuteFocus = this.focusValue('minute', minuteValues);\n const periodFocus = this.focusValue('period', CLOCK_PERIODS);\n\n return (\n <Host>\n <div class=\"time-picker\" role=\"group\" aria-label=\"Choose time\">\n <div class=\"time-picker__column\">\n <div class=\"time-picker__list\" role=\"listbox\" aria-label=\"Hour\">\n {CLOCK_HOURS.map(hour =>\n this.renderTile(\n 'hour',\n hour,\n hour === parts.hour12,\n hour === hourFocus,\n String(hour),\n CLOCK_HOURS\n )\n )}\n </div>\n </div>\n <div class=\"time-picker__column\">\n <div class=\"time-picker__list\" role=\"listbox\" aria-label=\"Minute\">\n {minuteValues.map(minute =>\n this.renderTile(\n 'minute',\n minute,\n minute === parts.minute,\n minute === minuteFocus,\n String(minute).padStart(2, '0'),\n minuteValues\n )\n )}\n </div>\n </div>\n <div class=\"time-picker__column\">\n <div class=\"time-picker__list\" role=\"listbox\" aria-label=\"AM/PM\">\n {CLOCK_PERIODS.map(period =>\n this.renderTile(\n 'period',\n period,\n period === parts.period,\n period === periodFocus,\n period,\n CLOCK_PERIODS\n )\n )}\n </div>\n </div>\n </div>\n </Host>\n );\n }\n}\n",
287
+ "content": "import {\n Component,\n Element,\n Event,\n EventEmitter,\n Method,\n Prop,\n Watch,\n h,\n Host,\n} from '@stencil/core';\nimport {\n CLOCK_HOURS,\n CLOCK_PERIODS,\n clockMinuteStep,\n clockMinutes,\n isClockTimeStepAligned,\n isClockTimeOutOfRange,\n joinClockTime,\n splitClockTime,\n stepBoundedIndex,\n type ClockPeriod,\n type ClockTimeParts,\n} from '../../utils';\n\nconst HOURS_24 = Array.from({ length: 24 }, (_, hour) => hour);\n\ntype TimePickerColumn = 'hour' | 'minute' | 'period';\n\n@Component({\n tag: 'ds-time-picker',\n styleUrl: 'TimePicker.css',\n scoped: true,\n})\nexport class TimePicker {\n @Element() el!: HTMLElement;\n\n /** Clock value as `HH:MM`. */\n @Prop() value: string = '';\n /** Display 12-hour lists with AM/PM or a 24-hour clock. Stored values remain HH:MM. */\n @Prop() hourFormat: '12' | '24' = '12';\n @Prop() min: string | undefined;\n @Prop() max: string | undefined;\n /** Native time step in seconds. Defaults to minutes (`60`). */\n @Prop() step: string | number = 60;\n @Prop() isInactive: boolean = false;\n /** Move keyboard focus into the hour list after the picker is rendered. */\n @Prop() autoFocus: boolean = false;\n\n @Event() dsChange!: EventEmitter<string>;\n\n componentDidLoad() {\n this.scrollSelectedIntoView();\n if (this.autoFocus) void this.setFocus();\n }\n\n @Watch('value')\n @Watch('hourFormat')\n onValueChange() {\n this.scrollSelectedIntoView();\n }\n\n @Method()\n async setFocus() {\n this.focusColumn('hour', this.hours());\n }\n\n private parts(): ClockTimeParts {\n return splitClockTime(this.value) ?? { hour12: 12, minute: 0, period: 'AM' };\n }\n\n private hours(): readonly number[] {\n return this.hourFormat === '24' ? HOURS_24 : CLOCK_HOURS;\n }\n\n private displayHour(): number {\n const parts = this.parts();\n return this.hourFormat === '24'\n ? (parts.hour12 % 12) + (parts.period === 'PM' ? 12 : 0)\n : parts.hour12;\n }\n\n private minutes(): number[] {\n const minimum = this.min ? splitClockTime(this.min) : null;\n return clockMinutes(clockMinuteStep(this.step), minimum?.minute ?? 0);\n }\n\n private isDisabledTime(iso: string): boolean {\n if (this.isInactive) return true;\n return (\n isClockTimeOutOfRange(iso, this.min, this.max) ||\n !isClockTimeStepAligned(iso, this.step, this.min)\n );\n }\n\n private optionParts(\n column: TimePickerColumn,\n value: number | ClockPeriod\n ): Partial<ClockTimeParts> {\n return column === 'hour'\n ? this.hourFormat === '24'\n ? { hour12: Number(value) % 12 || 12, period: Number(value) >= 12 ? 'PM' : 'AM' }\n : { hour12: value as number }\n : column === 'minute'\n ? { minute: value as number }\n : { period: value as ClockPeriod };\n }\n\n private isDisabledPart(column: TimePickerColumn, next: Partial<ClockTimeParts>): boolean {\n if (this.isInactive) return true;\n\n const current = { ...this.parts(), ...next };\n const hours: ReadonlyArray<number> = column === 'hour' ? [current.hour12] : CLOCK_HOURS;\n const minutes: ReadonlyArray<number> = column === 'minute' ? [current.minute] : this.minutes();\n const periods: ReadonlyArray<ClockPeriod> =\n column === 'period' || (column === 'hour' && this.hourFormat === '24')\n ? [current.period]\n : CLOCK_PERIODS;\n\n return !hours.some(hour =>\n minutes.some(minute =>\n periods.some(\n period => !this.isDisabledTime(joinClockTime({ hour12: hour, minute, period }))\n )\n )\n );\n }\n\n private orderedValues<T>(current: T, values: ReadonlyArray<T>): T[] {\n return [current, ...values.filter(value => value !== current)];\n }\n\n private commit(column: TimePickerColumn, next: Partial<ClockTimeParts>) {\n const current = { ...this.parts(), ...next };\n const hours =\n column === 'hour' ? [current.hour12] : this.orderedValues(current.hour12, CLOCK_HOURS);\n const minutes =\n column === 'minute' ? [current.minute] : this.orderedValues(current.minute, this.minutes());\n const periods =\n column === 'period' || (column === 'hour' && this.hourFormat === '24')\n ? [current.period]\n : this.orderedValues(current.period, CLOCK_PERIODS);\n\n for (const hour of hours) {\n for (const minute of minutes) {\n for (const period of periods) {\n const iso = joinClockTime({ hour12: hour, minute, period });\n if (!this.isDisabledTime(iso)) {\n this.dsChange.emit(iso);\n return;\n }\n }\n }\n }\n }\n\n private optionEl(column: TimePickerColumn, value: number | ClockPeriod): HTMLElement | null {\n return this.el.querySelector<HTMLElement>(`[data-${column}-option=\"${value}\"]`);\n }\n\n private scrollSelectedIntoView() {\n const parts = this.parts();\n this.optionEl('hour', this.displayHour())?.scrollIntoView({ block: 'nearest' });\n this.optionEl('minute', parts.minute)?.scrollIntoView({ block: 'nearest' });\n this.optionEl('period', parts.period)?.scrollIntoView({ block: 'nearest' });\n }\n\n private focusOption(column: TimePickerColumn, value: number | ClockPeriod) {\n requestAnimationFrame(() => {\n this.optionEl(column, value)?.focus();\n });\n }\n\n private focusValue(\n column: TimePickerColumn,\n values: ReadonlyArray<number | ClockPeriod>\n ): number | ClockPeriod | undefined {\n const current = this.parts();\n const currentValue =\n column === 'hour'\n ? this.displayHour()\n : column === 'minute'\n ? current.minute\n : current.period;\n if (!this.isDisabledPart(column, this.optionParts(column, currentValue))) return currentValue;\n return values.find(value => !this.isDisabledPart(column, this.optionParts(column, value)));\n }\n\n private focusColumn(column: TimePickerColumn, values: ReadonlyArray<number | ClockPeriod>): void {\n const value = this.focusValue(column, values);\n if (value !== undefined) this.optionEl(column, value)?.focus();\n }\n\n private handleColumnKeyDown = (\n event: KeyboardEvent,\n column: TimePickerColumn,\n values: ReadonlyArray<number | ClockPeriod>,\n current: number | ClockPeriod\n ) => {\n const columns: TimePickerColumn[] =\n this.hourFormat === '24' ? ['hour', 'minute'] : ['hour', 'minute', 'period'];\n const columnIndex = columns.indexOf(column);\n if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {\n const nextColumn =\n columns[stepBoundedIndex(columnIndex, event.key === 'ArrowLeft' ? -1 : 1, columns.length)];\n if (!nextColumn || nextColumn === column) {\n event.preventDefault();\n return;\n }\n event.preventDefault();\n const nextValues =\n nextColumn === 'hour'\n ? this.hours()\n : nextColumn === 'minute'\n ? this.minutes()\n : CLOCK_PERIODS;\n const nextValue = this.focusValue(nextColumn, nextValues);\n if (nextValue !== undefined) this.focusOption(nextColumn, nextValue);\n return;\n }\n\n let offset: number | null = null;\n if (event.key === 'ArrowUp') offset = -1;\n else if (event.key === 'ArrowDown') offset = 1;\n else if (event.key === 'Home' || event.key === 'End') offset = 0;\n if (offset === null) return;\n event.preventDefault();\n let next: number | ClockPeriod | undefined;\n if (event.key === 'Home') {\n next = values.find(value => !this.isDisabledPart(column, this.optionParts(column, value)));\n } else if (event.key === 'End') {\n for (let index = values.length - 1; index >= 0; index -= 1) {\n const value = values[index];\n if (value !== undefined && !this.isDisabledPart(column, this.optionParts(column, value))) {\n next = value;\n break;\n }\n }\n } else {\n const direction = offset;\n let index = values.indexOf(current);\n if (index < 0) index = direction > 0 ? -1 : values.length;\n for (\n let candidate = index + direction;\n candidate >= 0 && candidate < values.length;\n candidate += direction\n ) {\n const value = values[candidate];\n if (value !== undefined && !this.isDisabledPart(column, this.optionParts(column, value))) {\n next = value;\n break;\n }\n }\n }\n if (next === undefined) return;\n this.focusOption(column, next);\n };\n\n private renderTile(\n column: TimePickerColumn,\n value: number | ClockPeriod,\n selected: boolean,\n focused: boolean,\n label: string,\n values: ReadonlyArray<number | ClockPeriod>\n ) {\n const next = this.optionParts(column, value);\n const disabled = this.isDisabledPart(column, next);\n return (\n <button\n type=\"button\"\n role=\"option\"\n data-hour-option={column === 'hour' ? String(value) : undefined}\n data-minute-option={column === 'minute' ? String(value) : undefined}\n data-period-option={column === 'period' ? String(value) : undefined}\n class={{\n 'time-picker-tile': true,\n 'time-picker-tile--selected': selected,\n 'ds-focus-ring-inset': true,\n 'ds-interaction-fill': !disabled,\n 'ds-interaction-fill--selected': selected && !disabled,\n }}\n disabled={disabled}\n aria-selected={selected ? 'true' : 'false'}\n tabIndex={focused ? 0 : -1}\n onClick={() => this.commit(column, next)}\n onKeyDown={event => this.handleColumnKeyDown(event, column, values, value)}\n >\n <ds-text\n class=\"ds-interaction-fill__content\"\n as=\"span\"\n variant=\"text-body-medium\"\n color={selected ? 'primary' : 'secondary'}\n >\n {label}\n </ds-text>\n </button>\n );\n }\n\n render() {\n const parts = this.parts();\n const minutes = this.minutes();\n const minuteValues = minutes.includes(parts.minute)\n ? minutes\n : [...minutes, parts.minute].sort((a, b) => a - b);\n const hourFocus = this.focusValue('hour', this.hours());\n const minuteFocus = this.focusValue('minute', minuteValues);\n const periodFocus = this.focusValue('period', CLOCK_PERIODS);\n\n return (\n <Host>\n <div\n class={{ 'time-picker': true, 'time-picker--24': this.hourFormat === '24' }}\n role=\"group\"\n aria-label=\"Choose time\"\n >\n <div class=\"time-picker__column\">\n <div class=\"time-picker__list\" role=\"listbox\" aria-label=\"Hour\">\n {this.hours().map(hour =>\n this.renderTile(\n 'hour',\n hour,\n hour === this.displayHour(),\n hour === hourFocus,\n this.hourFormat === '24' ? String(hour).padStart(2, '0') : String(hour),\n this.hours()\n )\n )}\n </div>\n </div>\n <div class=\"time-picker__column\">\n <div class=\"time-picker__list\" role=\"listbox\" aria-label=\"Minute\">\n {minuteValues.map(minute =>\n this.renderTile(\n 'minute',\n minute,\n minute === parts.minute,\n minute === minuteFocus,\n String(minute).padStart(2, '0'),\n minuteValues\n )\n )}\n </div>\n </div>\n {this.hourFormat !== '24' && (\n <div class=\"time-picker__column\">\n <div class=\"time-picker__list\" role=\"listbox\" aria-label=\"AM/PM\">\n {CLOCK_PERIODS.map(period =>\n this.renderTile(\n 'period',\n period,\n period === parts.period,\n period === periodFocus,\n period,\n CLOCK_PERIODS\n )\n )}\n </div>\n </div>\n )}\n </div>\n </Host>\n );\n }\n}\n",
269
288
  "type": "registry:ui"
270
289
  }
271
290
  ]
@@ -335,8 +335,8 @@
335
335
  "complexPropertyNote": "Assign these non-primitive values as JavaScript properties: manager, swipeDirections.",
336
336
  "peerDependencies": {
337
337
  "required": [
338
- "@ds-mo/tokens ^6.5.1",
339
- "@ds-mo/icons ^8.1.0"
338
+ "@ds-mo/tokens ^6.5.2",
339
+ "@ds-mo/icons ^8.1.1"
340
340
  ],
341
341
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
342
342
  }
@@ -254,8 +254,8 @@
254
254
  "complexPropertyNote": "Assign these non-primitive values as JavaScript properties: items.",
255
255
  "peerDependencies": {
256
256
  "required": [
257
- "@ds-mo/tokens ^6.5.1",
258
- "@ds-mo/icons ^8.1.0"
257
+ "@ds-mo/tokens ^6.5.2",
258
+ "@ds-mo/icons ^8.1.1"
259
259
  ],
260
260
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
261
261
  }
@@ -386,8 +386,8 @@
386
386
  },
387
387
  "peerDependencies": {
388
388
  "required": [
389
- "@ds-mo/tokens ^6.5.1",
390
- "@ds-mo/icons ^8.1.0"
389
+ "@ds-mo/tokens ^6.5.2",
390
+ "@ds-mo/icons ^8.1.1"
391
391
  ],
392
392
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
393
393
  }
@@ -108,8 +108,8 @@
108
108
  },
109
109
  "peerDependencies": {
110
110
  "required": [
111
- "@ds-mo/tokens ^6.5.1",
112
- "@ds-mo/icons ^8.1.0"
111
+ "@ds-mo/tokens ^6.5.2",
112
+ "@ds-mo/icons ^8.1.1"
113
113
  ],
114
114
  "frameworks": "Custom Elements; React 18/19 wrappers; Vue 3 wrappers; Angular 19-22 standalone adapters."
115
115
  }
@@ -52,6 +52,8 @@ export { DsInputDate } from "./ds-input-date.js";
52
52
  export { DsInputTime } from "./ds-input-time.js";
53
53
  export { DsInput } from "./ds-input.js";
54
54
  export { DsLoader } from "./ds-loader.js";
55
+ export { DsMapClusterMarker } from "./ds-map-cluster-marker.js";
56
+ export { DsMapEntityMarker } from "./ds-map-entity-marker.js";
55
57
  export { DsMarkdown } from "./ds-markdown.js";
56
58
  export { DsMenu } from "./ds-menu.js";
57
59
  export { DsMessageActions } from "./ds-message-actions.js";
@@ -71,10 +73,12 @@ export { DsPanelToolHeader } from "./ds-panel-tool-header.js";
71
73
  export { DsPanelToolSearch } from "./ds-panel-tool-search.js";
72
74
  export { DsPanelTools } from "./ds-panel-tools.js";
73
75
  export { DsPaperTexture } from "./ds-paper-texture.js";
76
+ export { DsRadioTile } from "./ds-radio-tile.js";
74
77
  export { DsRadio } from "./ds-radio.js";
75
78
  export { DsScore } from "./ds-score.js";
76
79
  export { DsScrollOverlay } from "./ds-scroll-overlay.js";
77
80
  export { DsSelect } from "./ds-select.js";
81
+ export { DsSettingRow } from "./ds-setting-row.js";
78
82
  export { DsShellApp } from "./ds-shell-app.js";
79
83
  export { DsShellPage } from "./ds-shell-page.js";
80
84
  export { DsShellTools } from "./ds-shell-tools.js";
@@ -53,6 +53,8 @@ export { DsInputDate } from "./ds-input-date.js";
53
53
  export { DsInputTime } from "./ds-input-time.js";
54
54
  export { DsInput } from "./ds-input.js";
55
55
  export { DsLoader } from "./ds-loader.js";
56
+ export { DsMapClusterMarker } from "./ds-map-cluster-marker.js";
57
+ export { DsMapEntityMarker } from "./ds-map-entity-marker.js";
56
58
  export { DsMarkdown } from "./ds-markdown.js";
57
59
  export { DsMenu } from "./ds-menu.js";
58
60
  export { DsMessageActions } from "./ds-message-actions.js";
@@ -72,10 +74,12 @@ export { DsPanelToolHeader } from "./ds-panel-tool-header.js";
72
74
  export { DsPanelToolSearch } from "./ds-panel-tool-search.js";
73
75
  export { DsPanelTools } from "./ds-panel-tools.js";
74
76
  export { DsPaperTexture } from "./ds-paper-texture.js";
77
+ export { DsRadioTile } from "./ds-radio-tile.js";
75
78
  export { DsRadio } from "./ds-radio.js";
76
79
  export { DsScore } from "./ds-score.js";
77
80
  export { DsScrollOverlay } from "./ds-scroll-overlay.js";
78
81
  export { DsSelect } from "./ds-select.js";
82
+ export { DsSettingRow } from "./ds-setting-row.js";
79
83
  export { DsShellApp } from "./ds-shell-app.js";
80
84
  export { DsShellPage } from "./ds-shell-page.js";
81
85
  export { DsShellTools } from "./ds-shell-tools.js";
@@ -8,6 +8,8 @@ import type { Components } from "@ds-mo/ui/dist/components";
8
8
  import { DsInput as DsInputElement } from "@ds-mo/ui/dist/components/ds-input.js";
9
9
  export type DsInputEvents = {
10
10
  onDsChange: EventName<DsInputCustomEvent<string>>;
11
+ onDsTokensChange: EventName<DsInputCustomEvent<string[]>>;
12
+ onDsSuggestionSelect: EventName<DsInputCustomEvent<string>>;
11
13
  onDsClear: EventName<DsInputCustomEvent<void>>;
12
14
  };
13
15
  export declare const DsInput: StencilReactComponent<DsInputElement, DsInputEvents, Components.DsInput>;
@@ -9,6 +9,8 @@ export const DsInput = /*@__PURE__*/ createComponent({
9
9
  react: React,
10
10
  events: {
11
11
  onDsChange: 'dsChange',
12
+ onDsTokensChange: 'dsTokensChange',
13
+ onDsSuggestionSelect: 'dsSuggestionSelect',
12
14
  onDsClear: 'dsClear'
13
15
  },
14
16
  defineCustomElement: defineDsInput
@@ -0,0 +1,12 @@
1
+ /**
2
+ * This file was automatically generated by the Stencil React Output Target.
3
+ * Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
4
+ */
5
+ import type { EventName, StencilReactComponent } from './react-runtime.js';
6
+ import { type DsMapClusterMarkerCustomEvent } from "@ds-mo/ui";
7
+ import type { Components } from "@ds-mo/ui/dist/components";
8
+ import { DsMapClusterMarker as DsMapClusterMarkerElement } from "@ds-mo/ui/dist/components/ds-map-cluster-marker.js";
9
+ export type DsMapClusterMarkerEvents = {
10
+ onDsClick: EventName<DsMapClusterMarkerCustomEvent<MouseEvent>>;
11
+ };
12
+ export declare const DsMapClusterMarker: StencilReactComponent<DsMapClusterMarkerElement, DsMapClusterMarkerEvents, Components.DsMapClusterMarker, 'label'>;
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+ import { createComponent } from './react-runtime.js';
3
+ import React from 'react';
4
+ import { DsMapClusterMarker as DsMapClusterMarkerElement, defineCustomElement as defineDsMapClusterMarker } from "@ds-mo/ui/dist/components/ds-map-cluster-marker.js";
5
+ export const DsMapClusterMarker = /*@__PURE__*/ createComponent({
6
+ tagName: 'ds-map-cluster-marker',
7
+ elementClass: DsMapClusterMarkerElement,
8
+ // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.
9
+ react: React,
10
+ events: { onDsClick: 'dsClick' },
11
+ defineCustomElement: defineDsMapClusterMarker
12
+ });
@@ -0,0 +1,12 @@
1
+ /**
2
+ * This file was automatically generated by the Stencil React Output Target.
3
+ * Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
4
+ */
5
+ import type { EventName, StencilReactComponent } from './react-runtime.js';
6
+ import { type DsMapEntityMarkerCustomEvent } from "@ds-mo/ui";
7
+ import type { Components } from "@ds-mo/ui/dist/components";
8
+ import { DsMapEntityMarker as DsMapEntityMarkerElement } from "@ds-mo/ui/dist/components/ds-map-entity-marker.js";
9
+ export type DsMapEntityMarkerEvents = {
10
+ onDsClick: EventName<DsMapEntityMarkerCustomEvent<MouseEvent>>;
11
+ };
12
+ export declare const DsMapEntityMarker: StencilReactComponent<DsMapEntityMarkerElement, DsMapEntityMarkerEvents, Components.DsMapEntityMarker, 'label'>;
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+ import { createComponent } from './react-runtime.js';
3
+ import React from 'react';
4
+ import { DsMapEntityMarker as DsMapEntityMarkerElement, defineCustomElement as defineDsMapEntityMarker } from "@ds-mo/ui/dist/components/ds-map-entity-marker.js";
5
+ export const DsMapEntityMarker = /*@__PURE__*/ createComponent({
6
+ tagName: 'ds-map-entity-marker',
7
+ elementClass: DsMapEntityMarkerElement,
8
+ // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.
9
+ react: React,
10
+ events: { onDsClick: 'dsClick' },
11
+ defineCustomElement: defineDsMapEntityMarker
12
+ });
@@ -0,0 +1,12 @@
1
+ /**
2
+ * This file was automatically generated by the Stencil React Output Target.
3
+ * Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
4
+ */
5
+ import type { EventName, StencilReactComponent } from './react-runtime.js';
6
+ import { type DsRadioTileCustomEvent } from "@ds-mo/ui";
7
+ import type { Components } from "@ds-mo/ui/dist/components";
8
+ import { DsRadioTile as DsRadioTileElement } from "@ds-mo/ui/dist/components/ds-radio-tile.js";
9
+ export type DsRadioTileEvents = {
10
+ onDsChange: EventName<DsRadioTileCustomEvent<string>>;
11
+ };
12
+ export declare const DsRadioTile: StencilReactComponent<DsRadioTileElement, DsRadioTileEvents, Components.DsRadioTile>;
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+ import { createComponent } from './react-runtime.js';
3
+ import React from 'react';
4
+ import { DsRadioTile as DsRadioTileElement, defineCustomElement as defineDsRadioTile } from "@ds-mo/ui/dist/components/ds-radio-tile.js";
5
+ export const DsRadioTile = /*@__PURE__*/ createComponent({
6
+ tagName: 'ds-radio-tile',
7
+ elementClass: DsRadioTileElement,
8
+ // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.
9
+ react: React,
10
+ events: { onDsChange: 'dsChange' },
11
+ defineCustomElement: defineDsRadioTile
12
+ });
@@ -0,0 +1,12 @@
1
+ /**
2
+ * This file was automatically generated by the Stencil React Output Target.
3
+ * Changes to this file may cause incorrect behavior and will be lost if the code is regenerated.
4
+ */
5
+ import type { EventName, StencilReactComponent } from './react-runtime.js';
6
+ import { type DsSettingRowCustomEvent } from "@ds-mo/ui";
7
+ import type { Components } from "@ds-mo/ui/dist/components";
8
+ import { DsSettingRow as DsSettingRowElement } from "@ds-mo/ui/dist/components/ds-setting-row.js";
9
+ export type DsSettingRowEvents = {
10
+ onDsChange: EventName<DsSettingRowCustomEvent<boolean>>;
11
+ };
12
+ export declare const DsSettingRow: StencilReactComponent<DsSettingRowElement, DsSettingRowEvents, Components.DsSettingRow, 'label'>;
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+ import { createComponent } from './react-runtime.js';
3
+ import React from 'react';
4
+ import { DsSettingRow as DsSettingRowElement, defineCustomElement as defineDsSettingRow } from "@ds-mo/ui/dist/components/ds-setting-row.js";
5
+ export const DsSettingRow = /*@__PURE__*/ createComponent({
6
+ tagName: 'ds-setting-row',
7
+ elementClass: DsSettingRowElement,
8
+ // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.
9
+ react: React,
10
+ events: { onDsChange: 'dsChange' },
11
+ defineCustomElement: defineDsSettingRow
12
+ });
@@ -1,4 +1,5 @@
1
1
  import { EventEmitter } from '../../stencil-public-runtime';
2
+ export type CardSettingVariant = 'editable' | 'immediate';
2
3
  export type CardSettingWidth = 'sm' | 'md' | 'lg';
3
4
  export type CardSettingAction = 'edit' | 'save' | 'cancel';
4
5
  export interface CardSettingActionDetail {
@@ -9,11 +10,12 @@ export declare class CardSetting {
9
10
  /** Section heading shown in the card header. */
10
11
  heading: string;
11
12
  /**
12
- * Card width token (`sm` / `md` / `lg`). Also sets host `min-height` to the
13
- * matching `--dimension-card-height-*` so the body fills available space
14
- * even when the slot is empty.
13
+ * Card width token (`sm` / `md` / `lg`). Editable cards also use the matching
14
+ * minimum-height token; immediate cards fit their content.
15
15
  */
16
16
  cardWidth: CardSettingWidth;
17
+ /** Immediate settings omit edit actions and apply changes through their own controls. */
18
+ variant: CardSettingVariant;
17
19
  /** Controlled edit state — parent owns single-edit orchestration. */
18
20
  editing: boolean;
19
21
  editLabel: string;
@@ -1,2 +1,2 @@
1
- export type { CardSettingAction, CardSettingActionDetail, CardSettingWidth } from './CardSetting';
1
+ export type { CardSettingAction, CardSettingActionDetail, CardSettingVariant, CardSettingWidth, } from './CardSetting';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @slot actions - Optional recovery buttons or links. The consumer owns their labels and behavior.
3
+ */
1
4
  export declare class EmptyState {
2
5
  /** Optional decorative prefix glyph for the complete icon + title + body variant. */
3
6
  icon: string | undefined;
@@ -10,6 +10,9 @@ export declare class Field {
10
10
  error: boolean;
11
11
  /** Visible error associated with the slotted control while error is true. */
12
12
  errorMessage: string | undefined;
13
+ private constraintMessage;
14
+ private characterCount;
15
+ private characterLimit;
13
16
  private focused;
14
17
  private filled;
15
18
  private dirty;
@@ -40,6 +43,7 @@ export declare class Field {
40
43
  private get errorId();
41
44
  private get renderedDescription();
42
45
  private get renderedError();
46
+ private get visibleError();
43
47
  private readValue;
44
48
  private updateControlAttribute;
45
49
  private findControl;