@adia-ai/web-components 0.4.6 → 0.4.8

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 (399) hide show
  1. package/README.md +39 -0
  2. package/USAGE.md +29 -9
  3. package/components/accordion/accordion.a2ui.json +3 -0
  4. package/components/accordion/accordion.d.ts +27 -0
  5. package/components/accordion/accordion.js +10 -117
  6. package/components/accordion/accordion.yaml +4 -0
  7. package/components/accordion/class.js +132 -0
  8. package/components/action-list/action-list.a2ui.json +3 -0
  9. package/components/action-list/action-list.d.ts +25 -0
  10. package/components/action-list/action-list.js +9 -140
  11. package/components/action-list/action-list.yaml +4 -0
  12. package/components/action-list/class.js +156 -0
  13. package/components/agent-artifact/agent-artifact.a2ui.json +4 -0
  14. package/components/agent-artifact/agent-artifact.d.ts +35 -0
  15. package/components/agent-artifact/agent-artifact.js +8 -181
  16. package/components/agent-artifact/agent-artifact.yaml +5 -0
  17. package/components/agent-artifact/class.js +200 -0
  18. package/components/agent-feedback-bar/agent-feedback-bar.a2ui.json +3 -0
  19. package/components/agent-feedback-bar/agent-feedback-bar.d.ts +33 -0
  20. package/components/agent-feedback-bar/agent-feedback-bar.js +8 -143
  21. package/components/agent-feedback-bar/agent-feedback-bar.yaml +4 -0
  22. package/components/agent-feedback-bar/class.js +162 -0
  23. package/components/agent-questions/agent-questions.a2ui.json +3 -0
  24. package/components/agent-questions/agent-questions.d.ts +33 -0
  25. package/components/agent-questions/agent-questions.js +8 -180
  26. package/components/agent-questions/agent-questions.yaml +4 -0
  27. package/components/agent-questions/class.js +199 -0
  28. package/components/agent-reasoning/agent-reasoning.a2ui.json +4 -0
  29. package/components/agent-reasoning/agent-reasoning.d.ts +37 -0
  30. package/components/agent-reasoning/agent-reasoning.js +8 -494
  31. package/components/agent-reasoning/agent-reasoning.yaml +5 -0
  32. package/components/agent-reasoning/class.js +513 -0
  33. package/components/agent-suggestions/agent-suggestions.a2ui.json +3 -0
  34. package/components/agent-suggestions/agent-suggestions.d.ts +31 -0
  35. package/components/agent-suggestions/agent-suggestions.js +8 -78
  36. package/components/agent-suggestions/agent-suggestions.yaml +4 -0
  37. package/components/agent-suggestions/class.js +97 -0
  38. package/components/agent-trace/agent-trace.a2ui.json +1 -0
  39. package/components/agent-trace/agent-trace.d.ts +29 -0
  40. package/components/alert/alert.a2ui.json +1 -0
  41. package/components/alert/alert.d.ts +39 -0
  42. package/components/alert/alert.js +8 -175
  43. package/components/alert/class.js +194 -0
  44. package/components/aside/aside.a2ui.json +1 -0
  45. package/components/avatar/avatar.a2ui.json +3 -0
  46. package/components/avatar/avatar.d.ts +28 -0
  47. package/components/avatar/avatar.js +9 -159
  48. package/components/avatar/avatar.yaml +4 -0
  49. package/components/avatar/class.js +173 -0
  50. package/components/badge/badge.a2ui.json +3 -0
  51. package/components/badge/badge.d.ts +28 -0
  52. package/components/badge/badge.js +9 -75
  53. package/components/badge/badge.yaml +4 -0
  54. package/components/badge/class.js +93 -0
  55. package/components/block/block.a2ui.json +1 -0
  56. package/components/block/block.d.ts +20 -0
  57. package/components/block/block.js +9 -15
  58. package/components/block/class.js +33 -0
  59. package/components/breadcrumb/breadcrumb.a2ui.json +5 -0
  60. package/components/breadcrumb/breadcrumb.d.ts +24 -0
  61. package/components/breadcrumb/breadcrumb.js +8 -113
  62. package/components/breadcrumb/breadcrumb.yaml +6 -0
  63. package/components/breadcrumb/class.js +132 -0
  64. package/components/button/button.a2ui.json +3 -0
  65. package/components/button/button.d.ts +44 -0
  66. package/components/button/button.js +15 -66
  67. package/components/button/button.yaml +5 -0
  68. package/components/button/class.js +80 -0
  69. package/components/calendar-picker/calendar-picker.a2ui.json +7 -1
  70. package/components/calendar-picker/calendar-picker.js +8 -332
  71. package/components/calendar-picker/calendar-picker.yaml +51 -177
  72. package/components/calendar-picker/class.js +351 -0
  73. package/components/canvas/canvas.a2ui.json +7 -1
  74. package/components/canvas/canvas.d.ts +33 -0
  75. package/components/canvas/canvas.yaml +29 -36
  76. package/components/card/card.a2ui.json +4 -0
  77. package/components/card/card.d.ts +37 -0
  78. package/components/card/card.js +9 -50
  79. package/components/card/card.yaml +171 -433
  80. package/components/card/class.js +68 -0
  81. package/components/chart/chart.a2ui.json +1 -0
  82. package/components/chart/chart.d.ts +55 -0
  83. package/components/chart/chart.js +8 -2131
  84. package/components/chart/class.js +2150 -0
  85. package/components/chart-legend/chart-legend.a2ui.json +4 -0
  86. package/components/chart-legend/chart-legend.d.ts +37 -0
  87. package/components/chart-legend/chart-legend.js +8 -197
  88. package/components/chart-legend/chart-legend.yaml +5 -0
  89. package/components/chart-legend/class.js +215 -0
  90. package/components/chat-thread/chat-thread.a2ui.json +1 -0
  91. package/components/chat-thread/chat-thread.d.ts +27 -0
  92. package/components/chat-thread/chat-thread.js +8 -157
  93. package/components/chat-thread/class.js +176 -0
  94. package/components/check/check.a2ui.json +1 -0
  95. package/components/check/check.js +11 -52
  96. package/components/check/class.js +68 -0
  97. package/components/code/class.js +501 -0
  98. package/components/code/code.a2ui.json +1 -0
  99. package/components/code/code.js +8 -482
  100. package/components/col/class.js +30 -0
  101. package/components/col/col.a2ui.json +1 -0
  102. package/components/col/col.d.ts +24 -0
  103. package/components/col/col.js +10 -13
  104. package/components/color-picker/class.js +550 -0
  105. package/components/color-picker/color-picker.a2ui.json +3 -0
  106. package/components/color-picker/color-picker.js +8 -531
  107. package/components/color-picker/color-picker.yaml +4 -0
  108. package/components/command/class.js +364 -0
  109. package/components/command/command.a2ui.json +4 -0
  110. package/components/command/command.d.ts +31 -0
  111. package/components/command/command.js +8 -345
  112. package/components/command/command.yaml +105 -124
  113. package/components/demo-toggle/class.js +153 -0
  114. package/components/demo-toggle/demo-toggle.a2ui.json +1 -0
  115. package/components/demo-toggle/demo-toggle.d.ts +33 -0
  116. package/components/demo-toggle/demo-toggle.js +8 -135
  117. package/components/description-list/class.js +86 -0
  118. package/components/description-list/description-list.a2ui.json +1 -0
  119. package/components/description-list/description-list.d.ts +22 -0
  120. package/components/description-list/description-list.js +8 -67
  121. package/components/divider/class.js +57 -0
  122. package/components/divider/divider.a2ui.json +1 -0
  123. package/components/divider/divider.d.ts +20 -0
  124. package/components/divider/divider.js +10 -40
  125. package/components/drawer/class.js +306 -0
  126. package/components/drawer/drawer.a2ui.json +1 -0
  127. package/components/drawer/drawer.d.ts +35 -0
  128. package/components/drawer/drawer.js +8 -287
  129. package/components/embed/class.js +73 -0
  130. package/components/embed/embed.a2ui.json +1 -0
  131. package/components/embed/embed.d.ts +24 -0
  132. package/components/embed/embed.js +9 -55
  133. package/components/empty-state/class.js +108 -0
  134. package/components/empty-state/empty-state.a2ui.json +3 -0
  135. package/components/empty-state/empty-state.d.ts +22 -0
  136. package/components/empty-state/empty-state.js +9 -90
  137. package/components/empty-state/empty-state.yaml +4 -0
  138. package/components/feed/class.js +381 -0
  139. package/components/feed/feed.a2ui.json +9 -1
  140. package/components/feed/feed.d.ts +29 -0
  141. package/components/feed/feed.js +9 -367
  142. package/components/feed/feed.yaml +8 -1
  143. package/components/field/class.js +266 -0
  144. package/components/field/field.a2ui.json +1 -0
  145. package/components/field/field.d.ts +24 -0
  146. package/components/field/field.js +8 -247
  147. package/components/fields/class.js +106 -0
  148. package/components/fields/fields.a2ui.json +1 -0
  149. package/components/fields/fields.d.ts +20 -0
  150. package/components/fields/fields.js +8 -87
  151. package/components/footer/footer.a2ui.json +1 -0
  152. package/components/grid/class.js +31 -0
  153. package/components/grid/grid.a2ui.json +1 -0
  154. package/components/grid/grid.d.ts +24 -0
  155. package/components/grid/grid.js +10 -14
  156. package/components/header/header.a2ui.json +1 -0
  157. package/components/heatmap/class.js +305 -0
  158. package/components/heatmap/heatmap.a2ui.json +1 -0
  159. package/components/heatmap/heatmap.d.ts +43 -0
  160. package/components/heatmap/heatmap.js +8 -286
  161. package/components/icon/class.js +54 -0
  162. package/components/icon/icon.a2ui.json +1 -0
  163. package/components/icon/icon.d.ts +24 -0
  164. package/components/icon/icon.js +13 -40
  165. package/components/image/class.js +112 -0
  166. package/components/image/image.a2ui.json +3 -0
  167. package/components/image/image.d.ts +34 -0
  168. package/components/image/image.js +9 -94
  169. package/components/image/image.yaml +4 -0
  170. package/components/index.js +8 -0
  171. package/components/input/class.js +773 -0
  172. package/components/input/input.a2ui.json +7 -0
  173. package/components/input/input.js +8 -755
  174. package/components/input/input.yaml +177 -442
  175. package/components/inspector/class.js +142 -0
  176. package/components/inspector/inspector.a2ui.json +13 -1
  177. package/components/inspector/inspector.d.ts +18 -0
  178. package/components/inspector/inspector.js +8 -124
  179. package/components/inspector/inspector.yaml +21 -30
  180. package/components/kbd/class.js +34 -0
  181. package/components/kbd/kbd.a2ui.json +4 -0
  182. package/components/kbd/kbd.d.ts +18 -0
  183. package/components/kbd/kbd.js +10 -17
  184. package/components/kbd/kbd.yaml +54 -185
  185. package/components/link/class.js +187 -0
  186. package/components/link/link.a2ui.json +1 -0
  187. package/components/link/link.d.ts +65 -0
  188. package/components/link/link.js +8 -168
  189. package/components/list/class.js +249 -0
  190. package/components/list/list.a2ui.json +3 -0
  191. package/components/list/list.d.ts +33 -0
  192. package/components/list/list.js +9 -231
  193. package/components/list/list.yaml +4 -0
  194. package/components/menu/class.js +332 -0
  195. package/components/menu/menu.a2ui.json +3 -0
  196. package/components/menu/menu.d.ts +31 -0
  197. package/components/menu/menu.js +11 -316
  198. package/components/menu/menu.yaml +4 -0
  199. package/components/modal/class.js +231 -0
  200. package/components/modal/modal.a2ui.json +6 -1
  201. package/components/modal/modal.d.ts +33 -0
  202. package/components/modal/modal.js +8 -212
  203. package/components/modal/modal.yaml +19 -39
  204. package/components/nav/class.js +150 -0
  205. package/components/nav/nav.a2ui.json +1 -0
  206. package/components/nav/nav.d.ts +41 -0
  207. package/components/nav/nav.js +8 -131
  208. package/components/nav-group/class.js +152 -0
  209. package/components/nav-group/nav-group.a2ui.json +1 -0
  210. package/components/nav-group/nav-group.d.ts +45 -0
  211. package/components/nav-group/nav-group.js +9 -134
  212. package/components/nav-item/class.js +86 -0
  213. package/components/nav-item/nav-item.a2ui.json +1 -0
  214. package/components/nav-item/nav-item.d.ts +47 -0
  215. package/components/nav-item/nav-item.js +10 -69
  216. package/components/noodles/class.js +510 -0
  217. package/components/noodles/noodles.a2ui.json +1 -0
  218. package/components/noodles/noodles.d.ts +47 -0
  219. package/components/noodles/noodles.js +9 -493
  220. package/components/option-card/class.js +167 -0
  221. package/components/option-card/option-card.a2ui.json +3 -0
  222. package/components/option-card/option-card.js +8 -149
  223. package/components/option-card/option-card.yaml +4 -0
  224. package/components/otp-input/class.js +180 -0
  225. package/components/otp-input/otp-input.a2ui.json +6 -1
  226. package/components/otp-input/otp-input.js +9 -162
  227. package/components/otp-input/otp-input.yaml +45 -174
  228. package/components/page/class.js +97 -0
  229. package/components/page/page.a2ui.json +1 -0
  230. package/components/page/page.d.ts +47 -0
  231. package/components/page/page.js +8 -79
  232. package/components/pagination/class.js +195 -0
  233. package/components/pagination/pagination.a2ui.json +1 -0
  234. package/components/pagination/pagination.d.ts +33 -0
  235. package/components/pagination/pagination.js +9 -177
  236. package/components/pane/class.js +186 -0
  237. package/components/pane/pane.a2ui.json +20 -2
  238. package/components/pane/pane.d.ts +41 -0
  239. package/components/pane/pane.js +8 -167
  240. package/components/pane/pane.yaml +64 -158
  241. package/components/pipeline-status/class.js +189 -0
  242. package/components/pipeline-status/pipeline-status.a2ui.json +8 -1
  243. package/components/pipeline-status/pipeline-status.d.ts +22 -0
  244. package/components/pipeline-status/pipeline-status.js +9 -172
  245. package/components/pipeline-status/pipeline-status.yaml +34 -72
  246. package/components/popover/class.js +194 -0
  247. package/components/popover/popover.a2ui.json +1 -0
  248. package/components/popover/popover.d.ts +24 -0
  249. package/components/popover/popover.js +9 -176
  250. package/components/progress/class.js +74 -0
  251. package/components/progress/progress.a2ui.json +4 -0
  252. package/components/progress/progress.d.ts +20 -0
  253. package/components/progress/progress.js +10 -57
  254. package/components/progress/progress.yaml +124 -287
  255. package/components/progress-row/class.js +110 -0
  256. package/components/progress-row/progress-row.a2ui.json +3 -0
  257. package/components/progress-row/progress-row.d.ts +24 -0
  258. package/components/progress-row/progress-row.js +8 -92
  259. package/components/progress-row/progress-row.yaml +4 -0
  260. package/components/radio/class.js +83 -0
  261. package/components/radio/radio.a2ui.json +1 -0
  262. package/components/radio/radio.js +11 -67
  263. package/components/range/class.js +194 -0
  264. package/components/range/range.a2ui.json +1 -0
  265. package/components/range/range.js +9 -176
  266. package/components/rating/class.js +148 -0
  267. package/components/rating/rating.a2ui.json +1 -0
  268. package/components/rating/rating.js +9 -130
  269. package/components/richtext/class.js +87 -0
  270. package/components/richtext/richtext.a2ui.json +8 -1
  271. package/components/richtext/richtext.d.ts +20 -0
  272. package/components/richtext/richtext.js +8 -68
  273. package/components/richtext/richtext.yaml +30 -65
  274. package/components/row/class.js +50 -0
  275. package/components/row/row.a2ui.json +1 -0
  276. package/components/row/row.d.ts +37 -0
  277. package/components/row/row.js +10 -33
  278. package/components/search/class.js +134 -0
  279. package/components/search/search.a2ui.json +1 -0
  280. package/components/search/search.js +10 -117
  281. package/components/section/section.a2ui.json +1 -0
  282. package/components/segment/class.js +62 -0
  283. package/components/segment/segment.a2ui.json +3 -0
  284. package/components/segment/segment.d.ts +26 -0
  285. package/components/segment/segment.js +10 -45
  286. package/components/segment/segment.yaml +4 -0
  287. package/components/segmented/class.js +165 -0
  288. package/components/segmented/segmented.a2ui.json +5 -0
  289. package/components/segmented/segmented.js +10 -148
  290. package/components/segmented/segmented.yaml +41 -59
  291. package/components/select/class.js +408 -0
  292. package/components/select/select.a2ui.json +3 -0
  293. package/components/select/select.js +15 -396
  294. package/components/select/select.yaml +4 -0
  295. package/components/skeleton/class.js +52 -0
  296. package/components/skeleton/skeleton.a2ui.json +1 -0
  297. package/components/skeleton/skeleton.d.ts +24 -0
  298. package/components/skeleton/skeleton.js +8 -34
  299. package/components/slider/class.js +184 -0
  300. package/components/slider/slider.a2ui.json +1 -0
  301. package/components/slider/slider.js +9 -166
  302. package/components/stack/class.js +28 -0
  303. package/components/stack/stack.a2ui.json +1 -0
  304. package/components/stack/stack.d.ts +18 -0
  305. package/components/stack/stack.js +10 -11
  306. package/components/stat/stat.a2ui.json +1 -0
  307. package/components/step-progress/class.js +98 -0
  308. package/components/step-progress/step-progress.a2ui.json +1 -0
  309. package/components/step-progress/step-progress.d.ts +28 -0
  310. package/components/step-progress/step-progress.js +8 -79
  311. package/components/stepper/class.js +126 -0
  312. package/components/stepper/stepper.a2ui.json +3 -0
  313. package/components/stepper/stepper.d.ts +20 -0
  314. package/components/stepper/stepper.js +9 -112
  315. package/components/stepper/stepper.yaml +4 -0
  316. package/components/stream/class.js +109 -0
  317. package/components/stream/stream.a2ui.json +1 -0
  318. package/components/stream/stream.d.ts +33 -0
  319. package/components/stream/stream.js +8 -90
  320. package/components/swatch/class.js +131 -0
  321. package/components/swatch/swatch.a2ui.json +1 -0
  322. package/components/swatch/swatch.d.ts +29 -0
  323. package/components/swatch/swatch.js +8 -112
  324. package/components/swiper/class.js +373 -0
  325. package/components/swiper/swiper.a2ui.json +7 -0
  326. package/components/swiper/swiper.d.ts +45 -0
  327. package/components/swiper/swiper.js +8 -354
  328. package/components/swiper/swiper.yaml +72 -212
  329. package/components/switch/class.js +63 -0
  330. package/components/switch/switch.a2ui.json +7 -1
  331. package/components/switch/switch.js +11 -47
  332. package/components/switch/switch.yaml +70 -265
  333. package/components/table/class.js +1453 -0
  334. package/components/table/table.a2ui.json +7 -0
  335. package/components/table/table.d.ts +55 -0
  336. package/components/table/table.js +8 -1435
  337. package/components/table/table.yaml +8 -0
  338. package/components/table-toolbar/class.js +680 -0
  339. package/components/table-toolbar/table-toolbar.a2ui.json +12 -0
  340. package/components/table-toolbar/table-toolbar.d.ts +49 -0
  341. package/components/table-toolbar/table-toolbar.js +8 -689
  342. package/components/table-toolbar/table-toolbar.yaml +13 -0
  343. package/components/tabs/class.js +242 -0
  344. package/components/tabs/tabs.a2ui.json +3 -0
  345. package/components/tabs/tabs.d.ts +31 -0
  346. package/components/tabs/tabs.js +8 -223
  347. package/components/tabs/tabs.yaml +4 -0
  348. package/components/tag/class.js +99 -0
  349. package/components/tag/tag.a2ui.json +1 -0
  350. package/components/tag/tag.d.ts +37 -0
  351. package/components/tag/tag.js +8 -80
  352. package/components/text/class.js +46 -0
  353. package/components/text/text.a2ui.json +1 -0
  354. package/components/text/text.d.ts +26 -0
  355. package/components/text/text.js +9 -28
  356. package/components/textarea/class.js +134 -0
  357. package/components/textarea/textarea.a2ui.json +1 -0
  358. package/components/textarea/textarea.js +11 -118
  359. package/components/timeline/class.js +176 -0
  360. package/components/timeline/timeline.a2ui.json +18 -1
  361. package/components/timeline/timeline.d.ts +36 -0
  362. package/components/timeline/timeline.js +9 -162
  363. package/components/timeline/timeline.yaml +14 -1
  364. package/components/toast/class.js +92 -0
  365. package/components/toast/toast.a2ui.json +1 -0
  366. package/components/toast/toast.d.ts +33 -0
  367. package/components/toast/toast.js +9 -76
  368. package/components/toggle-group/class.js +154 -0
  369. package/components/toggle-group/toggle-group.a2ui.json +1 -0
  370. package/components/toggle-group/toggle-group.d.ts +29 -0
  371. package/components/toggle-group/toggle-group.js +11 -140
  372. package/components/toggle-scheme/class.js +286 -0
  373. package/components/toggle-scheme/toggle-scheme.a2ui.json +3 -0
  374. package/components/toggle-scheme/toggle-scheme.d.ts +51 -0
  375. package/components/toggle-scheme/toggle-scheme.js +8 -268
  376. package/components/toggle-scheme/toggle-scheme.yaml +4 -0
  377. package/components/toolbar/class.js +388 -0
  378. package/components/toolbar/toolbar.a2ui.json +3 -0
  379. package/components/toolbar/toolbar.d.ts +24 -0
  380. package/components/toolbar/toolbar.js +10 -376
  381. package/components/toolbar/toolbar.yaml +4 -0
  382. package/components/tooltip/class.js +299 -0
  383. package/components/tooltip/tooltip.a2ui.json +1 -0
  384. package/components/tooltip/tooltip.d.ts +28 -0
  385. package/components/tooltip/tooltip.js +8 -280
  386. package/components/tree/class.js +245 -0
  387. package/components/tree/tree.a2ui.json +3 -0
  388. package/components/tree/tree.d.ts +25 -0
  389. package/components/tree/tree.js +9 -244
  390. package/components/tree/tree.yaml +4 -0
  391. package/components/upload/class.js +199 -0
  392. package/components/upload/upload.a2ui.json +1 -0
  393. package/components/upload/upload.js +11 -183
  394. package/core/icons-phosphor.js +93 -0
  395. package/core/icons.js +92 -90
  396. package/core/index.js +5 -0
  397. package/index.d.ts +160 -5
  398. package/index.js +7 -0
  399. package/package.json +7 -2
package/README.md CHANGED
@@ -175,6 +175,45 @@ Authoring rules (enforced by `ui-audit-coherence`):
175
175
  5. **Light DOM only.** No `::part()`, `::slotted()`, shadow roots. Use
176
176
  attribute selectors on children: `:scope > [slot="icon"]`.
177
177
 
178
+ ### `static template` is a closure — import what it references
179
+
180
+ The `static template` property is a regular JavaScript closure (typically a tagged template literal — `() => html` followed by the template body). Any signal, variable, or function it references must be **lexically in scope** at the file where the class is defined. This is JavaScript scoping, not anything AdiaUI-specific — but it surprises authors coming from frameworks where templates magically receive props.
181
+
182
+ ```js
183
+ // ❌ WRONG — ReferenceError at runtime: minL is not defined
184
+ // (no import; the template function can't see minL just because
185
+ // it's exported elsewhere in the monorepo)
186
+ class MyPanel extends UIElement {
187
+ static template = () => html`<div>L: ${minL.value}</div>`;
188
+ }
189
+
190
+ // ✅ RIGHT — import the signal locally
191
+ import { minL } from './state.js';
192
+
193
+ class MyPanel extends UIElement {
194
+ static template = () => html`<div>L: ${minL.value}</div>`;
195
+ }
196
+ ```
197
+
198
+ The error surfaces in the browser console as `ReferenceError: minL is not defined` at first render — not at module load, not at `tsc --noEmit`. **The trace points at the template function body**, not at the missing import, which is the disorienting part.
199
+
200
+ If your primitive needs external reactive state that varies per-instance, **expose it as a property** rather than reaching for module-scoped signals:
201
+
202
+ ```js
203
+ // ✅ Best — per-instance reactive prop
204
+ class MyPanel extends UIElement {
205
+ static properties = {
206
+ minL: { type: Number, default: 0 },
207
+ };
208
+ static template = el => html`<div>L: ${el.minL}</div>`;
209
+ }
210
+
211
+ // Consumer:
212
+ <my-panel .minL=${minL}></my-panel> // signal binds reactively per ADR-template-binding
213
+ ```
214
+
215
+ The `el` parameter is the element instance — every signal-backed property is reactively read.
216
+
178
217
  Full authoring contract: [`docs/specs/component-token-contract.md`](../../docs/specs/component-token-contract.md).
179
218
  The `adia-ui-author` skill encodes the 20 non-negotiable rules.
180
219
 
package/USAGE.md CHANGED
@@ -445,33 +445,53 @@ register('my-slider', MySlider);
445
445
 
446
446
  The `slider-ui` import auto-registers, but that doesn't interfere — `my-slider` is a distinct tag that hosts your subclass.
447
447
 
448
- ### Roadmap — non-side-effect class imports
448
+ ### Non-side-effect class imports (since v0.4.7)
449
449
 
450
- A future v0.4.x release will ship a non-side-effect `class` subpath per component:
450
+ Every component ships a sibling `class` subpath that exports the class **without** running `customElements.define`. Use it when you need test isolation, tag-name override, or selective composition:
451
+
452
+ ```js
453
+ // Auto-register (default; tag registered immediately):
454
+ import '@adia-ai/web-components/components/slider';
455
+
456
+ // Class import (no auto-register; you decide when to define):
457
+ import { UISlider } from '@adia-ai/web-components/components/slider/class';
458
+
459
+ // Subclass + register under a different tag
460
+ class MySlider extends UISlider {
461
+ static properties = { ...UISlider.properties, custom: { type: String } };
462
+ }
463
+ customElements.define('my-slider', MySlider);
464
+ ```
465
+
466
+ **Test isolation example** — register the class under a unique per-test tag so subclass tests don't clobber the global registration:
451
467
 
452
468
  ```js
453
- // FUTURE — not available yet (v0.4.7+)
454
469
  import { UISlider } from '@adia-ai/web-components/components/slider/class';
455
- // imports the class without running customElements.define
470
+ import { defineIfFree } from '@adia-ai/web-components/core';
471
+
472
+ beforeEach(() => {
473
+ const tag = `slider-ui-test-${Math.random().toString(36).slice(2, 8)}`;
474
+ defineIfFree(tag, class extends UISlider { /* test overrides */ });
475
+ });
456
476
  ```
457
477
 
458
- This will enable test isolation (register the class under a different tag in unit tests without clobbering the global) + true tree-shaking elimination of un-used primitives. Until then, importing the auto-register subpath is the canonical path, and `defineIfFree` covers conflict avoidance.
478
+ The class subpath is available for every component that has an `<x-ui>` tag (~95 primitives). TypeScript types are picked up from the same per-primitive `.d.ts` files used by the auto-register path no separate `.d.ts` per subpath needed.
459
479
 
460
480
  ---
461
481
 
462
482
  ## TypeScript
463
483
 
464
- Since v0.4.6, the package ships hand-written `.d.ts` declarations. Adding the package to your dependencies automatically picks up:
484
+ Since v0.4.6, the package ships `.d.ts` declarations. v0.4.6 covered the 17 form-bearing primitives (input/select/slider/etc.) with hand-authored rich event types; v0.4.7 codegen extended coverage to the remaining 73 non-form primitives (button/card/table/chart/etc.) from each component's `.a2ui.json` sidecar. **90 of 95** primitives that ship a JS class are now typed (the 5 CSS-only "elements" — `header`, `footer`, `section`, etc. — have no class). Adding the package to your dependencies automatically picks up:
465
485
 
466
486
  - Typed properties on every primitive (e.g. `el.value` is `number` on `<slider-ui>`, `boolean` on `<switch-ui>`)
467
487
  - Typed events — `addEventListener('change', e => e.detail.value)` infers the detail shape
468
- - `HTMLElementTagNameMap` augmentation — `document.querySelector('slider-ui')` returns `UISliderElement`
488
+ - `HTMLElementTagNameMap` augmentation — `document.querySelector('slider-ui')` returns `UISlider`
469
489
  - Public types for `UIElement`, `UIFormElement`, signal, computed, effect, html, stamp
470
490
 
471
491
  ```ts
472
- import type { UISliderElement, SliderChangeEvent } from '@adia-ai/web-components';
492
+ import type { UISlider, SliderChangeEvent } from '@adia-ai/web-components';
473
493
 
474
- const slider: UISliderElement = document.querySelector('slider-ui')!;
494
+ const slider: UISlider = document.querySelector('slider-ui')!;
475
495
  slider.value = 75; // typed Number — string would error
476
496
 
477
497
  slider.addEventListener('change', (e: SliderChangeEvent) => {
@@ -29,6 +29,9 @@
29
29
  "x-adiaui": {
30
30
  "anti_patterns": [],
31
31
  "category": "container",
32
+ "composes": [
33
+ "icon-ui"
34
+ ],
32
35
  "events": {
33
36
  "change": {
34
37
  "description": "Fired when the set of open panels changes"
@@ -0,0 +1,27 @@
1
+ /**
2
+ * `<accordion-ui>` — Accordion container managing single/multiple open states.
3
+ *
4
+ * @see https://ui-kit.exe.xyz/site/components/accordion
5
+ *
6
+ * Type declarations generated by scripts/build/dts-codegen.mjs from
7
+ * the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
8
+ * run `npm run build:components`, then `npm run codegen:dts` to
9
+ * regenerate; or hand-author this file fully if rich event types are
10
+ * needed beyond what the yaml `events:` block can express.
11
+ */
12
+
13
+ import { UIElement } from '../../core/element.js';
14
+
15
+ export type AccordionChangeEvent = CustomEvent<unknown>;
16
+
17
+ export class UIAccordion extends UIElement {
18
+ /** Allow multiple panels to be open simultaneously */
19
+ multiple: boolean;
20
+
21
+ addEventListener<K extends keyof HTMLElementEventMap>(
22
+ type: K,
23
+ listener: (this: UIAccordion, ev: HTMLElementEventMap[K]) => unknown,
24
+ options?: boolean | AddEventListenerOptions,
25
+ ): void;
26
+ addEventListener(type: 'change', listener: (ev: AccordionChangeEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
27
+ }
@@ -1,125 +1,18 @@
1
1
  /**
2
- * <accordion-ui>
3
- * <accordion-item-ui text="Section 1">Content for section 1</accordion-item-ui>
4
- * <accordion-item-ui text="Section 2">Content for section 2</accordion-item-ui>
5
- * </accordion-ui>
2
+ * `<accordion-ui>` — auto-registers the tag on import.
6
3
  *
7
- * Accordion container + item pair.
8
- * Container manages single/multiple open states.
9
- * Items handle their own expand/collapse toggle.
4
+ * For non-side-effect class import (test isolation, tag override), use
5
+ * the `class` subpath:
10
6
  *
11
- * Events (on accordion-item-ui):
12
- * toggle — { detail: { open } }
7
+ * import { UIAccordion, UIAccordionItem } from '@adia-ai/web-components/components/accordion/class';
8
+ *
9
+ * @see ../../USAGE.md#registration--auto-vs-explicit
13
10
  */
14
11
 
15
- import { UIElement } from '../../core/element.js';
16
-
17
- // ── Accordion Container ────────────────────────────────────────
18
-
19
- class UIAccordion extends UIElement {
20
- static properties = {
21
- multiple: { type: Boolean, default: false, reflect: true },
22
- };
23
-
24
- static template = () => null;
25
-
26
- connected() {
27
- this.addEventListener('toggle', this.#onItemToggle);
28
- }
29
-
30
- disconnected() {
31
- this.removeEventListener('toggle', this.#onItemToggle);
32
- }
33
-
34
- #onItemToggle = (e) => {
35
- if (this.multiple) return;
36
-
37
- const target = e.target;
38
- if (!target.open) return;
39
-
40
- // Close other items
41
- const items = this.querySelectorAll('accordion-item-ui');
42
- for (const item of items) {
43
- if (item !== target && item.open) {
44
- item.open = false;
45
- }
46
- }
47
- };
48
- }
49
- customElements.define('accordion-ui', UIAccordion);
50
-
51
- // ── Accordion Item ─────────────────────────────────────────────
52
-
53
- class UIAccordionItem extends UIElement {
54
- static properties = {
55
- text: { type: String, default: '', reflect: true },
56
- open: { type: Boolean, default: false, reflect: true },
57
- };
58
-
59
- static template = () => null;
60
-
61
- #bound = false;
62
-
63
- connected() {
64
- // Stamp header if not present
65
- if (!this.querySelector('[slot="header"]')) {
66
- const header = document.createElement('div');
67
- header.setAttribute('slot', 'header');
68
-
69
- const label = document.createElement('span');
70
- label.setAttribute('slot', 'header-text');
71
- header.appendChild(label);
72
-
73
- const caret = document.createElement('icon-ui');
74
- caret.setAttribute('name', 'caret-down');
75
- caret.setAttribute('slot', 'caret');
76
- header.appendChild(caret);
77
-
78
- this.prepend(header);
79
- }
80
-
81
- // Stamp content wrapper if not present
82
- if (!this.querySelector('[slot="body"]')) {
83
- const body = document.createElement('div');
84
- body.setAttribute('slot', 'body');
85
-
86
- // Move non-slotted children into body
87
- const children = [...this.childNodes].filter(n => {
88
- if (n.nodeType === 1) return !n.hasAttribute('slot');
89
- return n.nodeType === 3 && n.textContent.trim();
90
- });
91
- for (const child of children) body.appendChild(child);
92
-
93
- this.appendChild(body);
94
- }
95
-
96
- if (!this.#bound) {
97
- this.#bound = true;
98
- this.addEventListener('click', this.#onClick);
99
- }
100
- }
101
-
102
- disconnected() {
103
- this.removeEventListener('click', this.#onClick);
104
- this.#bound = false;
105
- }
106
-
107
- render() {
108
- const label = this.querySelector('[slot="header-text"]');
109
- if (label) label.textContent = this.text;
110
- }
111
-
112
- #onClick = (e) => {
113
- const header = this.querySelector('[slot="header"]');
114
- if (!header || !header.contains(e.target)) return;
12
+ import { defineIfFree } from '../../core/register.js';
13
+ import { UIAccordion, UIAccordionItem } from './class.js';
115
14
 
116
- this.open = !this.open;
117
- this.dispatchEvent(new CustomEvent('toggle', {
118
- bubbles: true,
119
- detail: { open: this.open },
120
- }));
121
- };
122
- }
123
- customElements.define('accordion-item-ui', UIAccordionItem);
15
+ defineIfFree('accordion-ui', UIAccordion);
16
+ defineIfFree('accordion-item-ui', UIAccordionItem);
124
17
 
125
18
  export { UIAccordion, UIAccordionItem };
@@ -7,6 +7,10 @@ component: Accordion
7
7
  category: container
8
8
  version: 1
9
9
  description: Accordion container managing single/multiple open states.
10
+ # Per ADR-0027 — primitives that programmatically create other primitives
11
+ # do NOT auto-import them. Consumer (or demo shell) must explicitly import.
12
+ composes:
13
+ - icon-ui
10
14
  props:
11
15
  multiple:
12
16
  description: Allow multiple panels to be open simultaneously
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Non-side-effect class export for `<accordion-ui>` (+ co-located primitives).
3
+ *
4
+ * Importing this file gives you the class(es) without auto-registering the tag.
5
+ * Useful for test isolation, subclassing with tag-name override, or selective
6
+ * composition.
7
+ *
8
+ * The auto-register path stays at `@adia-ai/web-components/components/accordion`
9
+ * (which imports this file + calls `defineIfFree()`).
10
+ *
11
+ * @see ../../USAGE.md#registration--auto-vs-explicit
12
+ */
13
+
14
+ /**
15
+ * <accordion-ui>
16
+ * <accordion-item-ui text="Section 1">Content for section 1</accordion-item-ui>
17
+ * <accordion-item-ui text="Section 2">Content for section 2</accordion-item-ui>
18
+ * </accordion-ui>
19
+ *
20
+ * Accordion container + item pair.
21
+ * Container manages single/multiple open states.
22
+ * Items handle their own expand/collapse toggle.
23
+ *
24
+ * Events (on accordion-item-ui):
25
+ * toggle — { detail: { open } }
26
+ */
27
+
28
+ import { UIElement } from '../../core/element.js';
29
+
30
+ // ── Accordion Container ────────────────────────────────────────
31
+
32
+ export class UIAccordion extends UIElement {
33
+ static properties = {
34
+ multiple: { type: Boolean, default: false, reflect: true },
35
+ };
36
+
37
+ static template = () => null;
38
+
39
+ connected() {
40
+ this.addEventListener('toggle', this.#onItemToggle);
41
+ }
42
+
43
+ disconnected() {
44
+ this.removeEventListener('toggle', this.#onItemToggle);
45
+ }
46
+
47
+ #onItemToggle = (e) => {
48
+ if (this.multiple) return;
49
+
50
+ const target = e.target;
51
+ if (!target.open) return;
52
+
53
+ // Close other items
54
+ const items = this.querySelectorAll('accordion-item-ui');
55
+ for (const item of items) {
56
+ if (item !== target && item.open) {
57
+ item.open = false;
58
+ }
59
+ }
60
+ };
61
+ }
62
+
63
+ export class UIAccordionItem extends UIElement {
64
+ static properties = {
65
+ text: { type: String, default: '', reflect: true },
66
+ open: { type: Boolean, default: false, reflect: true },
67
+ };
68
+
69
+ static template = () => null;
70
+
71
+ #bound = false;
72
+
73
+ connected() {
74
+ // Stamp header if not present
75
+ if (!this.querySelector('[slot="header"]')) {
76
+ const header = document.createElement('div');
77
+ header.setAttribute('slot', 'header');
78
+
79
+ const label = document.createElement('span');
80
+ label.setAttribute('slot', 'header-text');
81
+ header.appendChild(label);
82
+
83
+ const caret = document.createElement('icon-ui');
84
+ caret.setAttribute('name', 'caret-down');
85
+ caret.setAttribute('slot', 'caret');
86
+ header.appendChild(caret);
87
+
88
+ this.prepend(header);
89
+ }
90
+
91
+ // Stamp content wrapper if not present
92
+ if (!this.querySelector('[slot="body"]')) {
93
+ const body = document.createElement('div');
94
+ body.setAttribute('slot', 'body');
95
+
96
+ // Move non-slotted children into body
97
+ const children = [...this.childNodes].filter(n => {
98
+ if (n.nodeType === 1) return !n.hasAttribute('slot');
99
+ return n.nodeType === 3 && n.textContent.trim();
100
+ });
101
+ for (const child of children) body.appendChild(child);
102
+
103
+ this.appendChild(body);
104
+ }
105
+
106
+ if (!this.#bound) {
107
+ this.#bound = true;
108
+ this.addEventListener('click', this.#onClick);
109
+ }
110
+ }
111
+
112
+ disconnected() {
113
+ this.removeEventListener('click', this.#onClick);
114
+ this.#bound = false;
115
+ }
116
+
117
+ render() {
118
+ const label = this.querySelector('[slot="header-text"]');
119
+ if (label) label.textContent = this.text;
120
+ }
121
+
122
+ #onClick = (e) => {
123
+ const header = this.querySelector('[slot="header"]');
124
+ if (!header || !header.contains(e.target)) return;
125
+
126
+ this.open = !this.open;
127
+ this.dispatchEvent(new CustomEvent('toggle', {
128
+ bubbles: true,
129
+ detail: { open: this.open },
130
+ }));
131
+ };
132
+ }
@@ -24,6 +24,9 @@
24
24
  "x-adiaui": {
25
25
  "anti_patterns": [],
26
26
  "category": "navigation",
27
+ "composes": [
28
+ "icon-ui"
29
+ ],
27
30
  "events": {
28
31
  "action": {
29
32
  "description": "Fired on action."
@@ -0,0 +1,25 @@
1
+ /**
2
+ * `<action-list-ui>` — Inline list of command actions with keyboard navigation. Fires action event when an item is clicked or activated via keyboard.
3
+ *
4
+ * @see https://ui-kit.exe.xyz/site/components/action-list
5
+ *
6
+ * Type declarations generated by scripts/build/dts-codegen.mjs from
7
+ * the component's `.a2ui.json` sidecar. Edit the source `.yaml`,
8
+ * run `npm run build:components`, then `npm run codegen:dts` to
9
+ * regenerate; or hand-author this file fully if rich event types are
10
+ * needed beyond what the yaml `events:` block can express.
11
+ */
12
+
13
+ import { UIElement } from '../../core/element.js';
14
+
15
+ export type ActionListActionEvent = CustomEvent<unknown>;
16
+
17
+ export class UIActionList extends UIElement {
18
+
19
+ addEventListener<K extends keyof HTMLElementEventMap>(
20
+ type: K,
21
+ listener: (this: UIActionList, ev: HTMLElementEventMap[K]) => unknown,
22
+ options?: boolean | AddEventListenerOptions,
23
+ ): void;
24
+ addEventListener(type: 'action', listener: (ev: ActionListActionEvent) => unknown, options?: boolean | AddEventListenerOptions): void;
25
+ }
@@ -1,149 +1,18 @@
1
1
  /**
2
- * <action-list-ui>
3
- * <action-item-ui icon="plus" text="New Project" value="new"></action-item-ui>
4
- * <action-item-ui icon="users" text="Invite Team" value="invite"></action-item-ui>
5
- * <action-item-ui icon="download" text="Export Data" value="export"></action-item-ui>
6
- * </action-list-ui>
2
+ * `<action-list-ui>` — auto-registers the tag on import.
7
3
  *
8
- * Inline (non-dropdown) list of command actions. Think of it as a menu that
9
- * stays open — useful for quick-actions cards, settings rails, sidebar shortcuts.
4
+ * For non-side-effect class import (test isolation, tag override), use
5
+ * the `class` subpath:
10
6
  *
11
- * Differs from <menu-ui> (which renders in a popover) and <list-ui> (which is
12
- * passive — no hover/click semantics).
7
+ * import { UIActionList, UIActionItem } from '@adia-ai/web-components/components/action-list/class';
13
8
  *
14
- * Fires `action` CustomEvent with { value, text, item } when an item is clicked
15
- * or activated via keyboard (Enter / Space). Keyboard nav: ArrowUp/Down, Home/End.
9
+ * @see ../../USAGE.md#registration--auto-vs-explicit
16
10
  */
17
11
 
18
- import { UIElement } from '../../core/element.js';
12
+ import { defineIfFree } from '../../core/register.js';
13
+ import { UIActionList, UIActionItem } from './class.js';
19
14
 
20
- class UIActionList extends UIElement {
21
- static properties = {};
22
- static template = () => null;
23
-
24
- #bound = false;
25
-
26
- connected() {
27
- this.setAttribute('role', 'list');
28
- if (!this.#bound) {
29
- this.#bound = true;
30
- this.addEventListener('click', this.#onClick);
31
- this.addEventListener('keydown', this.#onKey);
32
- }
33
- }
34
-
35
- disconnected() {
36
- this.removeEventListener('click', this.#onClick);
37
- this.removeEventListener('keydown', this.#onKey);
38
- this.#bound = false;
39
- }
40
-
41
- #items() {
42
- return Array.from(this.querySelectorAll(':scope > action-item-ui:not([disabled])'));
43
- }
44
-
45
- #onClick = (e) => {
46
- const item = e.target.closest('action-item-ui');
47
- if (!item || item.hasAttribute('disabled')) return;
48
- if (!this.contains(item)) return;
49
- this.dispatchEvent(new CustomEvent('action', {
50
- bubbles: true,
51
- detail: { value: item.getAttribute('value') || '', text: item.getAttribute('text') || item.textContent.trim(), item },
52
- }));
53
- };
54
-
55
- #onKey = (e) => {
56
- const items = this.#items();
57
- if (!items.length) return;
58
- const active = document.activeElement?.closest?.('action-item-ui');
59
- const i = active ? items.indexOf(active) : -1;
60
- const focus = (idx) => {
61
- const next = items[(idx + items.length) % items.length];
62
- next?.focus?.({ preventScroll: true });
63
- };
64
- switch (e.key) {
65
- case 'ArrowDown': e.preventDefault(); focus(i + 1); break;
66
- case 'ArrowUp': e.preventDefault(); focus(i - 1); break;
67
- case 'Home': e.preventDefault(); focus(0); break;
68
- case 'End': e.preventDefault(); focus(items.length - 1); break;
69
- case 'Enter':
70
- case ' ': {
71
- if (active) { e.preventDefault(); active.click(); }
72
- break;
73
- }
74
- }
75
- };
76
- }
77
-
78
- customElements.define('action-list-ui', UIActionList);
79
-
80
- class UIActionItem extends UIElement {
81
- static properties = {
82
- icon: { type: String, default: '', reflect: true },
83
- text: { type: String, default: '', reflect: true },
84
- value: { type: String, default: '', reflect: true },
85
- variant: { type: String, default: 'default', reflect: true },
86
- disabled: { type: Boolean, default: false, reflect: true },
87
- };
88
-
89
- static template = () => null;
90
-
91
- connected() {
92
- this.setAttribute('role', 'listitem');
93
- if (!this.hasAttribute('tabindex')) this.setAttribute('tabindex', '0');
94
- this.#stamp();
95
- this.#syncAria();
96
- }
97
-
98
- #stamp() {
99
- if (this.querySelector('[slot="text"]')) return;
100
-
101
- if (this.icon) {
102
- const iconEl = document.createElement('icon-ui');
103
- iconEl.setAttribute('slot', 'icon');
104
- iconEl.setAttribute('name', this.icon);
105
- this.appendChild(iconEl);
106
- }
107
-
108
- if (this.text) {
109
- const span = document.createElement('span');
110
- span.setAttribute('slot', 'text');
111
- span.textContent = this.text;
112
- this.appendChild(span);
113
- }
114
- }
115
-
116
- #syncAria() {
117
- if (this.disabled) {
118
- this.setAttribute('aria-disabled', 'true');
119
- this.setAttribute('tabindex', '-1');
120
- } else {
121
- this.removeAttribute('aria-disabled');
122
- this.setAttribute('tabindex', '0');
123
- }
124
- }
125
-
126
- render() {
127
- const iconEl = this.querySelector('[slot="icon"]');
128
- if (this.icon) {
129
- if (iconEl) iconEl.setAttribute('name', this.icon);
130
- else {
131
- const el = document.createElement('icon-ui');
132
- el.setAttribute('slot', 'icon');
133
- el.setAttribute('name', this.icon);
134
- this.prepend(el);
135
- }
136
- } else if (iconEl) {
137
- iconEl.remove();
138
- }
139
-
140
- const textEl = this.querySelector('[slot="text"]');
141
- if (textEl) textEl.textContent = this.text;
142
-
143
- this.#syncAria();
144
- }
145
- }
146
-
147
- customElements.define('action-item-ui', UIActionItem);
15
+ defineIfFree('action-list-ui', UIActionList);
16
+ defineIfFree('action-item-ui', UIActionItem);
148
17
 
149
18
  export { UIActionList, UIActionItem };
@@ -8,6 +8,10 @@ category: navigation
8
8
  version: 1
9
9
  description: Inline list of command actions with keyboard navigation. Fires action event when an
10
10
  item is clicked or activated via keyboard.
11
+ # Per ADR-0027 — primitives that programmatically create other primitives
12
+ # do NOT auto-import them. Consumer (or demo shell) must explicitly import.
13
+ composes:
14
+ - icon-ui
11
15
  props: {}
12
16
  events:
13
17
  action: