@antadesign/anta 0.3.34 → 0.3.35

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 (184) hide show
  1. package/LICENSE.md +14 -1
  2. package/README.md +9 -0
  3. package/dist/anta_helpers.d.ts +46 -30
  4. package/dist/anta_helpers.js +66 -25
  5. package/dist/bundle.css +1 -1
  6. package/dist/bundle.js +2 -1333
  7. package/dist/components/Banner.d.ts +25 -40
  8. package/dist/components/Banner.js +15 -17
  9. package/dist/components/Button.js +1 -0
  10. package/dist/components/ButtonCopy.js +3 -2
  11. package/dist/components/Calendar.js +13 -13
  12. package/dist/components/Card.d.ts +9 -17
  13. package/dist/components/Card.js +50 -46
  14. package/dist/components/Dialog.d.ts +1 -0
  15. package/dist/components/Dialog.js +16 -10
  16. package/dist/components/Expander.d.ts +6 -21
  17. package/dist/components/Expander.js +24 -23
  18. package/dist/components/Icon.d.ts +8 -14
  19. package/dist/components/Input.d.ts +77 -96
  20. package/dist/components/Input.js +23 -27
  21. package/dist/components/InputAutocomplete.d.ts +29 -10
  22. package/dist/components/InputAutocomplete.js +25 -8
  23. package/dist/components/InputDate.js +2 -2
  24. package/dist/components/InputTime.d.ts +10 -4
  25. package/dist/components/InputTime.js +20 -16
  26. package/dist/components/Loader.d.ts +2 -2
  27. package/dist/components/Menu.d.ts +5 -4
  28. package/dist/components/Menu.js +13 -8
  29. package/dist/components/MenuItem.js +1 -14
  30. package/dist/components/MenuItemCopy.js +2 -2
  31. package/dist/components/Panel.d.ts +3 -1
  32. package/dist/components/Panel.js +17 -11
  33. package/dist/components/Progress.d.ts +21 -23
  34. package/dist/components/Progress.js +13 -9
  35. package/dist/components/RadioGroup.js +6 -8
  36. package/dist/components/{select-parts.css → Select.css} +1 -1
  37. package/dist/components/Select.d.ts +53 -35
  38. package/dist/components/Select.js +53 -97
  39. package/dist/components/SelectFaceted.d.ts +7 -3
  40. package/dist/components/SelectFaceted.js +21 -9
  41. package/dist/components/Slider.d.ts +28 -11
  42. package/dist/components/Slider.js +20 -20
  43. package/dist/components/Steps.css +1 -1
  44. package/dist/components/Steps.js +1 -11
  45. package/dist/components/Tabs.d.ts +17 -20
  46. package/dist/components/Tabs.js +5 -8
  47. package/dist/components/Text.d.ts +55 -36
  48. package/dist/components/Text.js +35 -22
  49. package/dist/components/Title.d.ts +16 -26
  50. package/dist/components/Title.js +2 -1
  51. package/dist/components/Toaster.js +9 -2
  52. package/dist/components/Tooltip.d.ts +10 -15
  53. package/dist/components/copy-props.d.ts +14 -3
  54. package/dist/components/copy-props.js +14 -3
  55. package/dist/components/select-tree.d.ts +24 -0
  56. package/dist/components/select-tree.js +35 -0
  57. package/dist/element-base.d.ts +10 -0
  58. package/dist/element-base.js +15 -0
  59. package/dist/elements/a-banner.css +1 -1
  60. package/dist/elements/a-banner.d.ts +4 -1
  61. package/dist/elements/a-banner.js +22 -112
  62. package/dist/elements/a-button.d.ts +2 -1
  63. package/dist/elements/a-button.js +18 -1
  64. package/dist/elements/a-calendar.d.ts +14 -13
  65. package/dist/elements/a-calendar.js +29 -24
  66. package/dist/elements/a-card.css +1 -1
  67. package/dist/elements/a-card.d.ts +0 -9
  68. package/dist/elements/a-card.js +0 -184
  69. package/dist/elements/a-checkbox.css +1 -1
  70. package/dist/elements/a-copy.css +1 -1
  71. package/dist/elements/a-copy.d.ts +1 -5
  72. package/dist/elements/a-copy.js +129 -108
  73. package/dist/elements/a-dialog.css +1 -1
  74. package/dist/elements/a-dialog.d.ts +1 -1
  75. package/dist/elements/a-dialog.js +66 -194
  76. package/dist/elements/a-expander.css +1 -1
  77. package/dist/elements/a-expander.d.ts +4 -30
  78. package/dist/elements/a-expander.js +85 -344
  79. package/dist/elements/a-icon.d.ts +5 -23
  80. package/dist/elements/a-icon.js +1 -2
  81. package/dist/elements/a-input-time.css +1 -1
  82. package/dist/elements/a-input-time.d.ts +2 -1
  83. package/dist/elements/a-input-time.js +101 -168
  84. package/dist/elements/a-input.css +1 -1
  85. package/dist/elements/a-input.d.ts +10 -8
  86. package/dist/elements/a-input.js +155 -230
  87. package/dist/elements/a-loader.d.ts +5 -8
  88. package/dist/elements/a-loader.js +1 -2
  89. package/dist/elements/a-menu-item.css +1 -1
  90. package/dist/elements/a-menu-item.d.ts +5 -3
  91. package/dist/elements/a-menu-item.js +5 -1
  92. package/dist/elements/a-menu.css +1 -1
  93. package/dist/elements/a-menu.d.ts +5 -7
  94. package/dist/elements/a-menu.js +383 -299
  95. package/dist/elements/a-panel.css +1 -1
  96. package/dist/elements/a-panel.js +19 -37
  97. package/dist/elements/a-progress.css +1 -1
  98. package/dist/elements/a-progress.d.ts +0 -22
  99. package/dist/elements/a-progress.js +0 -100
  100. package/dist/elements/a-radio-group.d.ts +1 -1
  101. package/dist/elements/a-radio-group.js +6 -4
  102. package/dist/elements/a-select-faceted.d.ts +1 -1
  103. package/dist/elements/a-select-faceted.js +1 -1
  104. package/dist/elements/a-select.d.ts +1 -1
  105. package/dist/elements/a-select.js +1 -1
  106. package/dist/elements/a-slider.css +1 -1
  107. package/dist/elements/a-slider.d.ts +11 -3
  108. package/dist/elements/a-slider.js +244 -242
  109. package/dist/elements/a-switch.css +1 -1
  110. package/dist/elements/a-tab.css +1 -1
  111. package/dist/elements/a-tabs.css +1 -1
  112. package/dist/elements/a-tabs.d.ts +1 -1
  113. package/dist/elements/a-tabs.js +6 -4
  114. package/dist/elements/a-tag.css +1 -1
  115. package/dist/elements/a-text.css +1 -1
  116. package/dist/elements/a-text.d.ts +6 -43
  117. package/dist/elements/a-text.js +110 -193
  118. package/dist/elements/a-title.css +1 -1
  119. package/dist/elements/a-toast.css +1 -1
  120. package/dist/elements/a-toast.d.ts +10 -45
  121. package/dist/elements/a-toast.js +80 -66
  122. package/dist/elements/a-toaster.css +1 -1
  123. package/dist/elements/a-toaster.js +9 -44
  124. package/dist/elements/a-tooltip.css +1 -1
  125. package/dist/elements/a-tooltip.d.ts +1 -1
  126. package/dist/elements/a-tooltip.js +142 -136
  127. package/dist/elements/copy-behavior.d.ts +1 -1
  128. package/dist/elements/copy-behavior.js +21 -21
  129. package/dist/elements/index.d.ts +3 -3
  130. package/dist/elements/index.js +3 -7
  131. package/dist/elements/input-focus-modality.d.ts +15 -0
  132. package/dist/elements/input-focus-modality.js +44 -0
  133. package/dist/elements/input-trailing-actions.d.ts +5 -0
  134. package/dist/elements/input-trailing-actions.js +38 -0
  135. package/dist/elements/shadow-aria.d.ts +2 -0
  136. package/dist/elements/shadow-aria.js +2 -1
  137. package/dist/elements/value-input.d.ts +3 -0
  138. package/dist/elements/value-input.js +12 -0
  139. package/dist/general_types.d.ts +103 -96
  140. package/dist/index.d.ts +1 -1
  141. package/dist/input-events.d.ts +4 -0
  142. package/dist/input-events.js +15 -0
  143. package/dist/jsx-runtime.d.ts +70 -23
  144. package/dist/jsx-runtime.js +26 -19
  145. package/dist/native-event-props.d.ts +2 -0
  146. package/dist/native-event-props.js +10 -0
  147. package/dist/reset.css +1 -1
  148. package/dist/theme-antithesis.css +10 -1
  149. package/dist/theme-antune.css +1 -1
  150. package/docs/accessibility.md +17 -3
  151. package/docs/changelog.md +348 -2
  152. package/docs/comparison.md +2 -2
  153. package/docs/components/avatar.md +5 -0
  154. package/docs/components/banner.md +117 -187
  155. package/docs/components/button.md +22 -0
  156. package/docs/components/card.md +74 -28
  157. package/docs/components/checkbox.md +9 -10
  158. package/docs/components/dialog.md +83 -32
  159. package/docs/components/expander.md +198 -435
  160. package/docs/components/icon.md +11 -17
  161. package/docs/components/input-autocomplete.md +152 -52
  162. package/docs/components/input-date.md +175 -148
  163. package/docs/components/input-time.md +81 -38
  164. package/docs/components/input.md +343 -349
  165. package/docs/components/loader.md +2 -1
  166. package/docs/components/menu.md +35 -6
  167. package/docs/components/panel.md +18 -0
  168. package/docs/components/progress.md +83 -49
  169. package/docs/components/radio.md +39 -43
  170. package/docs/components/select-faceted.md +54 -7
  171. package/docs/components/select.md +390 -386
  172. package/docs/components/slider.md +136 -19
  173. package/docs/components/steps.md +2 -1
  174. package/docs/components/switch.md +8 -9
  175. package/docs/components/tabs.md +110 -104
  176. package/docs/components/text.md +110 -86
  177. package/docs/components/title.md +47 -33
  178. package/docs/components/toaster.md +242 -84
  179. package/docs/components/tooltip.md +204 -113
  180. package/docs/install-config.md +183 -26
  181. package/docs/packages/plot.md +170 -148
  182. package/docs/theming.md +7 -0
  183. package/package.json +41 -3
  184. package/theme-antithesis-license.md +66 -0
@@ -10,7 +10,6 @@ const GRACE_MS = 300;
10
10
  const CLOSE_DELAY = 120;
11
11
  const PROX_NEAR = 10;
12
12
  const PROX_FAR = 100;
13
- const PROX_FADE_MS = 60;
14
13
  const ENTER_TOUCH_DELAY = 500;
15
14
  const TRUNCATING_PARTS = "a-tab-label, a-button-label, a-step-hint";
16
15
  function reportsTruncation(el) {
@@ -19,43 +18,49 @@ function reportsTruncation(el) {
19
18
  const AUTOMATIC_TEXT_TOOLTIP = "data-anta-text-tooltip";
20
19
  const LEAVE_TOUCH_DELAY = 1500;
21
20
  const TOUCH_SLOP = 10;
22
- let currentOpen = null;
23
- let graceTimer;
24
- let graceFollows = false;
25
- function graceActive() {
26
- return graceTimer !== void 0;
21
+ const COORDINATION = /* @__PURE__ */ Symbol.for("anta.tooltip-coordination");
22
+ function coordination(doc) {
23
+ const owner = doc;
24
+ return owner[COORDINATION] ??= {
25
+ currentOpen: null,
26
+ graceFollows: false,
27
+ anchors: /* @__PURE__ */ new WeakMap(),
28
+ anchorCount: 0
29
+ };
27
30
  }
28
31
  function isHot(next) {
29
32
  if (!next.hasAttribute("follow")) return false;
30
- if (currentOpen) return currentOpen.hasAttribute("follow");
31
- return graceActive() && graceFollows;
33
+ const state = coordination(next.ownerDocument);
34
+ if (state.currentOpen) return state.currentOpen.hasAttribute("follow");
35
+ return state.graceTimer !== void 0 && state.graceFollows;
32
36
  }
33
- function clearGrace() {
34
- if (graceTimer !== void 0) {
35
- clearTimeout(graceTimer);
36
- graceTimer = void 0;
37
- }
38
- graceFollows = false;
37
+ function clearGrace(state) {
38
+ if (state.graceTimer !== void 0) clearTimeout(state.graceTimer);
39
+ state.graceTimer = void 0;
40
+ state.graceFollows = false;
39
41
  }
40
42
  function claimOpen(el) {
41
- if (currentOpen && currentOpen !== el) {
42
- if (currentOpen.isConnected) currentOpen.hide();
43
- else currentOpen.cleanup();
44
- }
45
- currentOpen = el;
46
- clearGrace();
43
+ const state = coordination(el.ownerDocument);
44
+ const previous = state.currentOpen;
45
+ if (previous && previous !== el) {
46
+ if (previous.isConnected) previous.hide();
47
+ else previous.cleanup();
48
+ }
49
+ state.currentOpen = el;
50
+ clearGrace(state);
47
51
  }
48
- function releaseOpen(el) {
49
- if (currentOpen !== el) return;
50
- currentOpen = null;
51
- clearGrace();
52
- graceFollows = el.hasAttribute("follow");
53
- graceTimer = setTimeout(() => {
54
- graceTimer = void 0;
55
- graceFollows = false;
52
+ function releaseOpen(el, doc, grace = true) {
53
+ const state = coordination(doc);
54
+ if (state.currentOpen !== el) return;
55
+ state.currentOpen = null;
56
+ clearGrace(state);
57
+ if (!grace) return;
58
+ state.graceFollows = el.hasAttribute("follow");
59
+ state.graceTimer = setTimeout(() => {
60
+ state.graceTimer = void 0;
61
+ state.graceFollows = false;
56
62
  }, GRACE_MS);
57
63
  }
58
- const anchorToTooltips = /* @__PURE__ */ new WeakMap();
59
64
  function preferredTooltip(registry) {
60
65
  let automatic;
61
66
  let explicit;
@@ -65,30 +70,39 @@ function preferredTooltip(registry) {
65
70
  }
66
71
  return explicit ?? automatic;
67
72
  }
68
- function syncAnchorListeners(anchor, registry) {
73
+ function syncAnchorListeners(anchor, registry, doc) {
69
74
  const preferred = preferredTooltip(registry);
70
75
  for (const tooltip of registry.tooltips) {
71
- if (tooltip !== preferred) tooltip.teardownListeners();
76
+ if (tooltip !== preferred) tooltip.cleanup();
72
77
  }
73
- if (!preferred || !registry.intersecting) {
74
- preferred?.teardownListeners();
78
+ const view = doc.defaultView;
79
+ if (registry.frame !== void 0) view?.cancelAnimationFrame(registry.frame);
80
+ registry.frame = void 0;
81
+ if (!preferred || !registry.intersecting || !view) {
82
+ preferred?.cleanup();
75
83
  return;
76
84
  }
77
- requestAnimationFrame(() => {
78
- const current = anchorToTooltips.get(anchor);
85
+ registry.frame = view.requestAnimationFrame(() => {
86
+ registry.frame = void 0;
87
+ const current = coordination(doc).anchors.get(anchor);
79
88
  if (current !== registry || !current.intersecting || preferredTooltip(current) !== preferred) return;
80
89
  preferred.setupListeners();
81
90
  });
82
91
  }
83
- function handleIntersection(entries) {
84
- for (const entry of entries) {
85
- const registry = anchorToTooltips.get(entry.target);
86
- if (!registry) continue;
87
- registry.intersecting = entry.isIntersecting;
88
- syncAnchorListeners(entry.target, registry);
92
+ function observeAnchor(anchor, doc, state) {
93
+ const Observer = doc.defaultView?.IntersectionObserver;
94
+ if (!state.observer && Observer) {
95
+ state.observer = new Observer((entries) => {
96
+ for (const entry of entries) {
97
+ const registry = state.anchors.get(entry.target);
98
+ if (!registry) continue;
99
+ registry.intersecting = entry.isIntersecting;
100
+ syncAnchorListeners(entry.target, registry, doc);
101
+ }
102
+ }, { root: null, rootMargin: "0px", threshold: 0 });
89
103
  }
104
+ state.observer?.observe(anchor);
90
105
  }
91
- const lazyObserver = typeof IntersectionObserver !== "undefined" ? new IntersectionObserver(handleIntersection, { root: null, rootMargin: "0px", threshold: 0 }) : null;
92
106
  class ATooltipElement extends HTMLElementBase {
93
107
  // Observe `delay` so changing it at runtime — e.g. the docs playground
94
108
  // patches the attribute on the live element — rebuilds the show debounce
@@ -103,6 +117,10 @@ class ATooltipElement extends HTMLElementBase {
103
117
  * container's enter/exit/cross-fade opacity. */
104
118
  bubble;
105
119
  anchor = null;
120
+ #connectedDocument;
121
+ #globalDocument;
122
+ #positionView;
123
+ #internals;
106
124
  listening = false;
107
125
  shown = false;
108
126
  /** True while the current open was triggered by a touch long-press. Such a
@@ -122,77 +140,13 @@ class ATooltipElement extends HTMLElementBase {
122
140
  constructor() {
123
141
  super();
124
142
  const shadow = this.attachShadow({ mode: "open" });
125
- const style = document.createElement("style");
126
- style.textContent = `
127
- :host { display: contents; }
128
-
129
- .container {
130
- --_dur: ${FADE_MS}ms;
131
- position: fixed;
132
- left: 0;
133
- top: 0;
134
- margin: 0;
135
- padding: 0;
136
- border: 0;
137
- background: transparent;
138
- color: inherit;
139
- overflow: visible;
140
- box-sizing: border-box;
141
- width: fit-content;
142
- pointer-events: none;
143
- opacity: 0;
144
- transition:
145
- opacity var(--_dur) ease,
146
- overlay var(--_dur) ease allow-discrete,
147
- display var(--_dur) ease allow-discrete;
148
- }
149
-
150
- .container:popover-open { opacity: 1; }
151
-
152
- @starting-style {
153
- .container:popover-open { opacity: 0; }
154
- }
155
-
156
- .bubble {
157
- display: block;
158
- box-sizing: border-box;
159
- width: fit-content;
160
- max-width: var(--tooltip-max-width, min(calc(100vw - 20px), 80ch));
161
- max-height: calc(100vh - 20px);
162
- overflow: clip;
163
- text-align: left;
164
- background: var(--tooltip-bg, Canvas);
165
- color: var(--text-2, CanvasText);
166
- box-shadow: var(--tooltip-shadow, 0 1px 8px rgba(0, 0, 0, 0.2));
167
- -webkit-backdrop-filter: var(--tooltip-backdrop-filter, blur(8px));
168
- backdrop-filter: var(--tooltip-backdrop-filter, blur(8px));
169
- padding: var(--tooltip-padding, 4px 8px);
170
- border: var(--tooltip-border, none);
171
- border-radius: var(--tooltip-radius, 3px);
172
- outline: none;
173
- font-family: var(--sans-serif, system-ui, sans-serif);
174
- font-size: 14px;
175
- font-weight: 400;
176
- font-style: normal;
177
- font-stretch: normal;
178
- line-height: 1.5;
179
- letter-spacing: var(--_tooltip-letter-spacing, 0.025ch);
180
- word-spacing: normal;
181
- text-transform: none;
182
- white-space: break-spaces;
183
- word-break: break-word;
184
- overflow-wrap: break-word;
185
- opacity: 1;
186
- transition: opacity ${PROX_FADE_MS}ms linear;
187
- }
188
-
189
- :host([interactive]) .container { pointer-events: auto; }
190
- `;
191
- this.container = document.createElement("div");
143
+ this.#internals = this.attachInternals();
144
+ this.container = this.doc.createElement("div");
192
145
  this.container.className = "container";
146
+ this.container.setAttribute("part", "container");
193
147
  this.container.setAttribute("popover", "manual");
194
148
  this.container.setAttribute("role", "tooltip");
195
- this.bubble = document.createElement("slot");
149
+ this.bubble = this.doc.createElement("slot");
196
150
  this.bubble.className = "bubble";
197
151
  this.bubble.setAttribute("part", "bubble");
198
152
  this.container.append(this.bubble);
@@ -202,35 +156,53 @@ class ATooltipElement extends HTMLElementBase {
202
156
  this.container.addEventListener("mouseleave", () => {
203
157
  if (this.#isInteractive && this.shown) this.scheduleHide();
204
158
  });
205
- shadow.append(style, this.container);
159
+ this.container.addEventListener("focusin", () => {
160
+ if (this.#isInteractive) this.cancelHide();
161
+ });
162
+ this.container.addEventListener("focusout", () => {
163
+ if (this.#isInteractive && this.shown) this.scheduleHide();
164
+ });
165
+ shadow.append(this.container);
206
166
  }
207
167
  connectedCallback() {
208
168
  const parent = this.parentElement;
209
169
  if (!parent) return;
210
170
  this.anchor = parent;
211
- let registry = anchorToTooltips.get(parent);
171
+ const doc = this.#connectedDocument = this.doc;
172
+ const state = coordination(doc);
173
+ let registry = state.anchors.get(parent);
212
174
  if (!registry) {
213
- registry = { tooltips: /* @__PURE__ */ new Set(), intersecting: false };
214
- anchorToTooltips.set(parent, registry);
215
- lazyObserver?.observe(parent);
175
+ registry = { tooltips: /* @__PURE__ */ new Set(), intersecting: !doc.defaultView?.IntersectionObserver };
176
+ state.anchors.set(parent, registry);
177
+ state.anchorCount++;
178
+ observeAnchor(parent, doc, state);
216
179
  }
217
180
  registry.tooltips.add(this);
218
- syncAnchorListeners(parent, registry);
181
+ syncAnchorListeners(parent, registry, doc);
219
182
  }
220
183
  disconnectedCallback() {
221
184
  this.cleanup();
222
- if (this.anchor) {
185
+ const doc = this.#connectedDocument;
186
+ if (this.anchor && doc) {
223
187
  const anchor = this.anchor;
224
- const registry = anchorToTooltips.get(anchor);
188
+ const state = coordination(doc);
189
+ const registry = state.anchors.get(anchor);
225
190
  registry?.tooltips.delete(this);
226
191
  if (registry && registry.tooltips.size === 0) {
227
- anchorToTooltips.delete(anchor);
228
- lazyObserver?.unobserve(this.anchor);
192
+ if (registry.frame !== void 0) doc.defaultView?.cancelAnimationFrame(registry.frame);
193
+ state.anchors.delete(anchor);
194
+ state.observer?.unobserve(anchor);
195
+ if (--state.anchorCount === 0) {
196
+ state.observer?.disconnect();
197
+ state.observer = void 0;
198
+ clearGrace(state);
199
+ }
229
200
  } else if (registry) {
230
- syncAnchorListeners(anchor, registry);
201
+ syncAnchorListeners(anchor, registry, doc);
231
202
  }
232
- this.anchor = null;
233
203
  }
204
+ this.anchor = null;
205
+ this.#connectedDocument = void 0;
234
206
  }
235
207
  attributeChangedCallback(name) {
236
208
  if (name === "delay" && this.listening) this.makeDebouncedShow();
@@ -357,10 +329,11 @@ class ATooltipElement extends HTMLElementBase {
357
329
  observeContent() {
358
330
  if (typeof MutationObserver === "undefined") return;
359
331
  if (!this.contentObserver) {
360
- this.contentObserver = new MutationObserver(() => {
332
+ this.contentObserver = new this.view.MutationObserver(() => {
361
333
  if (!this.shown) return;
362
334
  this.syncAutomaticTextContent();
363
335
  if (this.isEmpty()) this.hide();
336
+ else this.position(this.lastMouse);
364
337
  });
365
338
  }
366
339
  this.contentObserver.observe(this.#isAutomaticTextTooltip ? this.anchor ?? this : this, {
@@ -378,7 +351,8 @@ class ATooltipElement extends HTMLElementBase {
378
351
  schedulePosition(compute) {
379
352
  this.pendingPosition = compute;
380
353
  if (this.positionFrame != null) return;
381
- this.positionFrame = this.view.requestAnimationFrame(() => {
354
+ this.#positionView = this.view;
355
+ this.positionFrame = this.#positionView.requestAnimationFrame(() => {
382
356
  this.positionFrame = void 0;
383
357
  const run = this.pendingPosition;
384
358
  this.pendingPosition = void 0;
@@ -454,25 +428,28 @@ class ATooltipElement extends HTMLElementBase {
454
428
  // --- show / hide ---
455
429
  show = (e) => {
456
430
  if (!this.anchor) return;
457
- if (isMenuOpen() && !isInsideOpenMenu(this.anchor)) return;
431
+ if (isMenuOpen(this.doc) && !isInsideOpenMenu(this.anchor)) return;
458
432
  if (this.hasExplicitTextTooltip()) return;
459
433
  if (this.isEmpty()) return;
460
434
  if (this.#truncatedOnly && !this.isTargetTruncated()) return;
461
435
  this.syncAutomaticTextContent();
462
436
  this.cancelHide();
463
- if (currentOpen && currentOpen !== this && this.anchor.contains(currentOpen.anchor)) {
437
+ const currentOpen = coordination(this.doc).currentOpen;
438
+ if (currentOpen && currentOpen !== this && currentOpen.anchor && this.anchor.contains(currentOpen.anchor)) {
464
439
  return;
465
440
  }
466
441
  claimOpen(this);
467
442
  if (!this.shown) {
468
443
  this.shown = true;
469
444
  this.fading = false;
445
+ this.#internals.states.delete("proximity-hidden");
470
446
  this.bubble.style.opacity = "1";
471
447
  if (this.fadeTimer !== void 0) {
472
448
  clearTimeout(this.fadeTimer);
473
449
  this.fadeTimer = void 0;
474
450
  }
475
451
  this.container.showPopover();
452
+ this.#globalDocument = this.doc;
476
453
  this.view.addEventListener("scroll", this.hide, { capture: true, passive: true });
477
454
  this.doc.addEventListener("keydown", this.onKeyDown, true);
478
455
  if (!this.docMoveBound) {
@@ -482,6 +459,13 @@ class ATooltipElement extends HTMLElementBase {
482
459
  this.observeContent();
483
460
  }
484
461
  this.position(e);
462
+ const initialPosition = this.pendingPosition;
463
+ if (initialPosition) {
464
+ if (this.positionFrame !== void 0) this.#positionView?.cancelAnimationFrame(this.positionFrame);
465
+ this.positionFrame = void 0;
466
+ this.pendingPosition = void 0;
467
+ initialPosition();
468
+ }
485
469
  };
486
470
  hide = () => {
487
471
  this.cancelHide();
@@ -493,7 +477,7 @@ class ATooltipElement extends HTMLElementBase {
493
477
  this.fading = true;
494
478
  if (this.fadeTimer !== void 0) clearTimeout(this.fadeTimer);
495
479
  this.fadeTimer = setTimeout(() => this.detachGlobals(), FADE_MS);
496
- releaseOpen(this);
480
+ releaseOpen(this, this.#connectedDocument ?? this.doc);
497
481
  };
498
482
  /** Remove every document / window listener this element binds and stop the
499
483
  * fade timer. Used by hide() (after the exit fade) and by cleanup()
@@ -504,12 +488,14 @@ class ATooltipElement extends HTMLElementBase {
504
488
  this.fadeTimer = void 0;
505
489
  }
506
490
  this.fading = false;
507
- this.view.removeEventListener("scroll", this.hide, { capture: true });
508
- this.doc.removeEventListener("keydown", this.onKeyDown, true);
491
+ const doc = this.#globalDocument;
492
+ doc?.defaultView?.removeEventListener("scroll", this.hide, { capture: true });
493
+ doc?.removeEventListener("keydown", this.onKeyDown, true);
509
494
  if (this.docMoveBound) {
510
- this.doc.removeEventListener("mousemove", this.onDocMove);
495
+ doc?.removeEventListener("mousemove", this.onDocMove);
511
496
  this.docMoveBound = false;
512
497
  }
498
+ this.#globalDocument = void 0;
513
499
  }
514
500
  /** Full, immediate teardown: close the popover now (no fade), detach every
515
501
  * listener, clear all timers, release the coordinator slot, reset state.
@@ -519,6 +505,11 @@ class ATooltipElement extends HTMLElementBase {
519
505
  * calls it. */
520
506
  cleanup() {
521
507
  this.cancelHide();
508
+ if (this.positionFrame !== void 0) this.#positionView?.cancelAnimationFrame(this.positionFrame);
509
+ this.positionFrame = void 0;
510
+ this.#positionView = void 0;
511
+ this.pendingPosition = void 0;
512
+ this.lastMouse = void 0;
522
513
  this.contentObserver?.disconnect();
523
514
  if (this.shown) {
524
515
  this.shown = false;
@@ -527,7 +518,9 @@ class ATooltipElement extends HTMLElementBase {
527
518
  }
528
519
  this.detachGlobals();
529
520
  this.teardownListeners();
530
- releaseOpen(this);
521
+ releaseOpen(this, this.#connectedDocument ?? this.doc, false);
522
+ this.touchOpen = false;
523
+ this.#internals.states.delete("proximity-hidden");
531
524
  this.bubble.style.opacity = "";
532
525
  }
533
526
  /** While shown, track the cursor even after it has left the anchor (during
@@ -542,13 +535,13 @@ class ATooltipElement extends HTMLElementBase {
542
535
  this.lastMouse = e;
543
536
  const o = this.proximityOpacity(e);
544
537
  if (o === 0) {
545
- this.bubble.style.transition = "none";
538
+ this.#internals.states.add("proximity-hidden");
546
539
  this.bubble.style.opacity = "0";
547
540
  if (this.shown) this.hide();
548
541
  return;
549
542
  }
550
543
  this.positionToMouse(e);
551
- this.bubble.style.transition = "";
544
+ this.#internals.states.delete("proximity-hidden");
552
545
  this.bubble.style.opacity = String(o);
553
546
  };
554
547
  /** Hide after CLOSE_DELAY unless something cancels it first (re-enter, or
@@ -558,6 +551,7 @@ class ATooltipElement extends HTMLElementBase {
558
551
  this.cancelHide();
559
552
  this.closeTimer = setTimeout(() => {
560
553
  this.closeTimer = void 0;
554
+ if (this.#isInteractive && this.matches(":focus-within")) return;
561
555
  this.hide();
562
556
  }, delay);
563
557
  };
@@ -608,6 +602,7 @@ class ATooltipElement extends HTMLElementBase {
608
602
  anchor.removeEventListener("pointerleave", onLeave);
609
603
  anchor.removeEventListener("blur", onLeave);
610
604
  view.removeEventListener("pagehide", onLeave);
605
+ view.removeEventListener("scroll", onLeave, true);
611
606
  doc.removeEventListener("visibilitychange", onLeave);
612
607
  this.scheduleHide();
613
608
  };
@@ -617,13 +612,16 @@ class ATooltipElement extends HTMLElementBase {
617
612
  anchor.addEventListener("pointermove", onPointerMove);
618
613
  anchor.addEventListener("pointerleave", onLeave);
619
614
  view.addEventListener("pagehide", onLeave);
615
+ view.addEventListener("scroll", onLeave, { capture: true, passive: true });
620
616
  doc.addEventListener("visibilitychange", onLeave);
621
617
  this.trigger(e);
622
618
  };
623
619
  const onFocus = () => {
624
- if (!anchor.matches(":focus-visible")) return;
620
+ const focused = anchor.shadowRoot?.activeElement ?? this.doc.activeElement;
621
+ if (!focused?.matches(":focus-visible")) return;
625
622
  anchor.addEventListener("blur", onLeave);
626
623
  view.addEventListener("pagehide", onLeave);
624
+ view.addEventListener("scroll", onLeave, { capture: true, passive: true });
627
625
  doc.addEventListener("visibilitychange", onLeave);
628
626
  this.trigger();
629
627
  };
@@ -652,6 +650,11 @@ class ATooltipElement extends HTMLElementBase {
652
650
  anchor.removeEventListener("pointerup", onPressEnd);
653
651
  anchor.removeEventListener("pointercancel", onPressEnd);
654
652
  anchor.removeEventListener("contextmenu", preventContext);
653
+ view.removeEventListener("scroll", cancelPress, true);
654
+ };
655
+ const cancelPress = () => {
656
+ clearPressTimer();
657
+ detachPress();
655
658
  };
656
659
  const onPointerDown = (e) => {
657
660
  if (e.pointerType === "mouse") return;
@@ -661,14 +664,16 @@ class ATooltipElement extends HTMLElementBase {
661
664
  anchor.addEventListener("pointerup", onPressEnd);
662
665
  anchor.addEventListener("pointercancel", onPressEnd);
663
666
  anchor.addEventListener("contextmenu", preventContext);
667
+ view.addEventListener("scroll", cancelPress, { capture: true, passive: true });
664
668
  pressTimer = setTimeout(() => {
665
669
  pressTimer = void 0;
666
670
  this.touchOpen = true;
667
671
  this.show();
672
+ if (!this.shown) this.touchOpen = false;
668
673
  }, ENTER_TOUCH_DELAY);
669
674
  };
670
675
  anchor.addEventListener("pointerenter", onEnter);
671
- anchor.addEventListener("focus", onFocus);
676
+ anchor.addEventListener("focusin", onFocus);
672
677
  anchor.addEventListener("pointerdown", onPointerDown);
673
678
  this.teardown = () => {
674
679
  this.debouncedShow?.cancel();
@@ -677,10 +682,11 @@ class ATooltipElement extends HTMLElementBase {
677
682
  anchor.removeEventListener("pointermove", onPointerMove);
678
683
  anchor.removeEventListener("pointerenter", onEnter);
679
684
  anchor.removeEventListener("pointerleave", onLeave);
680
- anchor.removeEventListener("focus", onFocus);
685
+ anchor.removeEventListener("focusin", onFocus);
681
686
  anchor.removeEventListener("blur", onLeave);
682
687
  anchor.removeEventListener("pointerdown", onPointerDown);
683
688
  view.removeEventListener("pagehide", onLeave);
689
+ view.removeEventListener("scroll", onLeave, true);
684
690
  doc.removeEventListener("visibilitychange", onLeave);
685
691
  this.listening = false;
686
692
  };
@@ -49,4 +49,4 @@ export declare function emitCopyRequest(el: HTMLElement): void;
49
49
  * `true` if the element is a copy control (so the caller knows the copy path
50
50
  * ran); `false` for a plain, non-copy element.
51
51
  */
52
- export declare function runCopy(el: HTMLElement): boolean;
52
+ export declare function runCopy(el: HTMLElement, complete: (ok: boolean) => void): boolean;
@@ -1,27 +1,27 @@
1
- async function writeText(text) {
1
+ async function writeText(text, view) {
2
2
  try {
3
- await navigator.clipboard.writeText(text);
3
+ await view.navigator.clipboard.writeText(text);
4
4
  return true;
5
5
  } catch {
6
6
  return false;
7
7
  }
8
8
  }
9
- async function writeNode(node) {
9
+ async function writeNode(node, view) {
10
10
  const clone = node.cloneNode(true);
11
11
  clone.querySelectorAll("[data-copy-node-button]").forEach((n) => n.remove());
12
12
  const html = clone.outerHTML;
13
13
  const text = clone.textContent ?? "";
14
14
  try {
15
- if (typeof ClipboardItem !== "undefined" && navigator.clipboard?.write) {
16
- await navigator.clipboard.write([
17
- new ClipboardItem({
18
- "text/html": new Blob([html], { type: "text/html" }),
19
- "text/plain": new Blob([text], { type: "text/plain" })
15
+ if (typeof view.ClipboardItem !== "undefined" && view.navigator.clipboard?.write) {
16
+ await view.navigator.clipboard.write([
17
+ new view.ClipboardItem({
18
+ "text/html": new view.Blob([html], { type: "text/html" }),
19
+ "text/plain": new view.Blob([text], { type: "text/plain" })
20
20
  })
21
21
  ]);
22
22
  return true;
23
23
  }
24
- await navigator.clipboard.writeText(text);
24
+ await view.navigator.clipboard.writeText(text);
25
25
  return true;
26
26
  } catch {
27
27
  return false;
@@ -32,18 +32,16 @@ function resolveNodeTarget(el) {
32
32
  if (sel == null) return null;
33
33
  return el.closest(sel === "" ? "[data-copy-source]" : sel);
34
34
  }
35
- function run(el, work) {
36
- void work.then((ok) => {
37
- el.dispatchEvent(new CustomEvent("copydone", { bubbles: false, detail: { ok } }));
38
- });
35
+ function run(work, complete) {
36
+ void work.then(complete);
39
37
  }
40
- function currentUrl() {
41
- return typeof location !== "undefined" ? location.href : "";
38
+ function currentUrl(el) {
39
+ return el.ownerDocument.defaultView?.location.href ?? "";
42
40
  }
43
41
  function resolveText(el) {
44
- if (el.hasAttribute("copy-url")) return currentUrl();
42
+ if (el.hasAttribute("copy-url")) return currentUrl(el);
45
43
  const base = el.getAttribute("copy") ?? "";
46
- if (el.hasAttribute("copy-with-url")) return `// URL: ${currentUrl()}
44
+ if (el.hasAttribute("copy-with-url")) return `// URL: ${currentUrl(el)}
47
45
  ${base}`;
48
46
  return base;
49
47
  }
@@ -52,16 +50,18 @@ function isTextCopy(el) {
52
50
  }
53
51
  function emitCopyRequest(el) {
54
52
  if (!el.hasAttribute("copy")) return;
55
- el.dispatchEvent(new CustomEvent("copyrequest", { bubbles: false }));
53
+ const view = el.ownerDocument.defaultView ?? globalThis;
54
+ el.dispatchEvent(new view.CustomEvent("copyrequest", { bubbles: false }));
56
55
  }
57
- function runCopy(el) {
56
+ function runCopy(el, complete) {
57
+ const view = el.ownerDocument.defaultView ?? globalThis;
58
58
  if (el.hasAttribute("copy-node")) {
59
59
  const target = resolveNodeTarget(el);
60
- run(el, target ? writeNode(target) : Promise.resolve(false));
60
+ run(target ? writeNode(target, view) : Promise.resolve(false), complete);
61
61
  return true;
62
62
  }
63
63
  if (!isTextCopy(el)) return false;
64
- run(el, writeText(resolveText(el)));
64
+ run(writeText(resolveText(el), view), complete);
65
65
  return true;
66
66
  }
67
67
  export {
@@ -16,7 +16,7 @@
16
16
  * `customElements` (SSR), but there's no reason to load it server-side.
17
17
  */
18
18
  export { AAvatarElement, register_a_avatar } from './a-avatar';
19
- export { AProgressElement, register_a_progress } from './a-progress';
19
+ import './a-progress.css';
20
20
  export { ALoaderElement, register_a_loader } from './a-loader';
21
21
  export { ATextElement, register_a_text } from './a-text';
22
22
  export { ABoxElement, register_a_box } from './a-box';
@@ -43,7 +43,7 @@ export { ATabElement, register_a_tab } from './a-tab';
43
43
  export { ATabsElement, register_a_tabs } from './a-tabs';
44
44
  export { ATabPanelElement, register_a_tabpanel } from './a-tabpanel';
45
45
  export { ADialogElement, register_a_dialog } from './a-dialog';
46
- export { ACardElement, register_a_card } from './a-card';
46
+ import './a-card.css';
47
47
  export { ABannerElement, register_a_banner } from './a-banner';
48
48
  export { AToasterElement, register_a_toaster } from './a-toaster';
49
49
  export { AToastElement, register_a_toast } from './a-toast';
@@ -51,5 +51,5 @@ import './a-title.css';
51
51
  import './a-tag.css';
52
52
  import '../components/Breadcrumbs.css';
53
53
  import '../components/InputDate.css';
54
- import '../components/select-parts.css';
54
+ import '../components/Select.css';
55
55
  import '../components/Steps.css';
@@ -1,5 +1,5 @@
1
1
  import { AAvatarElement, register_a_avatar } from "./a-avatar";
2
- import { AProgressElement, register_a_progress } from "./a-progress";
2
+ import "./a-progress.css";
3
3
  import { ALoaderElement, register_a_loader } from "./a-loader";
4
4
  import { ATextElement, register_a_text } from "./a-text";
5
5
  import { ABoxElement, register_a_box } from "./a-box";
@@ -26,7 +26,7 @@ import { ATabElement, register_a_tab } from "./a-tab";
26
26
  import { ATabsElement, register_a_tabs } from "./a-tabs";
27
27
  import { ATabPanelElement, register_a_tabpanel } from "./a-tabpanel";
28
28
  import { ADialogElement, register_a_dialog } from "./a-dialog";
29
- import { ACardElement, register_a_card } from "./a-card";
29
+ import "./a-card.css";
30
30
  import { ABannerElement, register_a_banner } from "./a-banner";
31
31
  import { AToasterElement, register_a_toaster } from "./a-toaster";
32
32
  import { AToastElement, register_a_toast } from "./a-toast";
@@ -34,7 +34,7 @@ import "./a-title.css";
34
34
  import "./a-tag.css";
35
35
  import "../components/Breadcrumbs.css";
36
36
  import "../components/InputDate.css";
37
- import "../components/select-parts.css";
37
+ import "../components/Select.css";
38
38
  import "../components/Steps.css";
39
39
  export {
40
40
  AAvatarElement,
@@ -43,7 +43,6 @@ export {
43
43
  AButtonElement,
44
44
  ACalendarElement,
45
45
  ACaptureElement,
46
- ACardElement,
47
46
  ACheckboxElement,
48
47
  ACopyElement,
49
48
  ADialogElement,
@@ -57,7 +56,6 @@ export {
57
56
  AMenuItemElement,
58
57
  AMenuSeparatorElement,
59
58
  APanelElement,
60
- AProgressElement,
61
59
  ARadioElement,
62
60
  ARadioGroupElement,
63
61
  ASliderElement,
@@ -75,7 +73,6 @@ export {
75
73
  register_a_button,
76
74
  register_a_calendar,
77
75
  register_a_capture,
78
- register_a_card,
79
76
  register_a_checkbox,
80
77
  register_a_copy,
81
78
  register_a_dialog,
@@ -89,7 +86,6 @@ export {
89
86
  register_a_menu_item,
90
87
  register_a_menu_separator,
91
88
  register_a_panel,
92
- register_a_progress,
93
89
  register_a_radio,
94
90
  register_a_radio_group,
95
91
  register_a_slider,