@adia-ai/web-components 0.4.6 → 0.4.7

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 (284) hide show
  1. package/USAGE.md +29 -9
  2. package/components/accordion/accordion.d.ts +17 -0
  3. package/components/accordion/accordion.js +10 -117
  4. package/components/accordion/class.js +132 -0
  5. package/components/action-list/action-list.d.ts +15 -0
  6. package/components/action-list/action-list.js +9 -140
  7. package/components/action-list/class.js +156 -0
  8. package/components/agent-artifact/agent-artifact.d.ts +25 -0
  9. package/components/agent-artifact/agent-artifact.js +8 -181
  10. package/components/agent-artifact/class.js +200 -0
  11. package/components/agent-feedback-bar/agent-feedback-bar.d.ts +21 -0
  12. package/components/agent-feedback-bar/agent-feedback-bar.js +8 -143
  13. package/components/agent-feedback-bar/class.js +162 -0
  14. package/components/agent-questions/agent-questions.d.ts +23 -0
  15. package/components/agent-questions/agent-questions.js +8 -180
  16. package/components/agent-questions/class.js +199 -0
  17. package/components/agent-reasoning/agent-reasoning.d.ts +23 -0
  18. package/components/agent-reasoning/agent-reasoning.js +8 -494
  19. package/components/agent-reasoning/class.js +513 -0
  20. package/components/agent-suggestions/agent-suggestions.d.ts +21 -0
  21. package/components/agent-suggestions/agent-suggestions.js +8 -78
  22. package/components/agent-suggestions/class.js +97 -0
  23. package/components/agent-trace/agent-trace.d.ts +19 -0
  24. package/components/alert/alert.d.ts +29 -0
  25. package/components/alert/alert.js +8 -175
  26. package/components/alert/class.js +194 -0
  27. package/components/avatar/avatar.d.ts +27 -0
  28. package/components/avatar/avatar.js +9 -159
  29. package/components/avatar/class.js +173 -0
  30. package/components/badge/badge.d.ts +27 -0
  31. package/components/badge/badge.js +9 -75
  32. package/components/badge/class.js +93 -0
  33. package/components/block/block.d.ts +19 -0
  34. package/components/block/block.js +9 -15
  35. package/components/block/class.js +33 -0
  36. package/components/breadcrumb/breadcrumb.d.ts +23 -0
  37. package/components/breadcrumb/breadcrumb.js +8 -113
  38. package/components/breadcrumb/class.js +132 -0
  39. package/components/button/button.d.ts +34 -0
  40. package/components/button/button.js +15 -66
  41. package/components/button/class.js +80 -0
  42. package/components/calendar-picker/calendar-picker.a2ui.json +6 -1
  43. package/components/calendar-picker/calendar-picker.js +8 -332
  44. package/components/calendar-picker/calendar-picker.yaml +51 -177
  45. package/components/calendar-picker/class.js +351 -0
  46. package/components/canvas/canvas.a2ui.json +6 -1
  47. package/components/canvas/canvas.d.ts +17 -0
  48. package/components/canvas/canvas.yaml +19 -36
  49. package/components/card/card.a2ui.json +3 -0
  50. package/components/card/card.d.ts +27 -0
  51. package/components/card/card.js +9 -50
  52. package/components/card/card.yaml +171 -433
  53. package/components/card/class.js +68 -0
  54. package/components/chart/chart.d.ts +41 -0
  55. package/components/chart/chart.js +8 -2131
  56. package/components/chart/class.js +2150 -0
  57. package/components/chart-legend/chart-legend.d.ts +27 -0
  58. package/components/chart-legend/chart-legend.js +8 -197
  59. package/components/chart-legend/class.js +215 -0
  60. package/components/chat-thread/chat-thread.d.ts +17 -0
  61. package/components/chat-thread/chat-thread.js +8 -157
  62. package/components/chat-thread/class.js +176 -0
  63. package/components/check/check.js +11 -52
  64. package/components/check/class.js +68 -0
  65. package/components/code/class.js +501 -0
  66. package/components/code/code.js +8 -482
  67. package/components/col/class.js +30 -0
  68. package/components/col/col.d.ts +23 -0
  69. package/components/col/col.js +10 -13
  70. package/components/color-picker/class.js +550 -0
  71. package/components/color-picker/color-picker.js +8 -531
  72. package/components/command/class.js +364 -0
  73. package/components/command/command.a2ui.json +3 -0
  74. package/components/command/command.d.ts +19 -0
  75. package/components/command/command.js +8 -345
  76. package/components/command/command.yaml +105 -124
  77. package/components/demo-toggle/class.js +153 -0
  78. package/components/demo-toggle/demo-toggle.d.ts +23 -0
  79. package/components/demo-toggle/demo-toggle.js +8 -135
  80. package/components/description-list/class.js +86 -0
  81. package/components/description-list/description-list.d.ts +21 -0
  82. package/components/description-list/description-list.js +8 -67
  83. package/components/divider/class.js +57 -0
  84. package/components/divider/divider.d.ts +19 -0
  85. package/components/divider/divider.js +10 -40
  86. package/components/drawer/class.js +306 -0
  87. package/components/drawer/drawer.d.ts +25 -0
  88. package/components/drawer/drawer.js +8 -287
  89. package/components/embed/class.js +73 -0
  90. package/components/embed/embed.d.ts +23 -0
  91. package/components/embed/embed.js +9 -55
  92. package/components/empty-state/class.js +108 -0
  93. package/components/empty-state/empty-state.d.ts +21 -0
  94. package/components/empty-state/empty-state.js +9 -90
  95. package/components/feed/class.js +381 -0
  96. package/components/feed/feed.d.ts +19 -0
  97. package/components/feed/feed.js +9 -367
  98. package/components/field/class.js +266 -0
  99. package/components/field/field.d.ts +23 -0
  100. package/components/field/field.js +8 -247
  101. package/components/fields/class.js +106 -0
  102. package/components/fields/fields.d.ts +19 -0
  103. package/components/fields/fields.js +8 -87
  104. package/components/grid/class.js +31 -0
  105. package/components/grid/grid.d.ts +23 -0
  106. package/components/grid/grid.js +10 -14
  107. package/components/heatmap/class.js +305 -0
  108. package/components/heatmap/heatmap.d.ts +31 -0
  109. package/components/heatmap/heatmap.js +8 -286
  110. package/components/icon/class.js +54 -0
  111. package/components/icon/icon.d.ts +23 -0
  112. package/components/icon/icon.js +13 -40
  113. package/components/image/class.js +112 -0
  114. package/components/image/image.d.ts +33 -0
  115. package/components/image/image.js +9 -94
  116. package/components/input/class.js +773 -0
  117. package/components/input/input.a2ui.json +3 -0
  118. package/components/input/input.js +8 -755
  119. package/components/input/input.yaml +171 -442
  120. package/components/inspector/class.js +142 -0
  121. package/components/inspector/inspector.a2ui.json +8 -1
  122. package/components/inspector/inspector.d.ts +17 -0
  123. package/components/inspector/inspector.js +8 -124
  124. package/components/inspector/inspector.yaml +15 -30
  125. package/components/kbd/class.js +34 -0
  126. package/components/kbd/kbd.a2ui.json +3 -0
  127. package/components/kbd/kbd.d.ts +17 -0
  128. package/components/kbd/kbd.js +10 -17
  129. package/components/kbd/kbd.yaml +54 -185
  130. package/components/link/class.js +187 -0
  131. package/components/link/link.d.ts +55 -0
  132. package/components/link/link.js +8 -168
  133. package/components/list/class.js +249 -0
  134. package/components/list/list.d.ts +23 -0
  135. package/components/list/list.js +9 -231
  136. package/components/menu/class.js +332 -0
  137. package/components/menu/menu.d.ts +21 -0
  138. package/components/menu/menu.js +11 -316
  139. package/components/modal/class.js +231 -0
  140. package/components/modal/modal.a2ui.json +5 -1
  141. package/components/modal/modal.d.ts +23 -0
  142. package/components/modal/modal.js +8 -212
  143. package/components/modal/modal.yaml +19 -39
  144. package/components/nav/class.js +150 -0
  145. package/components/nav/nav.d.ts +31 -0
  146. package/components/nav/nav.js +8 -131
  147. package/components/nav-group/class.js +152 -0
  148. package/components/nav-group/nav-group.d.ts +35 -0
  149. package/components/nav-group/nav-group.js +9 -134
  150. package/components/nav-item/class.js +86 -0
  151. package/components/nav-item/nav-item.d.ts +37 -0
  152. package/components/nav-item/nav-item.js +10 -69
  153. package/components/noodles/class.js +510 -0
  154. package/components/noodles/noodles.d.ts +33 -0
  155. package/components/noodles/noodles.js +9 -493
  156. package/components/option-card/class.js +167 -0
  157. package/components/option-card/option-card.js +8 -149
  158. package/components/otp-input/class.js +180 -0
  159. package/components/otp-input/otp-input.a2ui.json +5 -1
  160. package/components/otp-input/otp-input.js +9 -162
  161. package/components/otp-input/otp-input.yaml +45 -174
  162. package/components/page/class.js +97 -0
  163. package/components/page/page.d.ts +46 -0
  164. package/components/page/page.js +8 -79
  165. package/components/pagination/class.js +195 -0
  166. package/components/pagination/pagination.d.ts +23 -0
  167. package/components/pagination/pagination.js +9 -177
  168. package/components/pane/class.js +186 -0
  169. package/components/pane/pane.a2ui.json +12 -1
  170. package/components/pane/pane.d.ts +31 -0
  171. package/components/pane/pane.js +8 -167
  172. package/components/pane/pane.yaml +57 -157
  173. package/components/pipeline-status/class.js +189 -0
  174. package/components/pipeline-status/pipeline-status.a2ui.json +7 -1
  175. package/components/pipeline-status/pipeline-status.d.ts +21 -0
  176. package/components/pipeline-status/pipeline-status.js +9 -172
  177. package/components/pipeline-status/pipeline-status.yaml +34 -72
  178. package/components/popover/class.js +194 -0
  179. package/components/popover/popover.d.ts +23 -0
  180. package/components/popover/popover.js +9 -176
  181. package/components/progress/class.js +74 -0
  182. package/components/progress/progress.a2ui.json +3 -0
  183. package/components/progress/progress.d.ts +19 -0
  184. package/components/progress/progress.js +10 -57
  185. package/components/progress/progress.yaml +124 -287
  186. package/components/progress-row/class.js +110 -0
  187. package/components/progress-row/progress-row.d.ts +23 -0
  188. package/components/progress-row/progress-row.js +8 -92
  189. package/components/radio/class.js +83 -0
  190. package/components/radio/radio.js +11 -67
  191. package/components/range/class.js +194 -0
  192. package/components/range/range.js +9 -176
  193. package/components/rating/class.js +148 -0
  194. package/components/rating/rating.js +9 -130
  195. package/components/richtext/class.js +87 -0
  196. package/components/richtext/richtext.a2ui.json +7 -1
  197. package/components/richtext/richtext.d.ts +19 -0
  198. package/components/richtext/richtext.js +8 -68
  199. package/components/richtext/richtext.yaml +30 -65
  200. package/components/row/class.js +50 -0
  201. package/components/row/row.d.ts +27 -0
  202. package/components/row/row.js +10 -33
  203. package/components/search/class.js +134 -0
  204. package/components/search/search.js +10 -117
  205. package/components/segment/class.js +62 -0
  206. package/components/segment/segment.d.ts +25 -0
  207. package/components/segment/segment.js +10 -45
  208. package/components/segmented/class.js +165 -0
  209. package/components/segmented/segmented.a2ui.json +4 -0
  210. package/components/segmented/segmented.js +10 -148
  211. package/components/segmented/segmented.yaml +41 -59
  212. package/components/select/class.js +408 -0
  213. package/components/select/select.js +15 -396
  214. package/components/skeleton/class.js +52 -0
  215. package/components/skeleton/skeleton.d.ts +23 -0
  216. package/components/skeleton/skeleton.js +8 -34
  217. package/components/slider/class.js +184 -0
  218. package/components/slider/slider.js +9 -166
  219. package/components/stack/class.js +28 -0
  220. package/components/stack/stack.d.ts +17 -0
  221. package/components/stack/stack.js +10 -11
  222. package/components/step-progress/class.js +98 -0
  223. package/components/step-progress/step-progress.d.ts +27 -0
  224. package/components/step-progress/step-progress.js +8 -79
  225. package/components/stepper/class.js +126 -0
  226. package/components/stepper/stepper.d.ts +19 -0
  227. package/components/stepper/stepper.js +9 -112
  228. package/components/stream/class.js +109 -0
  229. package/components/stream/stream.d.ts +19 -0
  230. package/components/stream/stream.js +8 -90
  231. package/components/swatch/class.js +131 -0
  232. package/components/swatch/swatch.d.ts +28 -0
  233. package/components/swatch/swatch.js +8 -112
  234. package/components/swiper/class.js +373 -0
  235. package/components/swiper/swiper.a2ui.json +4 -0
  236. package/components/swiper/swiper.d.ts +31 -0
  237. package/components/swiper/swiper.js +8 -354
  238. package/components/swiper/swiper.yaml +68 -212
  239. package/components/switch/class.js +63 -0
  240. package/components/switch/switch.a2ui.json +6 -1
  241. package/components/switch/switch.js +11 -47
  242. package/components/switch/switch.yaml +70 -265
  243. package/components/table/class.js +1453 -0
  244. package/components/table/table.d.ts +37 -0
  245. package/components/table/table.js +8 -1435
  246. package/components/table-toolbar/class.js +680 -0
  247. package/components/table-toolbar/table-toolbar.d.ts +33 -0
  248. package/components/table-toolbar/table-toolbar.js +8 -689
  249. package/components/tabs/class.js +242 -0
  250. package/components/tabs/tabs.d.ts +21 -0
  251. package/components/tabs/tabs.js +8 -223
  252. package/components/tag/class.js +99 -0
  253. package/components/tag/tag.d.ts +27 -0
  254. package/components/tag/tag.js +8 -80
  255. package/components/text/class.js +46 -0
  256. package/components/text/text.d.ts +25 -0
  257. package/components/text/text.js +9 -28
  258. package/components/textarea/class.js +134 -0
  259. package/components/textarea/textarea.js +11 -118
  260. package/components/timeline/class.js +176 -0
  261. package/components/timeline/timeline.d.ts +19 -0
  262. package/components/timeline/timeline.js +9 -162
  263. package/components/toast/class.js +92 -0
  264. package/components/toast/toast.d.ts +23 -0
  265. package/components/toast/toast.js +9 -76
  266. package/components/toggle-group/class.js +154 -0
  267. package/components/toggle-group/toggle-group.d.ts +19 -0
  268. package/components/toggle-group/toggle-group.js +11 -140
  269. package/components/toggle-scheme/class.js +286 -0
  270. package/components/toggle-scheme/toggle-scheme.d.ts +41 -0
  271. package/components/toggle-scheme/toggle-scheme.js +8 -268
  272. package/components/toolbar/class.js +388 -0
  273. package/components/toolbar/toolbar.d.ts +23 -0
  274. package/components/toolbar/toolbar.js +10 -376
  275. package/components/tooltip/class.js +299 -0
  276. package/components/tooltip/tooltip.d.ts +27 -0
  277. package/components/tooltip/tooltip.js +8 -280
  278. package/components/tree/class.js +245 -0
  279. package/components/tree/tree.d.ts +15 -0
  280. package/components/tree/tree.js +9 -244
  281. package/components/upload/class.js +199 -0
  282. package/components/upload/upload.js +11 -183
  283. package/index.d.ts +159 -5
  284. package/package.json +5 -1
@@ -1,5 +1,3 @@
1
- # Generated by scripts/migrate-yamls-to-v1.mjs — migrated to v1 contract.
2
- # Edit this file; run `npm run build:components` to regenerate a2ui.json.
3
1
  $schema: ../../../../scripts/schemas/component.yaml.schema.json
4
2
  name: UIPipelineStatus
5
3
  tag: pipeline-status-ui
@@ -9,91 +7,55 @@ version: 1
9
7
  description: <pipeline-status-ui> — Single updating pipeline status indicator.
10
8
  props:
11
9
  complete:
12
- description: "Component property: complete."
10
+ description: 'Component property: complete.'
13
11
  type: boolean
14
12
  default: false
15
13
  message:
16
- description: "Component property: message."
14
+ description: 'Component property: message.'
17
15
  type: string
18
- default: ""
16
+ default: ''
19
17
  stage:
20
- description: "Component property: stage."
18
+ description: 'Component property: stage.'
21
19
  type: string
22
- default: ""
20
+ default: ''
23
21
  events: {}
24
22
  slots:
25
23
  default:
26
- description: "Default slot — primary child content."
24
+ description: Default slot — primary child content.
27
25
  states:
28
- - name: idle
29
- description: Default, ready for interaction.
26
+ - name: idle
27
+ description: Default, ready for interaction.
30
28
  traits: []
31
29
  tokens: {}
32
30
  a2ui:
33
31
  rules: []
34
32
  anti_patterns: []
35
33
  examples:
36
- - name: basic-pipeline-status
37
- description: Basic PipelineStatus usage
38
- a2ui: >-
39
- [
40
- {
41
- "id": "root",
42
- "component": "Card",
43
- "children": [
44
- "sec"
45
- ]
46
- },
47
- {
48
- "id": "sec",
49
- "component": "Section",
50
- "children": [
51
- "comp"
52
- ]
53
- },
54
- {
55
- "id": "comp",
56
- "component": "PipelineStatus"
57
- }
58
- ]
59
- - name: stage
60
- description: Pipeline status with a prominent stage label for the current step.
61
- a2ui: >-
62
- [
63
- {
64
- "id": "root",
65
- "component": "PipelineStatus",
66
- "stage": "Building catalog",
67
- "message": "Reading 100 patterns from disk..."
68
- }
69
- ]
70
- - name: message
71
- description: Pipeline status with a secondary progress message updated as the stage advances.
72
- a2ui: >-
73
- [
74
- {
75
- "id": "root",
76
- "component": "PipelineStatus",
77
- "stage": "Running evals",
78
- "message": "32 / 100 intents scored..."
79
- }
80
- ]
81
- - name: complete
82
- description: Pipeline status marked complete; indicator switches to success state.
83
- a2ui: >-
84
- [
85
- {
86
- "id": "root",
87
- "component": "PipelineStatus",
88
- "stage": "Done",
89
- "message": "All 100 intents passed",
90
- "complete": true
91
- }
92
- ]
34
+ - name: basic-pipeline-status
35
+ description: Basic PipelineStatus usage
36
+ a2ui: "[\n {\n \"id\": \"root\",\n \"component\": \"Card\",\n \"children\": [\n \"sec\"\n ]\n },\n {\n\
37
+ \ \"id\": \"sec\",\n \"component\": \"Section\",\n \"children\": [\n \"comp\"\n ]\n },\n {\n \"\
38
+ id\": \"comp\",\n \"component\": \"PipelineStatus\"\n }\n]"
39
+ - name: stage
40
+ description: Pipeline status with a prominent stage label for the current step.
41
+ a2ui: "[\n {\n \"id\": \"root\",\n \"component\": \"PipelineStatus\",\n \"stage\": \"Building catalog\",\n \
42
+ \ \"message\": \"Reading 100 patterns from disk...\"\n }\n]"
43
+ - name: message
44
+ description: Pipeline status with a secondary progress message updated as the stage advances.
45
+ a2ui: "[\n {\n \"id\": \"root\",\n \"component\": \"PipelineStatus\",\n \"stage\": \"Running evals\",\n \"\
46
+ message\": \"32 / 100 intents scored...\"\n }\n]"
47
+ - name: complete
48
+ description: Pipeline status marked complete; indicator switches to success state.
49
+ a2ui: "[\n {\n \"id\": \"root\",\n \"component\": \"PipelineStatus\",\n \"stage\": \"Done\",\n \"message\"\
50
+ : \"All 100 intents passed\",\n \"complete\": true\n }\n]"
93
51
  keywords:
94
- - pipelinestatus
95
- - pipeline-status
96
- - pipeline
97
- - status
98
- synonyms: {}
52
+ - pipelinestatus
53
+ - pipeline-status
54
+ - pipeline
55
+ - status
56
+ synonyms:
57
+ tags:
58
+ - job-status
59
+ - deploy-status
60
+ - pipeline-indicator
99
61
  related: []
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Non-side-effect class export for `<popover-ui>`.
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/popover`
9
+ * (which imports this file + calls `defineIfFree()`).
10
+ *
11
+ * @see ../../USAGE.md#registration--auto-vs-explicit
12
+ */
13
+
14
+ /**
15
+ * <popover-ui trigger="click" placement="bottom-start">
16
+ * <button-ui slot="trigger" text="Open"></button-ui>
17
+ * <div slot="content">Popover content here</div>
18
+ * </popover-ui>
19
+ *
20
+ * Built on the web platform:
21
+ * • Popover API — content has popover="manual"; showPopover() promotes it
22
+ * to the top layer (no z-index, no overflow clipping, ESC bubbling handled).
23
+ * • CSS Anchor Positioning — used natively when supported, JS fallback otherwise
24
+ * (see @core/anchor.js).
25
+ *
26
+ * Triggers: click | hover | manual. ESC closes click/manual popovers.
27
+ */
28
+
29
+ import { UIElement } from '../../core/element.js';
30
+ import { anchorPopover } from '../../core/anchor.js';
31
+
32
+ const HOVER_CLOSE_DELAY = 120;
33
+
34
+ export class UIPopover extends UIElement {
35
+ static properties = {
36
+ placement: { type: String, default: 'bottom', reflect: true },
37
+ gap: { type: Number, default: 4, reflect: true },
38
+ open: { type: Boolean, default: false, reflect: true },
39
+ trigger: { type: String, default: 'click', reflect: true },
40
+ };
41
+
42
+ static template = () => null;
43
+
44
+ #anchorCleanup = null;
45
+ #bound = false;
46
+ #hoverTimer = null;
47
+ #content = null;
48
+ #rafId = null;
49
+
50
+ connected() {
51
+ const content = this.querySelector('[slot="content"]');
52
+ if (content) {
53
+ if (!content.hasAttribute('popover')) content.setAttribute('popover', 'manual');
54
+ // Sync state when the browser toggles the popover (e.g. light-dismiss, ESC on auto, programmatic).
55
+ content.addEventListener('toggle', this.#onToggle);
56
+ this.#content = content;
57
+ }
58
+
59
+ if (!this.#bound) {
60
+ this.#bound = true;
61
+
62
+ if (this.trigger === 'click') {
63
+ this.addEventListener('click', this.#onClick);
64
+ }
65
+
66
+ if (this.trigger === 'hover') {
67
+ this.addEventListener('pointerenter', this.#onEnter);
68
+ this.addEventListener('pointerleave', this.#onLeave);
69
+ // Also let the pointer cross into the content without closing.
70
+ if (content) {
71
+ content.addEventListener('pointerenter', this.#onEnter);
72
+ content.addEventListener('pointerleave', this.#onLeave);
73
+ }
74
+ }
75
+ }
76
+ }
77
+
78
+ render() {
79
+ if (this.open) this.#show();
80
+ else this.#hide();
81
+ }
82
+
83
+ // ── Public API ──
84
+ show() { this.open = true; }
85
+ hide() { this.open = false; }
86
+ toggle() { this.open = !this.open; }
87
+
88
+ // ── Internal ──
89
+
90
+ #show() {
91
+ const trigger = this.querySelector('[slot="trigger"]');
92
+ const content = this.#content ?? this.querySelector('[slot="content"]');
93
+ if (!trigger || !content) return;
94
+
95
+ if (!content.matches(':popover-open')) {
96
+ // try/catch covers test envs (happy-dom) without the API. Known iOS
97
+ // Safari quirks at the supported floor (light-dismiss broken on
98
+ // 17.0–18.2, virtual-keyboard-on-input persists past 18.3) are
99
+ // documented in docs/BROWSER-COMPAT.md §3a.
100
+ try { content.showPopover(); } catch { /* popover API unavailable — anchor positioning still runs */ }
101
+ }
102
+
103
+ this.#anchorCleanup?.();
104
+ this.#anchorCleanup = anchorPopover(trigger, content, {
105
+ placement: this.placement,
106
+ gap: this.gap,
107
+ });
108
+
109
+ if (this.trigger === 'click' || this.trigger === 'manual') {
110
+ // Defer to next frame so the opening click doesn't trigger outside-dismiss.
111
+ this.#rafId = requestAnimationFrame(() => {
112
+ this.#rafId = null;
113
+ document.addEventListener('pointerdown', this.#onOutside);
114
+ document.addEventListener('keydown', this.#onKey);
115
+ });
116
+ }
117
+ }
118
+
119
+ #hide() {
120
+ this.#anchorCleanup?.();
121
+ this.#anchorCleanup = null;
122
+
123
+ const content = this.#content ?? this.querySelector('[slot="content"]');
124
+ if (content?.matches(':popover-open')) {
125
+ try { content.hidePopover(); } catch { /* popover API unavailable */ }
126
+ }
127
+
128
+ if (this.#rafId != null) {
129
+ cancelAnimationFrame(this.#rafId);
130
+ this.#rafId = null;
131
+ }
132
+ document.removeEventListener('pointerdown', this.#onOutside);
133
+ document.removeEventListener('keydown', this.#onKey);
134
+ }
135
+
136
+ // ── Events ──
137
+
138
+ #onClick = (e) => {
139
+ const trigger = this.querySelector('[slot="trigger"]');
140
+ if (trigger && (e.target === trigger || trigger.contains(e.target))) {
141
+ this.open = !this.open;
142
+ }
143
+ };
144
+
145
+ #onOutside = (e) => {
146
+ if (!this.open) return;
147
+ const content = this.#content;
148
+ // Click inside host or inside the (top-layer) content: keep open.
149
+ if (this.contains(e.target) || content?.contains(e.target)) return;
150
+ this.open = false;
151
+ };
152
+
153
+ #onKey = (e) => {
154
+ if (e.key === 'Escape' && this.open) {
155
+ e.stopPropagation();
156
+ this.open = false;
157
+ }
158
+ };
159
+
160
+ #onEnter = () => {
161
+ clearTimeout(this.#hoverTimer);
162
+ this.open = true;
163
+ };
164
+
165
+ #onLeave = () => {
166
+ clearTimeout(this.#hoverTimer);
167
+ this.#hoverTimer = setTimeout(() => { this.open = false; }, HOVER_CLOSE_DELAY);
168
+ };
169
+
170
+ #onToggle = (e) => {
171
+ // Reflect browser-driven state changes (e.g. popover-auto light-dismiss).
172
+ const nowOpen = e.newState === 'open';
173
+ if (nowOpen !== this.open) this.open = nowOpen;
174
+ };
175
+
176
+ disconnected() {
177
+ clearTimeout(this.#hoverTimer);
178
+ this.#hide();
179
+ if (this.trigger === 'click') {
180
+ this.removeEventListener('click', this.#onClick);
181
+ }
182
+ if (this.trigger === 'hover') {
183
+ this.removeEventListener('pointerenter', this.#onEnter);
184
+ this.removeEventListener('pointerleave', this.#onLeave);
185
+ if (this.#content) {
186
+ this.#content.removeEventListener('pointerenter', this.#onEnter);
187
+ this.#content.removeEventListener('pointerleave', this.#onLeave);
188
+ }
189
+ }
190
+ this.#content?.removeEventListener('toggle', this.#onToggle);
191
+ this.#content = null;
192
+ this.#bound = false;
193
+ }
194
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * `<popover-ui>` — Popover using Popover API + CSS Anchor Positioning. Triggers: click, hover, manual.
3
+ *
4
+ * @see https://ui-kit.exe.xyz/site/components/popover
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 components`, then `npm run codegen:dts` to regenerate;
9
+ * or hand-author this file fully if rich event types are needed.
10
+ */
11
+
12
+ import { UIElement } from '../../core/element.js';
13
+
14
+ export class UIPopover extends UIElement {
15
+ /** Pixel offset between the anchor and the popover */
16
+ gap: number;
17
+ /** Controls visibility via showPopover()/hidePopover() */
18
+ open: boolean;
19
+ /** Popover placement */
20
+ placement: 'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end';
21
+ /** Trigger mode */
22
+ trigger: 'click' | 'hover' | 'manual';
23
+ }
@@ -1,184 +1,17 @@
1
1
  /**
2
- * <popover-ui trigger="click" placement="bottom-start">
3
- * <button-ui slot="trigger" text="Open"></button-ui>
4
- * <div slot="content">Popover content here</div>
5
- * </popover-ui>
2
+ * `<popover-ui>` auto-registers the tag on import.
6
3
  *
7
- * Built on the web platform:
8
- * Popover API — content has popover="manual"; showPopover() promotes it
9
- * to the top layer (no z-index, no overflow clipping, ESC bubbling handled).
10
- * • CSS Anchor Positioning — used natively when supported, JS fallback otherwise
11
- * (see @core/anchor.js).
4
+ * For non-side-effect class import (test isolation, tag override), use
5
+ * the `class` subpath:
12
6
  *
13
- * Triggers: click | hover | manual. ESC closes click/manual popovers.
7
+ * import { UIPopover } from '@adia-ai/web-components/components/popover/class';
8
+ *
9
+ * @see ../../USAGE.md#registration--auto-vs-explicit
14
10
  */
15
11
 
16
- import { UIElement } from '../../core/element.js';
17
- import { anchorPopover } from '../../core/anchor.js';
18
-
19
- const HOVER_CLOSE_DELAY = 120;
20
-
21
- class UIPopover extends UIElement {
22
- static properties = {
23
- placement: { type: String, default: 'bottom', reflect: true },
24
- gap: { type: Number, default: 4, reflect: true },
25
- open: { type: Boolean, default: false, reflect: true },
26
- trigger: { type: String, default: 'click', reflect: true },
27
- };
28
-
29
- static template = () => null;
30
-
31
- #anchorCleanup = null;
32
- #bound = false;
33
- #hoverTimer = null;
34
- #content = null;
35
- #rafId = null;
36
-
37
- connected() {
38
- const content = this.querySelector('[slot="content"]');
39
- if (content) {
40
- if (!content.hasAttribute('popover')) content.setAttribute('popover', 'manual');
41
- // Sync state when the browser toggles the popover (e.g. light-dismiss, ESC on auto, programmatic).
42
- content.addEventListener('toggle', this.#onToggle);
43
- this.#content = content;
44
- }
45
-
46
- if (!this.#bound) {
47
- this.#bound = true;
48
-
49
- if (this.trigger === 'click') {
50
- this.addEventListener('click', this.#onClick);
51
- }
52
-
53
- if (this.trigger === 'hover') {
54
- this.addEventListener('pointerenter', this.#onEnter);
55
- this.addEventListener('pointerleave', this.#onLeave);
56
- // Also let the pointer cross into the content without closing.
57
- if (content) {
58
- content.addEventListener('pointerenter', this.#onEnter);
59
- content.addEventListener('pointerleave', this.#onLeave);
60
- }
61
- }
62
- }
63
- }
64
-
65
- render() {
66
- if (this.open) this.#show();
67
- else this.#hide();
68
- }
69
-
70
- // ── Public API ──
71
- show() { this.open = true; }
72
- hide() { this.open = false; }
73
- toggle() { this.open = !this.open; }
74
-
75
- // ── Internal ──
76
-
77
- #show() {
78
- const trigger = this.querySelector('[slot="trigger"]');
79
- const content = this.#content ?? this.querySelector('[slot="content"]');
80
- if (!trigger || !content) return;
81
-
82
- if (!content.matches(':popover-open')) {
83
- // try/catch covers test envs (happy-dom) without the API. Known iOS
84
- // Safari quirks at the supported floor (light-dismiss broken on
85
- // 17.0–18.2, virtual-keyboard-on-input persists past 18.3) are
86
- // documented in docs/BROWSER-COMPAT.md §3a.
87
- try { content.showPopover(); } catch { /* popover API unavailable — anchor positioning still runs */ }
88
- }
89
-
90
- this.#anchorCleanup?.();
91
- this.#anchorCleanup = anchorPopover(trigger, content, {
92
- placement: this.placement,
93
- gap: this.gap,
94
- });
95
-
96
- if (this.trigger === 'click' || this.trigger === 'manual') {
97
- // Defer to next frame so the opening click doesn't trigger outside-dismiss.
98
- this.#rafId = requestAnimationFrame(() => {
99
- this.#rafId = null;
100
- document.addEventListener('pointerdown', this.#onOutside);
101
- document.addEventListener('keydown', this.#onKey);
102
- });
103
- }
104
- }
105
-
106
- #hide() {
107
- this.#anchorCleanup?.();
108
- this.#anchorCleanup = null;
109
-
110
- const content = this.#content ?? this.querySelector('[slot="content"]');
111
- if (content?.matches(':popover-open')) {
112
- try { content.hidePopover(); } catch { /* popover API unavailable */ }
113
- }
114
-
115
- if (this.#rafId != null) {
116
- cancelAnimationFrame(this.#rafId);
117
- this.#rafId = null;
118
- }
119
- document.removeEventListener('pointerdown', this.#onOutside);
120
- document.removeEventListener('keydown', this.#onKey);
121
- }
122
-
123
- // ── Events ──
124
-
125
- #onClick = (e) => {
126
- const trigger = this.querySelector('[slot="trigger"]');
127
- if (trigger && (e.target === trigger || trigger.contains(e.target))) {
128
- this.open = !this.open;
129
- }
130
- };
131
-
132
- #onOutside = (e) => {
133
- if (!this.open) return;
134
- const content = this.#content;
135
- // Click inside host or inside the (top-layer) content: keep open.
136
- if (this.contains(e.target) || content?.contains(e.target)) return;
137
- this.open = false;
138
- };
139
-
140
- #onKey = (e) => {
141
- if (e.key === 'Escape' && this.open) {
142
- e.stopPropagation();
143
- this.open = false;
144
- }
145
- };
146
-
147
- #onEnter = () => {
148
- clearTimeout(this.#hoverTimer);
149
- this.open = true;
150
- };
151
-
152
- #onLeave = () => {
153
- clearTimeout(this.#hoverTimer);
154
- this.#hoverTimer = setTimeout(() => { this.open = false; }, HOVER_CLOSE_DELAY);
155
- };
156
-
157
- #onToggle = (e) => {
158
- // Reflect browser-driven state changes (e.g. popover-auto light-dismiss).
159
- const nowOpen = e.newState === 'open';
160
- if (nowOpen !== this.open) this.open = nowOpen;
161
- };
12
+ import { defineIfFree } from '../../core/register.js';
13
+ import { UIPopover } from './class.js';
162
14
 
163
- disconnected() {
164
- clearTimeout(this.#hoverTimer);
165
- this.#hide();
166
- if (this.trigger === 'click') {
167
- this.removeEventListener('click', this.#onClick);
168
- }
169
- if (this.trigger === 'hover') {
170
- this.removeEventListener('pointerenter', this.#onEnter);
171
- this.removeEventListener('pointerleave', this.#onLeave);
172
- if (this.#content) {
173
- this.#content.removeEventListener('pointerenter', this.#onEnter);
174
- this.#content.removeEventListener('pointerleave', this.#onLeave);
175
- }
176
- }
177
- this.#content?.removeEventListener('toggle', this.#onToggle);
178
- this.#content = null;
179
- this.#bound = false;
180
- }
181
- }
15
+ defineIfFree('popover-ui', UIPopover);
182
16
 
183
- customElements.define('popover-ui', UIPopover);
184
17
  export { UIPopover };
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Non-side-effect class export for `<progress-ui>`.
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/progress`
9
+ * (which imports this file + calls `defineIfFree()`).
10
+ *
11
+ * @see ../../USAGE.md#registration--auto-vs-explicit
12
+ */
13
+
14
+ /**
15
+ * <progress-ui value="60"></progress-ui>
16
+ * <progress-ui variant="spinner"></progress-ui>
17
+ * <progress-ui></progress-ui> <!-- indeterminate bar -->
18
+ *
19
+ * Progress indicator. Bar (default) or spinner variant.
20
+ * value null (absent) = indeterminate, 0-100 = determinate.
21
+ * (Legacy `value="-1"` is still treated as indeterminate for back-compat.)
22
+ */
23
+
24
+ import { UIElement } from '../../core/element.js';
25
+
26
+ export class UIProgress extends UIElement {
27
+ static properties = {
28
+ value: { type: Number, default: null, reflect: true },
29
+ variant: { type: String, default: 'bar', reflect: true },
30
+ };
31
+
32
+ static template = () => null;
33
+
34
+ #track = null;
35
+ #fill = null;
36
+
37
+ connected() {
38
+ this.setAttribute('role', 'progressbar');
39
+ this.setAttribute('aria-valuemin', '0');
40
+ this.setAttribute('aria-valuemax', '100');
41
+
42
+ if (this.variant === 'bar') {
43
+ this.#track = document.createElement('div');
44
+ this.#track.setAttribute('slot', 'track');
45
+ this.#fill = document.createElement('div');
46
+ this.#fill.setAttribute('slot', 'fill');
47
+ this.#track.appendChild(this.#fill);
48
+ this.appendChild(this.#track);
49
+ }
50
+ }
51
+
52
+ render() {
53
+ const indeterminate = this.value == null || this.value < 0;
54
+ const clamped = Math.max(0, Math.min(100, this.value));
55
+
56
+ this.setAttribute('aria-busy', String(indeterminate));
57
+
58
+ if (indeterminate) {
59
+ this.removeAttribute('aria-valuenow');
60
+ } else {
61
+ this.setAttribute('aria-valuenow', String(clamped));
62
+ }
63
+
64
+ if (this.#fill) {
65
+ this.#fill.style.width = indeterminate ? '100%' : `${clamped}%`;
66
+ }
67
+ }
68
+
69
+ disconnected() {
70
+ this.#track?.remove();
71
+ this.#track = null;
72
+ this.#fill = null;
73
+ }
74
+ }
@@ -158,6 +158,9 @@
158
158
  "progress",
159
159
  "tracker"
160
160
  ],
161
+ "tags": [
162
+ "LoadingIndicator"
163
+ ],
161
164
  "timeline": [
162
165
  "social",
163
166
  "post",
@@ -0,0 +1,19 @@
1
+ /**
2
+ * `<progress-ui>` — Progress indicator. Bar (default) or spinner. Value < 0 = indeterminate.
3
+ *
4
+ * @see https://ui-kit.exe.xyz/site/components/progress
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 components`, then `npm run codegen:dts` to regenerate;
9
+ * or hand-author this file fully if rich event types are needed.
10
+ */
11
+
12
+ import { UIElement } from '../../core/element.js';
13
+
14
+ export class UIProgress extends UIElement {
15
+ /** Current progress. 0..max (or 0..1 when max omitted). null = indeterminate (legacy -1 accepted for back-compat). */
16
+ value: number;
17
+ /** Display variant. Structural values (bar, spinner) set the render mode; semantic values (primary/success/warning/danger/info) set the fill color. Prefer the `color` global attribute for color; variant-as-color accepted for back-compat with older exemplars. */
18
+ variant: 'bar' | 'spinner' | 'primary' | 'success' | 'warning' | 'danger' | 'info';
19
+ }