@adia-ai/web-components 0.8.40 → 0.8.42

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 (410) hide show
  1. package/CHANGELOG.md +71 -3
  2. package/MIGRATION.md +1229 -16
  3. package/README.md +25 -30
  4. package/USAGE.md +30 -4
  5. package/bin/audit-template-children.mjs +556 -0
  6. package/components/accordion/accordion-item.a2ui.json +4 -0
  7. package/components/accordion/accordion-item.yaml +2 -0
  8. package/components/accordion/accordion.a2ui.json +4 -0
  9. package/components/accordion/accordion.yaml +2 -0
  10. package/components/action-list/action-item.a2ui.json +29 -2
  11. package/components/action-list/action-item.yaml +46 -3
  12. package/components/action-list/action-list.a2ui.json +6 -1
  13. package/components/action-list/action-list.class.js +114 -11
  14. package/components/action-list/action-list.css +43 -3
  15. package/components/action-list/action-list.d.ts +6 -2
  16. package/components/action-list/action-list.yaml +5 -0
  17. package/components/adia-mark/adia-mark.a2ui.json +1 -0
  18. package/components/adia-wordmark/adia-wordmark.a2ui.json +1 -0
  19. package/components/agent-artifact/agent-artifact.a2ui.json +1 -0
  20. package/components/agent-feedback-bar/agent-feedback-bar.a2ui.json +6 -5
  21. package/components/agent-feedback-bar/agent-feedback-bar.yaml +6 -2
  22. package/components/agent-questions/agent-questions.a2ui.json +1 -0
  23. package/components/agent-reasoning/agent-reasoning.a2ui.json +6 -5
  24. package/components/agent-reasoning/agent-reasoning.yaml +6 -2
  25. package/components/agent-suggestions/agent-suggestions.a2ui.json +11 -2
  26. package/components/agent-suggestions/agent-suggestions.class.js +2 -1
  27. package/components/agent-suggestions/agent-suggestions.d.ts +4 -4
  28. package/components/agent-suggestions/agent-suggestions.yaml +4 -2
  29. package/components/agent-trace/agent-trace.a2ui.json +6 -5
  30. package/components/agent-trace/agent-trace.yaml +6 -2
  31. package/components/alert/alert.a2ui.json +1 -0
  32. package/components/alert/alert.css +1 -1
  33. package/components/anchor-bar/anchor-bar.a2ui.json +1 -0
  34. package/components/aside/aside.a2ui.json +1 -0
  35. package/components/avatar/avatar-group.a2ui.json +7 -1
  36. package/components/avatar/avatar-group.yaml +1 -0
  37. package/components/avatar/avatar.a2ui.json +12 -11
  38. package/components/avatar/avatar.d.ts +1 -1
  39. package/components/avatar/avatar.yaml +4 -4
  40. package/components/badge/badge.a2ui.json +1 -0
  41. package/components/block/block.a2ui.json +1 -0
  42. package/components/blockquote/blockquote.a2ui.json +1 -0
  43. package/components/breadcrumb/breadcrumb.a2ui.json +1 -0
  44. package/components/button/button.a2ui.json +1 -3
  45. package/components/button/button.yaml +1 -3
  46. package/components/calendar-grid/calendar-grid.a2ui.json +1 -0
  47. package/components/calendar-grid/calendar-grid.class.js +2 -1
  48. package/components/calendar-picker/calendar-picker.a2ui.json +143 -24
  49. package/components/calendar-picker/calendar-picker.class.js +490 -197
  50. package/components/calendar-picker/calendar-picker.css +120 -171
  51. package/components/calendar-picker/calendar-picker.yaml +225 -47
  52. package/components/canvas/canvas.a2ui.json +6 -5
  53. package/components/canvas/canvas.d.ts +37 -0
  54. package/components/canvas/canvas.js +72 -3
  55. package/components/canvas/canvas.yaml +6 -2
  56. package/components/card/card.a2ui.json +25 -2
  57. package/components/card/card.class.js +3 -0
  58. package/components/card/card.css +31 -1
  59. package/components/card/card.d.ts +2 -2
  60. package/components/card/card.examples.md +3 -3
  61. package/components/card/card.yaml +28 -4
  62. package/components/chart/chart.a2ui.json +27 -7
  63. package/components/chart/chart.class.js +64 -22
  64. package/components/chart/chart.css +6 -4
  65. package/components/chart/chart.d.ts +10 -4
  66. package/components/chart/chart.yaml +40 -6
  67. package/components/chart-legend/chart-legend.a2ui.json +7 -1
  68. package/components/chart-legend/chart-legend.class.js +59 -6
  69. package/components/chart-legend/chart-legend.css +5 -2
  70. package/components/chart-legend/chart-legend.d.ts +3 -1
  71. package/components/chart-legend/chart-legend.yaml +15 -1
  72. package/components/chat-thread/chat-input.a2ui.json +1 -0
  73. package/components/chat-thread/chat-thread.a2ui.json +10 -9
  74. package/components/chat-thread/chat-thread.yaml +13 -20
  75. package/components/check/check.a2ui.json +10 -9
  76. package/components/check/check.yaml +4 -4
  77. package/components/code/code.a2ui.json +1 -0
  78. package/components/col/col.a2ui.json +1 -0
  79. package/components/color-area/color-area.a2ui.json +148 -0
  80. package/components/color-area/color-area.class.js +657 -0
  81. package/components/color-area/color-area.css +188 -0
  82. package/components/color-area/color-area.d.ts +66 -0
  83. package/components/color-area/color-area.examples.md +19 -0
  84. package/components/color-area/color-area.js +17 -0
  85. package/components/color-area/color-area.yaml +183 -0
  86. package/components/color-input/color-input.a2ui.json +6 -5
  87. package/components/color-input/color-input.class.js +9 -6
  88. package/components/color-input/color-input.css +1 -1
  89. package/components/color-input/color-input.js +2 -2
  90. package/components/color-input/color-input.yaml +14 -12
  91. package/components/color-picker/color-picker.a2ui.json +16 -12
  92. package/components/color-picker/color-picker.class.js +24 -633
  93. package/components/color-picker/color-picker.css +14 -182
  94. package/components/color-picker/color-picker.yaml +41 -41
  95. package/components/combobox/combobox.a2ui.json +3 -2
  96. package/components/combobox/combobox.yaml +2 -2
  97. package/components/command/command.a2ui.json +12 -10
  98. package/components/command/command.class.js +3 -2
  99. package/components/command/command.yaml +17 -4
  100. package/components/context-menu/context-menu.a2ui.json +1 -0
  101. package/components/date-range-picker/date-range-picker.a2ui.json +2 -1
  102. package/components/date-range-picker/date-range-picker.yaml +1 -1
  103. package/components/datetime-picker/datetime-picker.a2ui.json +15 -108
  104. package/components/datetime-picker/datetime-picker.class.js +37 -690
  105. package/components/datetime-picker/datetime-picker.css +11 -183
  106. package/components/datetime-picker/datetime-picker.d.ts +4 -5
  107. package/components/datetime-picker/datetime-picker.yaml +44 -135
  108. package/components/demo-toggle/demo-toggle.a2ui.json +1 -0
  109. package/components/demo-toggle/demo-toggle.css +1 -1
  110. package/components/description-list/description-list.a2ui.json +2 -1
  111. package/components/description-list/description-list.css +1 -1
  112. package/components/description-list/description-list.d.ts +1 -1
  113. package/components/description-list/description-list.yaml +1 -1
  114. package/components/display-field/display-field.a2ui.json +1 -0
  115. package/components/divider/divider.a2ui.json +1 -0
  116. package/components/drawer/drawer.a2ui.json +1 -3
  117. package/components/drawer/drawer.css +1 -1
  118. package/components/drawer/drawer.yaml +0 -2
  119. package/components/drilldown/drilldown.a2ui.json +22 -20
  120. package/components/drilldown/drilldown.class.js +4 -3
  121. package/components/drilldown/drilldown.css +6 -6
  122. package/components/drilldown/drilldown.yaml +40 -9
  123. package/components/embed/embed.a2ui.json +6 -5
  124. package/components/embed/embed.yaml +2 -2
  125. package/components/empty-state/empty-state.a2ui.json +1 -0
  126. package/components/feed/feed-item.a2ui.json +25 -5
  127. package/components/feed/feed-item.yaml +28 -7
  128. package/components/feed/feed.a2ui.json +9 -2
  129. package/components/feed/feed.class.js +19 -12
  130. package/components/feed/feed.css +8 -8
  131. package/components/feed/feed.yaml +14 -1
  132. package/components/field/field.a2ui.json +2 -1
  133. package/components/field/field.class.js +4 -1
  134. package/components/field/field.examples.md +1 -1
  135. package/components/field/field.yaml +1 -1
  136. package/components/fields/fields.a2ui.json +1 -0
  137. package/components/fields/fields.examples.md +1 -1
  138. package/components/footer/footer.a2ui.json +1 -0
  139. package/components/frame/frame.a2ui.json +1 -0
  140. package/components/grid/grid.a2ui.json +1 -0
  141. package/components/header/header.a2ui.json +3 -2
  142. package/components/header/header.yaml +3 -3
  143. package/components/heatmap/heatmap.a2ui.json +2 -1
  144. package/components/heatmap/heatmap.class.js +1 -1
  145. package/components/heatmap/heatmap.css +4 -4
  146. package/components/heatmap/heatmap.yaml +1 -1
  147. package/components/icon/icon.a2ui.json +1 -0
  148. package/components/image/image.a2ui.json +28 -14
  149. package/components/image/image.class.js +38 -23
  150. package/components/image/image.css +18 -8
  151. package/components/image/image.d.ts +2 -2
  152. package/components/image/image.examples.md +3 -3
  153. package/components/image/image.yaml +23 -7
  154. package/components/index.js +1 -0
  155. package/components/inline-edit/inline-edit.a2ui.json +1 -0
  156. package/components/inline-message/inline-message.a2ui.json +3 -1
  157. package/components/inline-message/inline-message.class.js +3 -1
  158. package/components/inline-message/inline-message.d.ts +2 -2
  159. package/components/inline-message/inline-message.yaml +2 -1
  160. package/components/input/input.a2ui.json +66 -16
  161. package/components/input/input.class.js +64 -7
  162. package/components/input/input.css +14 -14
  163. package/components/input/input.d.ts +9 -4
  164. package/components/input/input.yaml +83 -10
  165. package/components/inspector/inspector.a2ui.json +1 -0
  166. package/components/integration-card/integration-card.a2ui.json +1 -0
  167. package/components/integration-card/integration-card.examples.md +2 -1
  168. package/components/kbd/kbd.a2ui.json +1 -0
  169. package/components/link/link.a2ui.json +2 -1
  170. package/components/link/link.yaml +1 -1
  171. package/components/list/list-item.a2ui.json +9 -0
  172. package/components/list/list-item.yaml +12 -0
  173. package/components/list/list.a2ui.json +9 -3
  174. package/components/list/list.class.js +14 -1
  175. package/components/list/list.css +12 -1
  176. package/components/list/list.d.ts +7 -5
  177. package/components/list/list.yaml +16 -6
  178. package/components/list-window/list-window.a2ui.json +1 -0
  179. package/components/list-window/list-window.class.js +2 -1
  180. package/components/loading-overlay/loading-overlay.a2ui.json +1 -0
  181. package/components/mark/mark.a2ui.json +2 -1
  182. package/components/mark/mark.yaml +1 -1
  183. package/components/menu/menu-divider.a2ui.json +1 -0
  184. package/components/menu/menu-item.a2ui.json +11 -4
  185. package/components/menu/menu-item.yaml +30 -3
  186. package/components/menu/menu-label.a2ui.json +1 -0
  187. package/components/menu/menu.a2ui.json +3 -2
  188. package/components/menu/menu.class.js +36 -8
  189. package/components/menu/menu.d.ts +5 -3
  190. package/components/menu/menu.yaml +3 -3
  191. package/components/modal/modal.a2ui.json +1 -0
  192. package/components/nav/nav.a2ui.json +1 -0
  193. package/components/nav/nav.class.js +14 -3
  194. package/components/nav-group/nav-group.a2ui.json +1 -0
  195. package/components/nav-group/nav-group.class.js +3 -1
  196. package/components/nav-item/nav-item.a2ui.json +1 -0
  197. package/components/noodles/noodles.a2ui.json +1 -0
  198. package/components/noodles/noodles.class.js +5 -1
  199. package/components/number-format/number-format.a2ui.json +1 -0
  200. package/components/option-card/option-card.a2ui.json +1 -0
  201. package/components/otp-input/otp-input.a2ui.json +3 -2
  202. package/components/otp-input/otp-input.yaml +9 -2
  203. package/components/page/page.a2ui.json +13 -0
  204. package/components/page/page.d.ts +1 -1
  205. package/components/page/page.yaml +1 -0
  206. package/components/pagination/pagination.a2ui.json +1 -0
  207. package/components/pagination/pagination.class.js +3 -2
  208. package/components/pane/pane.a2ui.json +17 -1
  209. package/components/pane/pane.class.js +35 -6
  210. package/components/pane/pane.css +17 -12
  211. package/components/pane/pane.d.ts +10 -7
  212. package/components/pane/pane.yaml +18 -1
  213. package/components/password-strength/password-strength.a2ui.json +1 -0
  214. package/components/pipeline-status/pipeline-status.a2ui.json +1 -0
  215. package/components/popover/popover.a2ui.json +7 -6
  216. package/components/popover/popover.class.js +2 -2
  217. package/components/popover/popover.d.ts +2 -2
  218. package/components/popover/popover.yaml +4 -4
  219. package/components/preview/preview.a2ui.json +1 -0
  220. package/components/preview/preview.class.js +5 -1
  221. package/components/progress/progress.a2ui.json +47 -24
  222. package/components/progress/progress.class.js +66 -11
  223. package/components/progress/progress.css +44 -26
  224. package/components/progress/progress.d.ts +7 -5
  225. package/components/progress/progress.examples.md +2 -2
  226. package/components/progress/progress.yaml +235 -53
  227. package/components/progress-row/progress-row.a2ui.json +16 -12
  228. package/components/progress-row/progress-row.d.ts +2 -2
  229. package/components/progress-row/progress-row.examples.md +2 -14
  230. package/components/progress-row/progress-row.yaml +28 -36
  231. package/components/qr-code/qr-code.a2ui.json +3 -2
  232. package/components/qr-code/qr-code.class.js +4 -4
  233. package/components/qr-code/qr-code.css +1 -1
  234. package/components/qr-code/qr-code.yaml +5 -3
  235. package/components/radio/radio.a2ui.json +8 -7
  236. package/components/radio/radio.class.js +8 -0
  237. package/components/radio/radio.yaml +3 -3
  238. package/components/radio-group/radio-group.a2ui.json +5 -3
  239. package/components/radio-group/radio-group.class.js +11 -0
  240. package/components/radio-group/radio-group.yaml +7 -1
  241. package/components/range/range.a2ui.json +6 -0
  242. package/components/range/range.class.js +2 -2
  243. package/components/range/range.css +2 -2
  244. package/components/range/range.yaml +3 -0
  245. package/components/rating/rating.a2ui.json +1 -0
  246. package/components/relative-time/relative-time.a2ui.json +1 -0
  247. package/components/richtext/richtext.a2ui.json +2 -1
  248. package/components/richtext/richtext.yaml +1 -1
  249. package/components/row/row.a2ui.json +1 -0
  250. package/components/search/search.a2ui.json +1 -0
  251. package/components/search/search.class.js +4 -1
  252. package/components/section/section.a2ui.json +1 -0
  253. package/components/segment/segment.a2ui.json +21 -10
  254. package/components/segment/segment.css +15 -0
  255. package/components/segment/segment.d.ts +2 -1
  256. package/components/segment/segment.yaml +20 -13
  257. package/components/segmented/segmented.a2ui.json +36 -7
  258. package/components/segmented/segmented.class.js +113 -22
  259. package/components/segmented/segmented.css +3 -0
  260. package/components/segmented/segmented.d.ts +3 -1
  261. package/components/segmented/segmented.yaml +80 -8
  262. package/components/select/select.a2ui.json +18 -13
  263. package/components/select/select.class.js +61 -37
  264. package/components/select/select.css +15 -13
  265. package/components/select/select.yaml +18 -7
  266. package/components/skeleton/skeleton.a2ui.json +8 -7
  267. package/components/skeleton/skeleton.class.js +8 -7
  268. package/components/skeleton/skeleton.css +21 -6
  269. package/components/skeleton/skeleton.d.ts +2 -2
  270. package/components/skeleton/skeleton.examples.md +2 -2
  271. package/components/skeleton/skeleton.yaml +3 -2
  272. package/components/skip-nav/skip-nav.a2ui.json +1 -0
  273. package/components/slider/slider.a2ui.json +6 -0
  274. package/components/slider/slider.class.js +20 -3
  275. package/components/slider/slider.css +2 -2
  276. package/components/slider/slider.yaml +3 -0
  277. package/components/spinner/spinner.a2ui.json +1 -0
  278. package/components/stack/stack.a2ui.json +1 -0
  279. package/components/stat/stat.a2ui.json +1 -0
  280. package/components/stat/stat.js +2 -2
  281. package/components/step-progress/step-progress.a2ui.json +1 -0
  282. package/components/step-progress/step-progress.yaml +1 -1
  283. package/components/stepper/stepper-item.a2ui.json +7 -3
  284. package/components/stepper/stepper-item.yaml +15 -5
  285. package/components/stepper/stepper.a2ui.json +5 -1
  286. package/components/stepper/stepper.class.js +31 -16
  287. package/components/stepper/stepper.d.ts +1 -1
  288. package/components/stepper/stepper.yaml +4 -2
  289. package/components/stream/stream.a2ui.json +1 -0
  290. package/components/swatch/swatch.a2ui.json +1 -0
  291. package/components/swatch/swatch.yaml +1 -1
  292. package/components/swiper/swiper.a2ui.json +1 -0
  293. package/components/swiper/swiper.class.js +5 -1
  294. package/components/switch/switch.a2ui.json +12 -11
  295. package/components/switch/switch.css +1 -1
  296. package/components/switch/switch.yaml +6 -6
  297. package/components/table/table.a2ui.json +1 -0
  298. package/components/table/table.class.js +14 -12
  299. package/components/table/table.css +11 -9
  300. package/components/table-toolbar/table-toolbar.a2ui.json +1 -0
  301. package/components/table-toolbar/table-toolbar.class.js +53 -22
  302. package/components/table-toolbar/table-toolbar.css +1 -1
  303. package/components/tabs/tab.a2ui.json +9 -0
  304. package/components/tabs/tab.js +4 -0
  305. package/components/tabs/tab.yaml +15 -0
  306. package/components/tabs/tabs.a2ui.json +9 -4
  307. package/components/tabs/tabs.class.js +13 -1
  308. package/components/tabs/tabs.css +8 -0
  309. package/components/tabs/tabs.d.ts +2 -0
  310. package/components/tabs/tabs.yaml +9 -2
  311. package/components/tag/tag.a2ui.json +1 -0
  312. package/components/tags-input/tags-input.a2ui.json +22 -17
  313. package/components/tags-input/tags-input.class.js +13 -11
  314. package/components/tags-input/tags-input.css +10 -6
  315. package/components/tags-input/tags-input.d.ts +16 -7
  316. package/components/tags-input/tags-input.examples.md +2 -2
  317. package/components/tags-input/tags-input.yaml +25 -8
  318. package/components/text/text.a2ui.json +6 -5
  319. package/components/text/text.css +10 -5
  320. package/components/text/text.d.ts +2 -2
  321. package/components/text/text.yaml +9 -4
  322. package/components/textarea/textarea.a2ui.json +2 -1
  323. package/components/textarea/textarea.yaml +1 -1
  324. package/components/theme-provider/theme-provider.a2ui.json +2 -1
  325. package/components/theme-provider/theme-provider.d.ts +5 -3
  326. package/components/theme-provider/theme-provider.yaml +5 -3
  327. package/components/time-picker/time-picker.a2ui.json +1 -0
  328. package/components/time-picker/time-picker.class.js +4 -2
  329. package/components/timeline/timeline-item.a2ui.json +26 -3
  330. package/components/timeline/timeline-item.yaml +22 -7
  331. package/components/timeline/timeline.a2ui.json +4 -0
  332. package/components/timeline/timeline.class.js +29 -18
  333. package/components/timeline/timeline.d.ts +3 -3
  334. package/components/timeline/timeline.yaml +2 -0
  335. package/components/toast/toast.a2ui.json +10 -3
  336. package/components/toast/toast.yaml +20 -13
  337. package/components/toc/toc.a2ui.json +1 -0
  338. package/components/toggle-group/toggle-group.a2ui.json +7 -3
  339. package/components/toggle-group/toggle-group.class.js +40 -1
  340. package/components/toggle-group/toggle-group.css +6 -1
  341. package/components/toggle-group/toggle-group.d.ts +2 -2
  342. package/components/toggle-group/toggle-group.yaml +21 -12
  343. package/components/toggle-group/toggle-option.a2ui.json +7 -3
  344. package/components/toggle-group/toggle-option.yaml +13 -7
  345. package/components/toggle-scheme/toggle-scheme.a2ui.json +2 -1
  346. package/components/toggle-scheme/toggle-scheme.yaml +1 -1
  347. package/components/toolbar/toolbar-group.a2ui.json +1 -0
  348. package/components/toolbar/toolbar.a2ui.json +1 -0
  349. package/components/toolbar/toolbar.class.js +3 -0
  350. package/components/tooltip/tooltip.a2ui.json +1 -0
  351. package/components/tour/tour-step.a2ui.json +4 -0
  352. package/components/tour/tour-step.yaml +2 -0
  353. package/components/tour/tour.a2ui.json +4 -0
  354. package/components/tour/tour.yaml +2 -0
  355. package/components/tree/tree-item.a2ui.json +5 -0
  356. package/components/tree/tree-item.yaml +3 -0
  357. package/components/tree/tree.a2ui.json +4 -0
  358. package/components/tree/tree.class.js +2 -1
  359. package/components/tree/tree.yaml +2 -0
  360. package/components/upload/upload.a2ui.json +8 -1
  361. package/components/upload/upload.class.js +35 -5
  362. package/components/upload/upload.css +28 -0
  363. package/components/upload/upload.d.ts +16 -0
  364. package/components/upload/upload.yaml +27 -7
  365. package/components/visually-hidden/visually-hidden.a2ui.json +1 -0
  366. package/core/dom.d.ts +11 -0
  367. package/core/dom.js +34 -0
  368. package/core/form.js +7 -0
  369. package/core/icons.js +5 -0
  370. package/core/index.d.ts +1 -0
  371. package/core/index.js +1 -0
  372. package/core/responsive.js +16 -4
  373. package/core/template.js +2 -1
  374. package/custom-elements.json +710 -587
  375. package/dist/host.min.css +1 -1
  376. package/dist/host.sheet.js +1 -1
  377. package/dist/theme-provider.min.js +5 -5
  378. package/dist/web-components.min.css +1 -1
  379. package/dist/web-components.min.js +92 -105
  380. package/dist/web-components.sheet.js +1 -1
  381. package/index.d.ts +12 -1
  382. package/package.json +4 -2
  383. package/patterns/admin-shell/admin-shell.examples.html +2 -2
  384. package/patterns/conversion-funnel/conversion-funnel.examples.html +15 -15
  385. package/patterns/form-system/form-system.examples.html +1 -1
  386. package/patterns/inline-dialog/inline-dialog.examples.html +2 -2
  387. package/patterns/inline-dialog/inline-dialog.html +4 -0
  388. package/patterns/timezone-selector/timezone-selector.examples.html +1 -1
  389. package/patterns/timezone-selector/timezone-selector.html +2 -2
  390. package/styles/api/text.css +7 -0
  391. package/styles/components.css +1 -0
  392. package/traits/_catalog.json +129 -41
  393. package/traits/anchor-positioning/anchor-positioning.js +1 -0
  394. package/traits/announcer/announcer.js +1 -0
  395. package/traits/arrow-grid-nav/arrow-grid-nav.js +1 -0
  396. package/traits/attention-pulse/attention-pulse.js +1 -0
  397. package/traits/count-up/count-up.js +1 -0
  398. package/traits/define.js +78 -0
  399. package/traits/focus-restore/focus-restore.js +2 -1
  400. package/traits/haptic-feedback/haptic-feedback.js +1 -0
  401. package/traits/input-mask/input-mask.js +1 -0
  402. package/traits/intersection-observer/intersection-observer.js +1 -0
  403. package/traits/layout-animation/layout-animation.js +1 -0
  404. package/traits/noise-texture/noise-texture.js +1 -0
  405. package/traits/resize-observer/resize-observer.js +1 -0
  406. package/traits/scroll-progress/scroll-progress.js +1 -0
  407. package/traits/snap-to-grid/snap-to-grid.js +1 -0
  408. package/traits/sound-feedback/sound-feedback.js +1 -0
  409. package/traits/spring-animate/spring-animate.js +1 -0
  410. package/traits/validation/validation.js +1 -0
@@ -28,7 +28,9 @@
28
28
  * When `selectable`:
29
29
  * - Children (role="listitem") become keyboard-focusable via roving tabindex.
30
30
  * - Click selects the child; key is its id or data-key.
31
- * - aria-selected is set on all children.
31
+ * - [selected] (ADR-0056, #1363 B7) and aria-selected are both set on
32
+ * all children — [selected] is the declared API state, aria-selected
33
+ * is wiring.
32
34
  * - Fires `selection-change` with { key, previousKey }.
33
35
  */
34
36
 
@@ -73,6 +75,7 @@ export class UIList extends UIElement {
73
75
  // (patient-visit rail's roving tabindex, gh#746).
74
76
  if (this.#stampedSelection) {
75
77
  for (const ch of this.#items()) {
78
+ ch.removeAttribute('selected');
76
79
  ch.removeAttribute('aria-selected');
77
80
  ch.removeAttribute('tabindex');
78
81
  }
@@ -87,6 +90,11 @@ export class UIList extends UIElement {
87
90
  for (const ch of items) {
88
91
  const k = this.#keyOf(ch);
89
92
  const selected = k && k === key;
93
+ // [selected] (ADR-0056, #1363 B7) is the declared, reflected API
94
+ // surface — parent-managed, mirrors <segment-ui>. aria-selected
95
+ // stays as-is: ARIA is wiring, not API.
96
+ if (selected) ch.setAttribute('selected', '');
97
+ else ch.removeAttribute('selected');
90
98
  ch.setAttribute('aria-selected', selected ? 'true' : 'false');
91
99
  ch.setAttribute('tabindex', selected ? '0' : '-1');
92
100
  if (selected) focusTarget = ch;
@@ -173,6 +181,11 @@ export class UIListItem extends UIElement {
173
181
  icon: { type: String, default: '', reflect: true },
174
182
  text: { type: String, default: '', reflect: true },
175
183
  description: { type: String, default: '', reflect: true },
184
+ // ADR-0056 (gh#1303, #1363 B7): declared reflected selection-item
185
+ // state, parent-managed — <list-ui>[selectable] stamps this instead
186
+ // of leaving selection visible only via aria-selected. Mirrors
187
+ // <segment-ui>'s [selected].
188
+ selected: { type: Boolean, default: false, reflect: true },
176
189
  };
177
190
 
178
191
  static template = () => null;
@@ -67,7 +67,18 @@
67
67
  background: var(--a-bg-hover);
68
68
  }
69
69
 
70
- :scope[selectable] > [role="listitem"][aria-selected="true"] {
70
+ /* [selected] is the declared, reflected state hook (ADR-0056, #1363 B7)
71
+ — list.class.js stamps it in lockstep with aria-selected; ARIA stays
72
+ wiring, not the style hook. Matched on the tag directly (not only
73
+ [role="listitem"]): UIList's adopt-or-stamp (gh#753) lets a
74
+ consumer-authored role (e.g. role="button") survive on <list-item-ui>
75
+ — #items() still selects/stamps it by TAG, so the style hook must
76
+ too, or a role-overridden selected row silently loses its selected
77
+ colors. The role fallback stays for non-list-item-ui children that
78
+ opt into role="listitem" themselves (list-ui also hosts "arbitrary
79
+ children", list.yaml). */
80
+ :scope[selectable] > list-item-ui[selected],
81
+ :scope[selectable] > [role="listitem"][selected] {
71
82
  background: var(--list-bg-selected);
72
83
  color: var(--list-fg-selected);
73
84
  border-inline-start-color: var(--list-border-selected);
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * `<list-ui>` — Styled flat list with optional row dividers and icons — each row
3
3
  is a <list-item-ui> child. Selectable mode via [selectable] +
4
- [selectedKey] / `select` event. Composes <icon-ui> for row leading
5
- glyphs. Distinct from <nav-ui> (sidebar navigation, route-aware),
4
+ [selectedKey] / `selection-change` event. Composes <icon-ui> for row
5
+ leading glyphs. Distinct from <nav-ui> (sidebar navigation, route-aware),
6
6
  <tree-ui> (hierarchical with arbitrary nesting), and <table-ui>
7
7
  (tabular data with columns). Use list-ui for non-navigable,
8
8
  non-tabular vertical rows — comment lists, file lists, message
@@ -41,10 +41,10 @@ so content sits at the list-ui edges (canonical edge-to-edge style).
41
41
  divider: boolean;
42
42
  /** Enable selection on child listitems (roving tabindex + aria-selected). */
43
43
  selectable: boolean;
44
- /** ID (or data-key) of the currently-selected child listitem. */
44
+ /** ID (or data-key) of the currently-selected child listitem — drives each child's [selected] reflected prop (ADR-0056, #1363 B7). Kept as `selectedKey` rather than renamed to `value` (segmented/tabs/ select's parent-selection prop name): list rows are identified by DOM id/data-key, not an option value, and ADR-0056 itself governs only the child's own [selected] state surface, not this naming — a cross-family rename has no ratifying ADR (B5/B9-shaped follow-up). */
45
45
  selectedKey: string;
46
- /** Item spacing */
47
- spacing: string;
46
+ /** Item spacing scale — `sm`/`lg` modulate the per-item inset; `md` (default) is the base inset. */
47
+ spacing: 'sm' | 'md' | 'lg';
48
48
 
49
49
  addEventListener(type: 'selection-change', listener: (ev: ListSelectionChangeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
50
50
  addEventListener<K extends keyof HTMLElementEventMap>(
@@ -59,6 +59,8 @@ export class UIListItem extends UIElement {
59
59
  description: string;
60
60
  /** Optional leading icon name (Phosphor). */
61
61
  icon: string;
62
+ /** Whether this row is the current selection. Managed by the parent <list-ui>[selectable] — don't set directly; the parent's [selectedKey] is the single source of truth (ADR-0056). */
63
+ selected: boolean;
62
64
  /** Primary text. Renders as semibold inline body. */
63
65
  text: string;
64
66
  }
@@ -10,8 +10,8 @@ version: 1
10
10
  description: |
11
11
  Styled flat list with optional row dividers and icons — each row
12
12
  is a <list-item-ui> child. Selectable mode via [selectable] +
13
- [selectedKey] / `select` event. Composes <icon-ui> for row leading
14
- glyphs. Distinct from <nav-ui> (sidebar navigation, route-aware),
13
+ [selectedKey] / `selection-change` event. Composes <icon-ui> for row
14
+ leading glyphs. Distinct from <nav-ui> (sidebar navigation, route-aware),
15
15
  <tree-ui> (hierarchical with arbitrary nesting), and <table-ui>
16
16
  (tabular data with columns). Use list-ui for non-navigable,
17
17
  non-tabular vertical rows — comment lists, file lists, message
@@ -40,14 +40,22 @@ props:
40
40
  type: boolean
41
41
  default: false
42
42
  selectedKey:
43
- description: ID (or data-key) of the currently-selected child listitem.
43
+ description: >-
44
+ ID (or data-key) of the currently-selected child listitem — drives
45
+ each child's [selected] reflected prop (ADR-0056, #1363 B7). Kept
46
+ as `selectedKey` rather than renamed to `value` (segmented/tabs/
47
+ select's parent-selection prop name): list rows are identified by
48
+ DOM id/data-key, not an option value, and ADR-0056 itself governs
49
+ only the child's own [selected] state surface, not this naming —
50
+ a cross-family rename has no ratifying ADR (B5/B9-shaped follow-up).
44
51
  type: string
45
52
  default: ""
46
53
  attribute: selected-key
47
54
  spacing:
48
- description: Item spacing
55
+ description: Item spacing scale — `sm`/`lg` modulate the per-item inset; `md` (default) is the base inset.
49
56
  type: string
50
57
  default: md
58
+ enum: [sm, md, lg]
51
59
  events:
52
60
  selection-change:
53
61
  description: "Fired on selection-change."
@@ -68,10 +76,12 @@ a2ui:
68
76
  rules:
69
77
  - rule: 'Generic vertical list container — hosts <list-item-ui> or arbitrary children.'
70
78
  reason: 'Lowest-friction list primitive.'
71
- - rule: 'For interactive selection lists use <nav-ui> (single-select navigation) or <menu-ui> (action menu); list-ui is content display.'
72
- reason: 'Different interaction contracts.'
79
+ - rule: 'list-ui supports single selection natively via [selectable] + [selectedKey] (ADR-0056, #1363 B7) — the parent stamps the matching <list-item-ui>''s [selected] + aria-selected and fires selection-change. For route-aware navigation use <nav-ui> instead; for a popover action menu use <menu-ui> instead both have different interaction contracts than a plain selectable list.'
80
+ reason: 'list-ui selectable is the supported non-navigation, non-menu selection surface; nav-ui/menu-ui remain the right choice for their own contracts.'
73
81
  - rule: 'For data-grid / sortable / sticky-header needs use <table-ui> instead.'
74
82
  reason: 'Table has different semantics.'
83
+ - rule: 'list-ui carries no fire-and-forget "action" mode. [selectable] keeps a persisted single selection (`selectedKey` / `aria-selected`, roving tabindex); for rows that activate immediately with no persisted selection state use <action-list-ui> + <action-item-ui> instead.'
84
+ reason: 'Container-level decision (#1363 C5): kept separate rather than absorbed as a mode axis — stateful selection and fire-and-forget activation are genuinely different interaction contracts, and list-item-ui''s selection state is under active convergence elsewhere (#1379); rationale in gh#1374 Findings.'
75
85
  anti_patterns: []
76
86
  examples:
77
87
  - name: basic-list
@@ -179,6 +179,7 @@
179
179
  "10k-rows"
180
180
  ],
181
181
  "name": "UIListWindow",
182
+ "parts": {},
182
183
  "related": [
183
184
  "List",
184
185
  "ListItem",
@@ -44,6 +44,7 @@
44
44
  */
45
45
 
46
46
  import { UIElement } from '../../core/element.js';
47
+ import { isNode } from '../../core/dom.js';
47
48
 
48
49
  export class UIListWindow extends UIElement {
49
50
  static properties = {
@@ -616,7 +617,7 @@ export class UIListWindow extends UIElement {
616
617
  try { content = renderFn(item, index); }
617
618
  catch (err) { console.warn('[list-window-ui] render() threw:', err); }
618
619
  }
619
- if (content instanceof Node) {
620
+ if (isNode(content)) {
620
621
  row.appendChild(content);
621
622
  } else if (content != null) {
622
623
  row.textContent = String(content);
@@ -88,6 +88,7 @@
88
88
  "wait"
89
89
  ],
90
90
  "name": "UILoadingOverlay",
91
+ "parts": {},
91
92
  "related": [
92
93
  "Spinner",
93
94
  "Skeleton",
@@ -40,7 +40,7 @@
40
40
  "wrong": "<mark>matched</mark>"
41
41
  }
42
42
  ],
43
- "category": "typography",
43
+ "category": "display",
44
44
  "composes": [],
45
45
  "events": {},
46
46
  "examples": [
@@ -57,6 +57,7 @@
57
57
  "emphasis"
58
58
  ],
59
59
  "name": "UIMark",
60
+ "parts": {},
60
61
  "related": [
61
62
  "text",
62
63
  "tag"
@@ -3,7 +3,7 @@ name: UIMark
3
3
  tag: mark-ui
4
4
  status: stable
5
5
  component: Mark
6
- category: typography
6
+ category: display
7
7
  version: 1
8
8
  description: |
9
9
  Highlighted inline text — token-driven theme-aware wrapper around the
@@ -33,6 +33,7 @@
33
33
  "menu-rule"
34
34
  ],
35
35
  "name": "UIMenuDivider",
36
+ "parts": {},
36
37
  "related": [
37
38
  "Menu",
38
39
  "MenuItem",
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://adiaui.dev/a2ui/v0_9/components/MenuItem.json",
4
4
  "title": "MenuItem",
5
- "description": "Child of `<menu-ui>`. One actionable row inside a menu, with optional leading icon + label + subtitle + value.",
5
+ "description": "Child of `<menu-ui>`. One actionable row inside a menu, with optional leading icon + label + description + value. (`subtitle` is a deprecated alias for `description` — ADR-0063, gh#1563.)",
6
6
  "type": "object",
7
7
  "allOf": [
8
8
  {
@@ -13,6 +13,11 @@
13
13
  }
14
14
  ],
15
15
  "properties": {
16
+ "description": {
17
+ "description": "Optional secondary description line rendered under the label. Canonical spelling (ADR-0063, gh#1563) replacing `subtitle` — converges menu-item onto the ~20-component corpus majority that already names this concept `description`.",
18
+ "type": "string",
19
+ "default": ""
20
+ },
16
21
  "component": {
17
22
  "const": "MenuItem"
18
23
  },
@@ -27,7 +32,7 @@
27
32
  "default": ""
28
33
  },
29
34
  "subtitle": {
30
- "description": "Optional secondary description line rendered under the label.",
35
+ "description": "DEPRECATED (ADR-0063, gh#1563) — use `description` instead. Same type/default/rendered position; kept working as a dual-read compat shim (one-time console.warn when it's the name that resolves). Removed in 0.9.0. (The `subtitle` SLOT below is a separate surface, deliberately left unrenamed in this pass — see its own description.)",
31
36
  "type": "string",
32
37
  "default": ""
33
38
  },
@@ -68,18 +73,20 @@
68
73
  "dropdown-item"
69
74
  ],
70
75
  "name": "UIMenuItem",
76
+ "parts": {},
71
77
  "related": [
72
78
  "Menu",
73
79
  "MenuDivider",
74
80
  "Button",
75
- "NavItem"
81
+ "NavItem",
82
+ "ActionItem"
76
83
  ],
77
84
  "slots": {
78
85
  "icon": {
79
86
  "description": "Custom leading element override; falls through to `[icon]` prop if not slotted."
80
87
  },
81
88
  "subtitle": {
82
- "description": "Custom secondary-line content override; falls through to `[subtitle]` prop if not slotted."
89
+ "description": "Custom secondary-line content override; falls through to the `[description]` prop (or its deprecated `[subtitle]` alias — ADR-0063, gh#1563) if not slotted. The slot's own name is unchanged by that rename — this is a distinct, deliberately-unrenamed surface."
83
90
  },
84
91
  "text": {
85
92
  "description": "Custom label content; falls through to `[text]` prop if not slotted."
@@ -13,7 +13,7 @@ component: MenuItem
13
13
  category: navigation
14
14
  version: 1
15
15
  description: |-
16
- Child of `<menu-ui>`. One actionable row inside a menu, with optional leading icon + label + subtitle + value.
16
+ Child of `<menu-ui>`. One actionable row inside a menu, with optional leading icon + label + description + value. (`subtitle` is a deprecated alias for `description` — ADR-0063, gh#1563.)
17
17
 
18
18
  props:
19
19
  icon:
@@ -25,7 +25,20 @@ props:
25
25
  type: string
26
26
  default: ""
27
27
  subtitle:
28
- description: Optional secondary description line rendered under the label.
28
+ description: >-
29
+ DEPRECATED (ADR-0063, gh#1563) — use `description` instead. Same
30
+ type/default/rendered position; kept working as a dual-read compat
31
+ shim (one-time console.warn when it's the name that resolves).
32
+ Removed in 0.9.0. (The `subtitle` SLOT below is a separate surface,
33
+ deliberately left unrenamed in this pass — see its own description.)
34
+ type: string
35
+ default: ""
36
+ description:
37
+ description: >-
38
+ Optional secondary description line rendered under the label.
39
+ Canonical spelling (ADR-0063, gh#1563) replacing `subtitle` —
40
+ converges menu-item onto the ~20-component corpus majority that
41
+ already names this concept `description`.
29
42
  type: string
30
43
  default: ""
31
44
  value:
@@ -49,7 +62,11 @@ slots:
49
62
  text:
50
63
  description: Custom label content; falls through to `[text]` prop if not slotted.
51
64
  subtitle:
52
- description: Custom secondary-line content override; falls through to `[subtitle]` prop if not slotted.
65
+ description: >-
66
+ Custom secondary-line content override; falls through to the
67
+ `[description]` prop (or its deprecated `[subtitle]` alias — ADR-0063,
68
+ gh#1563) if not slotted. The slot's own name is unchanged by that
69
+ rename — this is a distinct, deliberately-unrenamed surface.
53
70
  trailing:
54
71
  description: Trailing element pinned to the far edge (shortcut hint, check mark).
55
72
 
@@ -79,6 +96,15 @@ a2ui:
79
96
  Use slot="icon" / slot="text" only when you need custom markup
80
97
  (e.g. <avatar-ui slot="icon">, <kbd slot="trailing"> shortcut
81
98
  hint).
99
+ - >-
100
+ <action-item-ui> (child of <action-list-ui>) shares this row contract
101
+ (icon/text/subtitle/value/variant/disabled props, icon/text/subtitle/
102
+ trailing slot overrides) for inline, non-popover command rows — use
103
+ it instead when the surface isn't a <menu-ui> popover (#1363 C5).
104
+ NOTE (ADR-0063, gh#1563): <menu-item-ui>'s own `subtitle` PROP is now
105
+ a deprecated alias for `description` — <action-item-ui> still uses
106
+ `subtitle` as its own primary spelling and was NOT renamed in this
107
+ pass (flagged as a discovered follow-up candidate, not fixed here).
82
108
 
83
109
  keywords:
84
110
  - menu-item
@@ -91,6 +117,7 @@ related:
91
117
  - MenuDivider
92
118
  - Button
93
119
  - NavItem
120
+ - ActionItem
94
121
 
95
122
  synonyms:
96
123
  menu-item: [dropdown-item, menu-row, popover-action]
@@ -39,6 +39,7 @@
39
39
  "menu-heading"
40
40
  ],
41
41
  "name": "UIMenuLabel",
42
+ "parts": {},
42
43
  "related": [
43
44
  "Menu",
44
45
  "MenuItem",
@@ -16,8 +16,8 @@
16
16
  "component": {
17
17
  "const": "Menu"
18
18
  },
19
- "gap": {
20
- "description": "Gap in px",
19
+ "offset": {
20
+ "description": "Pixel offset between the anchor (trigger) and the menu popover. Renamed from `[gap]` (gh#1335) — a raw-px number can't share a name with the global Scale-grammar `[gap]` attribute (ADR-0053); matches popover-ui's own `[offset]` (same anchorPopover() helper).",
21
21
  "type": "number",
22
22
  "default": 4
23
23
  },
@@ -81,6 +81,7 @@
81
81
  "right-click"
82
82
  ],
83
83
  "name": "UIMenu",
84
+ "parts": {},
84
85
  "related": [
85
86
  "MenuItem",
86
87
  "MenuDivider",
@@ -35,7 +35,7 @@ export class UIMenu extends UIElement {
35
35
  static properties = {
36
36
  open: { type: Boolean, default: false, reflect: true },
37
37
  placement: { type: String, default: 'bottom-start', reflect: true },
38
- gap: { type: Number, default: 4, reflect: true },
38
+ offset: { type: Number, default: 4, reflect: true },
39
39
  };
40
40
 
41
41
  static template = () => null;
@@ -103,7 +103,7 @@ export class UIMenu extends UIElement {
103
103
  this.#anchorCleanup?.();
104
104
  this.#anchorCleanup = anchorPopover(trigger, pop, {
105
105
  placement: this.placement,
106
- gap: this.gap,
106
+ gap: this.offset,
107
107
  });
108
108
 
109
109
  // Focus first enabled item (only when opened via keyboard).
@@ -258,7 +258,14 @@ export class UIMenuItem extends UIElement {
258
258
  static properties = {
259
259
  icon: { type: String, default: '', reflect: true },
260
260
  text: { type: String, default: '', reflect: true },
261
+ // ADR-0063 (gh#1563) — `subtitle` is DEPRECATED (menu-item was the sole
262
+ // ~20-component-corpus outlier using `subtitle` where every sibling
263
+ // uses `description`); `description` is canonical. `subtitle` stays
264
+ // declared (dual-read compat, 0.8.42). The `subtitle` SLOT (a separate
265
+ // surface — see menu-item.yaml) is deliberately unchanged; only the
266
+ // PROP renames.
261
267
  subtitle: { type: String, default: '', reflect: true },
268
+ description: { type: String, default: '', reflect: true },
262
269
  value: { type: String, default: '', reflect: true },
263
270
  variant: { type: String, default: 'default', reflect: true },
264
271
  disabled: { type: Boolean, default: false, reflect: true },
@@ -266,12 +273,32 @@ export class UIMenuItem extends UIElement {
266
273
 
267
274
  static template = () => null;
268
275
 
276
+ // ADR-0063 (gh#1563) one-shot-per-class deprecation warn for [subtitle].
277
+ static #warnedSubtitle = false;
278
+
269
279
  // Set when connected() stamped role="menuitem" itself; a consumer-provided
270
280
  // role (e.g. admin-roster's role="menuitemradio", gh#616) is never touched
271
281
  // — that consumer also owns tabindex and any checked-state aria.
272
282
  #roleStamped = false;
273
283
 
274
284
  connected() {
285
+ // ADR-0063 (gh#1563) compat shim — resolve BEFORE #stamp() reads
286
+ // `this.description`, so there's no wrong-then-right flash. New-name
287
+ // precedence: [description] wins outright when present; only fall
288
+ // back to (and mirror) [subtitle] when [description] is absent.
289
+ if (!this.hasAttribute('description') && this.hasAttribute('subtitle')) {
290
+ this.description = this.subtitle;
291
+ if (!UIMenuItem.#warnedSubtitle) {
292
+ UIMenuItem.#warnedSubtitle = true;
293
+ // eslint-disable-next-line no-console
294
+ console.warn(
295
+ '[AdiaUI] <menu-item-ui [subtitle]> is deprecated — use ' +
296
+ '[description] instead (ADR-0063, gh#1563). Kept working as-is; ' +
297
+ 'no behavior change.',
298
+ );
299
+ }
300
+ }
301
+
275
302
  // role="menuitem" ONLY when actually inside a menu container. A menu-ui
276
303
  // closes by moving its items back into its own light DOM (see #hide()),
277
304
  // where there is no role="menu"/menubar ancestor — a bare role="menuitem"
@@ -324,10 +351,10 @@ export class UIMenuItem extends UIElement {
324
351
  this.appendChild(span);
325
352
  }
326
353
 
327
- if (this.subtitle && !this.#ownChild('[slot="subtitle"]')) {
354
+ if (this.description && !this.#ownChild('[slot="subtitle"]')) {
328
355
  const sub = this.#stampMark(document.createElement('span'));
329
356
  sub.setAttribute('slot', 'subtitle');
330
- sub.textContent = this.subtitle;
357
+ sub.textContent = this.description;
331
358
  this.appendChild(sub);
332
359
  }
333
360
  }
@@ -357,15 +384,16 @@ export class UIMenuItem extends UIElement {
357
384
  const textEl = this.#ownChild('[slot="text"]');
358
385
  if (this.#wasStamped(textEl)) textEl.textContent = this.text;
359
386
 
360
- // Sync subtitle only touch elements we stamped.
387
+ // Sync subtitle (backed by the `description` prop — ADR-0063, gh#1563)
388
+ // — only touch elements we stamped.
361
389
  const subEl = this.#ownChild('[slot="subtitle"]');
362
- if (this.subtitle) {
390
+ if (this.description) {
363
391
  if (subEl) {
364
- if (this.#wasStamped(subEl)) subEl.textContent = this.subtitle;
392
+ if (this.#wasStamped(subEl)) subEl.textContent = this.description;
365
393
  } else {
366
394
  const el = this.#stampMark(document.createElement('span'));
367
395
  el.setAttribute('slot', 'subtitle');
368
- el.textContent = this.subtitle;
396
+ el.textContent = this.description;
369
397
  this.appendChild(el);
370
398
  }
371
399
  } else if (this.#wasStamped(subEl)) {
@@ -22,8 +22,8 @@ export interface MenuActionEventDetail {
22
22
  export type MenuActionEvent = CustomEvent<MenuActionEventDetail>;
23
23
 
24
24
  export class UIMenu extends UIElement {
25
- /** Gap in px */
26
- gap: number;
25
+ /** Pixel offset between the anchor (trigger) and the menu popover. Renamed from `[gap]` (gh#1335) — a raw-px number can't share a name with the global Scale-grammar `[gap]` attribute (ADR-0053); matches popover-ui's own `[offset]` (same anchorPopover() helper). */
26
+ offset: number;
27
27
  /** Controls visibility via popover API */
28
28
  open: boolean;
29
29
  /** Preferred position relative to the anchor element */
@@ -41,11 +41,13 @@ export class UIMenuDivider extends UIElement {
41
41
  }
42
42
 
43
43
  export class UIMenuItem extends UIElement {
44
+ /** Optional secondary description line rendered under the label. Canonical spelling (ADR-0063, gh#1563) replacing `subtitle` — converges menu-item onto the ~20-component corpus majority that already names this concept `description`. */
45
+ description: string;
44
46
  /** Disabled state — blocks pointer + keyboard activation. */
45
47
  disabled: boolean;
46
48
  /** Optional leading Phosphor icon name. */
47
49
  icon: string;
48
- /** Optional secondary description line rendered under the label. */
50
+ /** DEPRECATED (ADR-0063, gh#1563) — use `description` instead. Same type/default/rendered position; kept working as a dual-read compat shim (one-time console.warn when it's the name that resolves). Removed in 0.9.0. (The `subtitle` SLOT below is a separate surface, deliberately left unrenamed in this pass — see its own description.) */
49
51
  subtitle: string;
50
52
  /** Item label text. */
51
53
  text: string;
@@ -13,8 +13,8 @@ description: Dropdown action menu with roving focus and keyboard navigation. Use
13
13
  composes:
14
14
  - icon-ui # leading affordances on menu items (created in render)
15
15
  props:
16
- gap:
17
- description: Gap in px
16
+ offset:
17
+ description: Pixel offset between the anchor (trigger) and the menu popover. Renamed from `[gap]` (gh#1335) — a raw-px number can't share a name with the global Scale-grammar `[gap]` attribute (ADR-0053); matches popover-ui's own `[offset]` (same anchorPopover() helper).
18
18
  type: number
19
19
  default: 4
20
20
  open:
@@ -83,7 +83,7 @@ a2ui:
83
83
  Set [placement="top-start"] or [placement="top-end"] when the
84
84
  trigger sits near the bottom of the viewport (statusbar / footer
85
85
  menus); default [placement="bottom-start"] otherwise. Adjust
86
- [gap] (default 4px) only when chrome demands it.
86
+ [offset] (default 4px) only when chrome demands it.
87
87
  anti_patterns: []
88
88
  examples:
89
89
  - name: basic-menu
@@ -66,6 +66,7 @@
66
66
  "modal"
67
67
  ],
68
68
  "name": "UIModal",
69
+ "parts": {},
69
70
  "related": [
70
71
  "Drawer",
71
72
  "Card",
@@ -98,6 +98,7 @@
98
98
  "links"
99
99
  ],
100
100
  "name": "UINav",
101
+ "parts": {},
101
102
  "related": [
102
103
  "NavGroup",
103
104
  "NavItem",
@@ -78,8 +78,20 @@ export class UINav extends UIElement {
78
78
  if (this.variant !== 'section') this.#updateTooltips();
79
79
  }
80
80
 
81
+ /**
82
+ * Collapsed = explicit [collapsed], or a rail narrower than 96px.
83
+ * linkedom (SSR — gh#1436's render sweep) has no getBoundingClientRect
84
+ * at all, so only the attribute can answer there. (A ZERO rect from a
85
+ * real pre-layout connect is the separate, unswept shape-3 question in
86
+ * ssr-compatibility's failure-shapes.md — not decided here.)
87
+ */
88
+ get #isCollapsed() {
89
+ return this.collapsed ||
90
+ (typeof this.getBoundingClientRect === 'function' && this.getBoundingClientRect().width <= 96);
91
+ }
92
+
81
93
  #updateTooltips() {
82
- const isCollapsed = this.collapsed || this.getBoundingClientRect().width <= 96;
94
+ const isCollapsed = this.#isCollapsed;
83
95
  for (const group of this.querySelectorAll(':scope > nav-group-ui')) {
84
96
  const header = group.querySelector(':scope > [slot="header"]');
85
97
  if (header) header.title = isCollapsed ? group.text : '';
@@ -143,8 +155,7 @@ export class UINav extends UIElement {
143
155
 
144
156
  const group = e.target.closest('nav-group-ui');
145
157
  if (group && this.contains(group)) {
146
- const isCollapsed = this.collapsed || this.getBoundingClientRect().width <= 96;
147
- if (isCollapsed) {
158
+ if (this.#isCollapsed) {
148
159
  // The flyout popover is appended INSIDE the group, so an option
149
160
  // click bubbles here after the option's own handler has selected
150
161
  // and hidePopover()'d — re-showing would instantly reopen the
@@ -92,6 +92,7 @@
92
92
  "menu"
93
93
  ],
94
94
  "name": "UINavGroup",
95
+ "parts": {},
95
96
  "related": [
96
97
  "Nav",
97
98
  "NavItem",
@@ -99,7 +99,9 @@ export class UINavGroup extends UIElement {
99
99
  // whole subtree includes this host's own [selected], which render()
100
100
  // reads anyway; render() writes only the icon's [weight], which the
101
101
  // attributeFilter excludes, so the observer can't feed back.
102
- if (!this.#selectionObserver) {
102
+ // Guarded like the other Observer sites (gh#285 §1 pattern) — SSR shims
103
+ // have no MutationObserver; teardown already uses `?.disconnect()`.
104
+ if (!this.#selectionObserver && typeof MutationObserver !== 'undefined') {
103
105
  this.#selectionObserver = new MutationObserver(this.#onChildSelection);
104
106
  this.#selectionObserver.observe(this, {
105
107
  subtree: true,
@@ -96,6 +96,7 @@
96
96
  "sidebar"
97
97
  ],
98
98
  "name": "UINavItem",
99
+ "parts": {},
99
100
  "related": [
100
101
  "Nav",
101
102
  "NavGroup",
@@ -156,6 +156,7 @@
156
156
  "noodles"
157
157
  ],
158
158
  "name": "UINoodles",
159
+ "parts": {},
159
160
  "related": [
160
161
  "Canvas",
161
162
  "EditorCanvas"
@@ -24,6 +24,7 @@
24
24
  */
25
25
 
26
26
  import { UIElement } from '../../core/element.js';
27
+ import { isElement } from '../../core/dom.js';
27
28
 
28
29
  let nextId = 0;
29
30
 
@@ -159,6 +160,9 @@ export class UINoodles extends UIElement {
159
160
 
160
161
  #scheduleUpdate() {
161
162
  if (this.#rafId) return;
163
+ // No rAF (SSR shim — gh#1436's render sweep) → no frame and no layout
164
+ // to measure connectors against; the client redraws on hydrate.
165
+ if (typeof requestAnimationFrame !== 'function') return;
162
166
  this.#rafId = requestAnimationFrame(() => {
163
167
  this.#rafId = null;
164
168
  this.#performUpdate();
@@ -251,7 +255,7 @@ export class UINoodles extends UIElement {
251
255
  // ── Element resolution ──────────────────────────────────────
252
256
 
253
257
  #resolveElement(ref) {
254
- if (ref instanceof HTMLElement) return ref;
258
+ if (isElement(ref)) return ref;
255
259
  if (typeof ref === 'string') return this.querySelector(`#${CSS.escape(ref)}`);
256
260
  if (typeof ref === 'number') return this.#getPortChildren()[ref] ?? null;
257
261
  return null;
@@ -143,6 +143,7 @@
143
143
  "intl"
144
144
  ],
145
145
  "name": "UINumberFormat",
146
+ "parts": {},
146
147
  "related": [
147
148
  "stat",
148
149
  "text",