@spectrum-web-components/overlay 0.34.1-rc.0 → 0.35.1-rc.15

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 (91) hide show
  1. package/README.md +17 -8
  2. package/custom-elements.json +492 -305
  3. package/package.json +14 -13
  4. package/src/AbstractOverlay.d.ts +54 -0
  5. package/src/AbstractOverlay.dev.js +192 -0
  6. package/src/AbstractOverlay.dev.js.map +7 -0
  7. package/src/AbstractOverlay.js +2 -0
  8. package/src/AbstractOverlay.js.map +7 -0
  9. package/src/Overlay.d.ts +135 -19
  10. package/src/Overlay.dev.js +714 -69
  11. package/src/Overlay.dev.js.map +3 -3
  12. package/src/Overlay.js +30 -1
  13. package/src/Overlay.js.map +3 -3
  14. package/src/OverlayDialog.d.ts +3 -7
  15. package/src/OverlayDialog.dev.js +6 -34
  16. package/src/OverlayDialog.dev.js.map +2 -2
  17. package/src/OverlayDialog.js +1 -1
  18. package/src/OverlayDialog.js.map +3 -3
  19. package/src/OverlayNoPopover.d.ts +3 -7
  20. package/src/OverlayNoPopover.dev.js +7 -46
  21. package/src/OverlayNoPopover.dev.js.map +2 -2
  22. package/src/OverlayNoPopover.js +1 -1
  23. package/src/OverlayNoPopover.js.map +3 -3
  24. package/src/OverlayPopover.d.ts +3 -7
  25. package/src/OverlayPopover.dev.js +18 -49
  26. package/src/OverlayPopover.dev.js.map +2 -2
  27. package/src/OverlayPopover.js +1 -1
  28. package/src/OverlayPopover.js.map +3 -3
  29. package/src/OverlayStack.d.ts +9 -2
  30. package/src/OverlayStack.dev.js +16 -3
  31. package/src/OverlayStack.dev.js.map +2 -2
  32. package/src/OverlayStack.js +1 -1
  33. package/src/OverlayStack.js.map +3 -3
  34. package/src/OverlayTrigger.d.ts +6 -14
  35. package/src/OverlayTrigger.dev.js +0 -47
  36. package/src/OverlayTrigger.dev.js.map +2 -2
  37. package/src/OverlayTrigger.js +2 -2
  38. package/src/OverlayTrigger.js.map +3 -3
  39. package/src/PlacementController.d.ts +3 -1
  40. package/src/PlacementController.dev.js +10 -2
  41. package/src/PlacementController.dev.js.map +2 -2
  42. package/src/PlacementController.js +1 -1
  43. package/src/PlacementController.js.map +2 -2
  44. package/src/VirtualTrigger.dev.js +3 -0
  45. package/src/VirtualTrigger.dev.js.map +2 -2
  46. package/src/VirtualTrigger.js +1 -1
  47. package/src/VirtualTrigger.js.map +3 -3
  48. package/src/fullSizePlugin.dev.js.map +2 -2
  49. package/src/fullSizePlugin.js.map +2 -2
  50. package/src/loader.d.ts +1 -2
  51. package/src/overlay-timer.dev.js.map +2 -2
  52. package/src/overlay-timer.js.map +2 -2
  53. package/src/overlay-types.d.ts +18 -27
  54. package/src/overlay-types.dev.js.map +2 -2
  55. package/src/overlay-types.js.map +2 -2
  56. package/src/overlay.css.dev.js +9 -0
  57. package/src/overlay.css.dev.js.map +7 -0
  58. package/src/overlay.css.js +6 -0
  59. package/src/overlay.css.js.map +7 -0
  60. package/src/topLayerOverTransforms.d.ts +2 -23
  61. package/src/topLayerOverTransforms.dev.js +7 -91
  62. package/src/topLayerOverTransforms.dev.js.map +2 -2
  63. package/src/topLayerOverTransforms.js +1 -1
  64. package/src/topLayerOverTransforms.js.map +3 -3
  65. package/stories/overlay-element.stories.js +2 -6
  66. package/stories/overlay-element.stories.js.map +2 -2
  67. package/stories/overlay.stories.js +46 -15
  68. package/stories/overlay.stories.js.map +2 -2
  69. package/test/index.js +1 -1
  70. package/test/index.js.map +1 -1
  71. package/test/overlay-element.test.js +1 -2
  72. package/test/overlay-element.test.js.map +2 -2
  73. package/test/overlay-trigger-hover-click.test.js +1 -1
  74. package/test/overlay-trigger-hover-click.test.js.map +2 -2
  75. package/test/overlay-trigger-hover.test.js +1 -1
  76. package/test/overlay-trigger-hover.test.js.map +2 -2
  77. package/test/overlay-v1.test.js +2 -11
  78. package/test/overlay-v1.test.js.map +2 -2
  79. package/test/{overlay-v2.test.js → overlay.test.js} +42 -8
  80. package/test/overlay.test.js.map +7 -0
  81. package/src/OverlayBase.d.ts +0 -124
  82. package/src/OverlayBase.dev.js +0 -744
  83. package/src/OverlayBase.dev.js.map +0 -7
  84. package/src/OverlayBase.js +0 -31
  85. package/src/OverlayBase.js.map +0 -7
  86. package/src/overlay-base.css.dev.js +0 -9
  87. package/src/overlay-base.css.dev.js.map +0 -7
  88. package/src/overlay-base.css.js +0 -6
  89. package/src/overlay-base.css.js.map +0 -7
  90. package/test/overlay-v2.test.js.map +0 -7
  91. /package/src/{overlay-base.css.d.ts → overlay.css.d.ts} +0 -0
@@ -1,91 +1,736 @@
1
1
  "use strict";
2
- import { noop, OverlayBase } from "./OverlayBase.dev.js";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __decorateClass = (decorators, target, key, kind) => {
5
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
6
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
7
+ if (decorator = decorators[i])
8
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
9
+ if (kind && result)
10
+ __defProp(target, key, result);
11
+ return result;
12
+ };
13
+ import {
14
+ html
15
+ } from "@spectrum-web-components/base";
16
+ import {
17
+ property,
18
+ query,
19
+ queryAssignedElements,
20
+ state
21
+ } from "@spectrum-web-components/base/src/decorators.js";
22
+ import {
23
+ isAndroid,
24
+ isIOS
25
+ } from "@spectrum-web-components/shared/src/platform.js";
26
+ import {
27
+ ElementResolutionController,
28
+ elementResolverUpdatedSymbol
29
+ } from "@spectrum-web-components/reactive-controllers/src/ElementResolution.js";
30
+ import { conditionAttributeWithId } from "@spectrum-web-components/base/src/condition-attribute-with-id.js";
31
+ import {
32
+ ifDefined,
33
+ styleMap
34
+ } from "@spectrum-web-components/base/src/directives.js";
35
+ import { AbstractOverlay, nextFrame } from "./AbstractOverlay.dev.js";
3
36
  import { OverlayDialog } from "./OverlayDialog.dev.js";
4
37
  import { OverlayPopover } from "./OverlayPopover.dev.js";
5
38
  import { OverlayNoPopover } from "./OverlayNoPopover.dev.js";
6
- import { reparentChildren } from "@spectrum-web-components/shared";
39
+ import { overlayStack } from "./OverlayStack.dev.js";
40
+ import { noop } from "./AbstractOverlay.dev.js";
41
+ import { VirtualTrigger } from "./VirtualTrigger.dev.js";
42
+ import { PlacementController } from "./PlacementController.dev.js";
43
+ import styles from "./overlay.css.js";
44
+ const LONGPRESS_DURATION = 300;
45
+ export const LONGPRESS_INSTRUCTIONS = {
46
+ touch: "Double tap and long press for additional options",
47
+ keyboard: "Press Space or Alt+Down Arrow for additional options",
48
+ mouse: "Click and hold for additional options"
49
+ };
7
50
  const supportsPopover = "showPopover" in document.createElement("div");
8
- let OverlayFeatures = OverlayDialog(OverlayBase);
51
+ let OverlayFeatures = OverlayDialog(AbstractOverlay);
9
52
  if (supportsPopover) {
10
53
  OverlayFeatures = OverlayPopover(OverlayFeatures);
11
54
  } else {
12
55
  OverlayFeatures = OverlayNoPopover(OverlayFeatures);
13
56
  }
14
- export class Overlay extends OverlayFeatures {
15
- static update() {
16
- const overlayUpdateEvent = new CustomEvent("sp-update-overlays", {
17
- bubbles: true,
18
- composed: true,
19
- cancelable: true
20
- });
21
- document.dispatchEvent(overlayUpdateEvent);
22
- }
23
- static async open(targetOrContent, interactionOrOptions, content, options) {
24
- var _a, _b, _c;
25
- const v2 = arguments.length === 2;
26
- const overlayContent = content || targetOrContent;
27
- const overlay = new Overlay();
28
- overlay.dispose = () => {
29
- overlay.addEventListener("sp-closed", () => {
30
- if (!restored) {
31
- restoreContent();
32
- restored = true;
57
+ const _Overlay = class extends OverlayFeatures {
58
+ constructor() {
59
+ super(...arguments);
60
+ this.delayed = false;
61
+ this._disabled = false;
62
+ this.longpressed = false;
63
+ this.isVisible = false;
64
+ this.offset = 6;
65
+ this.placementController = new PlacementController(this);
66
+ this._open = false;
67
+ this.receivesFocus = "auto";
68
+ this.releaseAriaDescribedby = noop;
69
+ this.releaseLongpressDescribedby = noop;
70
+ this.triggerElement = null;
71
+ this.type = "hint";
72
+ this.wasOpen = false;
73
+ this.elementResolver = new ElementResolutionController(this);
74
+ this.elementIds = [];
75
+ this.handlePointerdown = (event) => {
76
+ if (!this.triggerElement)
77
+ return;
78
+ if (event.button !== 0)
79
+ return;
80
+ const triggerElement = this.triggerElement;
81
+ this.longpressed = false;
82
+ triggerElement.addEventListener("pointerup", this.handlePointerup);
83
+ triggerElement.addEventListener("pointercancel", this.handlePointerup);
84
+ this.longressTimeout = setTimeout(() => {
85
+ if (!triggerElement)
86
+ return;
87
+ triggerElement.dispatchEvent(
88
+ new CustomEvent("longpress", {
89
+ bubbles: true,
90
+ composed: true,
91
+ detail: {
92
+ source: "pointer"
93
+ }
94
+ })
95
+ );
96
+ }, LONGPRESS_DURATION);
97
+ };
98
+ this.handlePointerup = () => {
99
+ clearTimeout(this.longressTimeout);
100
+ if (!this.triggerElement)
101
+ return;
102
+ if (this.longpressed) {
103
+ this.open = true;
104
+ }
105
+ setTimeout(() => {
106
+ this.longpressed = false;
107
+ });
108
+ const triggerElement = this.triggerElement;
109
+ triggerElement.removeEventListener("pointerup", this.handlePointerup);
110
+ triggerElement.removeEventListener(
111
+ "pointercancel",
112
+ this.handlePointerup
113
+ );
114
+ };
115
+ /**
116
+ * @private
117
+ */
118
+ this.handleKeydown = (event) => {
119
+ const { code, altKey } = event;
120
+ if (code === "Space" || altKey && code === "ArrowDown") {
121
+ if (code === "ArrowDown") {
122
+ event.stopPropagation();
123
+ event.stopImmediatePropagation();
33
124
  }
34
- requestAnimationFrame(() => {
35
- overlay.remove();
125
+ }
126
+ };
127
+ this.handleKeyup = (event) => {
128
+ const { code, altKey } = event;
129
+ if (code === "Space" || altKey && code === "ArrowDown") {
130
+ event.stopPropagation();
131
+ this.dispatchEvent(
132
+ new CustomEvent("longpress", {
133
+ bubbles: true,
134
+ composed: true,
135
+ detail: {
136
+ source: "keyboard"
137
+ }
138
+ })
139
+ );
140
+ }
141
+ };
142
+ /**
143
+ * An overlay with a `click` interaction should not close on click `triggerElement`.
144
+ * When a click is initiated (`pointerdown`), apply `preventNextToggle` when the
145
+ * overlay is `open` to prevent from toggling the overlay when the click event
146
+ * propagates later in the interaction.
147
+ */
148
+ this.preventNextToggle = false;
149
+ this.handlePointerdownForClick = () => {
150
+ this.preventNextToggle = this.open;
151
+ };
152
+ this.handleClick = () => {
153
+ if (this.longpressed)
154
+ return;
155
+ if (!this.preventNextToggle) {
156
+ this.open = !this.open;
157
+ }
158
+ this.preventNextToggle = false;
159
+ };
160
+ this.focusedin = false;
161
+ this.handleFocusin = () => {
162
+ this.open = true;
163
+ this.focusedin = true;
164
+ };
165
+ this.handleFocusout = () => {
166
+ this.focusedin = false;
167
+ if (this.pointerentered)
168
+ return;
169
+ this.open = false;
170
+ };
171
+ this.pointerentered = false;
172
+ this.handlePointerenter = () => {
173
+ if (this.disabled)
174
+ return;
175
+ this.open = true;
176
+ this.pointerentered = true;
177
+ };
178
+ this.handlePointerleave = (event) => {
179
+ if (this === event.relatedTarget || this.contains(event.relatedTarget) || [...this.children].find((child) => {
180
+ if (child.localName !== "slot") {
181
+ return false;
182
+ }
183
+ return child.assignedElements({ flatten: true }).find((el) => {
184
+ return el === event.relatedTarget || el.contains(event.relatedTarget);
36
185
  });
37
- });
38
- overlay.open = false;
39
- overlay.dispose = noop;
186
+ })) {
187
+ return;
188
+ }
189
+ this.doPointerleave();
40
190
  };
41
- let restored = false;
42
- const restoreContent = reparentChildren([overlayContent], overlay, {
43
- position: "beforeend",
44
- prepareCallback: (el) => {
45
- const slot = el.slot;
46
- el.removeAttribute("slot");
47
- return () => {
48
- el.slot = slot;
49
- };
191
+ this.handleOverlayPointerleave = (event) => {
192
+ if (this.triggerElement === event.relatedTarget || this.hasNonVirtualTrigger && this.triggerElement.contains(
193
+ event.relatedTarget
194
+ )) {
195
+ return;
50
196
  }
197
+ this.doPointerleave();
198
+ };
199
+ this.handleLongpress = () => {
200
+ this.open = true;
201
+ this.longpressed = true;
202
+ };
203
+ this.willPreventClose = false;
204
+ }
205
+ get disabled() {
206
+ return this._disabled;
207
+ }
208
+ set disabled(disabled) {
209
+ this._disabled = disabled;
210
+ if (disabled) {
211
+ if (this.hasNonVirtualTrigger) {
212
+ this.unbindEvents();
213
+ }
214
+ this.wasOpen = this.open;
215
+ this.open = false;
216
+ } else {
217
+ this.bindEvents();
218
+ this.open = this.open || this.wasOpen;
219
+ this.wasOpen = false;
220
+ }
221
+ }
222
+ get hasNonVirtualTrigger() {
223
+ return !!this.triggerElement && !(this.triggerElement instanceof VirtualTrigger);
224
+ }
225
+ get open() {
226
+ return this._open;
227
+ }
228
+ set open(open) {
229
+ if (open && this.disabled)
230
+ return;
231
+ if (open === this.open)
232
+ return;
233
+ this._open = open;
234
+ if (this.open) {
235
+ _Overlay.openCount += 1;
236
+ this.isVisible = true;
237
+ }
238
+ this.requestUpdate("open", !this.open);
239
+ }
240
+ get usesDialog() {
241
+ return this.type === "modal" || this.type === "page";
242
+ }
243
+ get popoverValue() {
244
+ switch (this.type) {
245
+ case "modal":
246
+ case "page":
247
+ return void 0;
248
+ case "hint":
249
+ return "manual";
250
+ default:
251
+ return this.type;
252
+ }
253
+ }
254
+ get requiresPosition() {
255
+ if (this.type === "page" || !this.open)
256
+ return false;
257
+ if (!this.triggerElement || !this.placement && this.type !== "hint")
258
+ return false;
259
+ return true;
260
+ }
261
+ managePosition() {
262
+ if (!this.requiresPosition || !this.open)
263
+ return;
264
+ const offset = this.offset || 0;
265
+ const trigger = this.triggerElement;
266
+ const placement = this.placement || "right";
267
+ const tipPadding = this.tipPadding;
268
+ this.placementController.placeOverlay(this.dialogEl, {
269
+ offset,
270
+ placement,
271
+ tipPadding,
272
+ trigger,
273
+ type: this.type
51
274
  });
52
- if (v2) {
53
- const options2 = interactionOrOptions;
54
- overlay.append(overlayContent);
55
- overlay.receivesFocus = (_a = options2.receivesFocus) != null ? _a : "auto";
56
- overlay.triggerElement = options2.trigger || null;
57
- overlay.type = options2.type || "modal";
58
- overlay.offset = options2.offset || 6;
59
- overlay.placement = options2.placement;
60
- overlay.willPreventClose = !!options2.notImmediatelyClosable;
61
- requestAnimationFrame(() => {
62
- requestAnimationFrame(() => {
63
- overlay.open = true;
275
+ }
276
+ async managePopoverOpen() {
277
+ super.managePopoverOpen();
278
+ const targetOpenState = this.open;
279
+ if (this.open !== targetOpenState) {
280
+ return;
281
+ }
282
+ await this.manageDelay(targetOpenState);
283
+ if (this.open !== targetOpenState) {
284
+ return;
285
+ }
286
+ await this.ensureOnDOM(targetOpenState);
287
+ if (this.open !== targetOpenState) {
288
+ return;
289
+ }
290
+ const focusEl = await this.makeTransition(targetOpenState);
291
+ if (this.open !== targetOpenState) {
292
+ return;
293
+ }
294
+ await this.applyFocus(targetOpenState, focusEl);
295
+ }
296
+ async applyFocus(targetOpenState, focusEl) {
297
+ if (this.receivesFocus === "false" || this.type === "hint") {
298
+ return;
299
+ }
300
+ await nextFrame();
301
+ await nextFrame();
302
+ if (targetOpenState === this.open && !this.open) {
303
+ if (this.hasNonVirtualTrigger && this.contains(this.getRootNode().activeElement)) {
304
+ this.triggerElement.focus();
305
+ }
306
+ return;
307
+ }
308
+ focusEl == null ? void 0 : focusEl.focus();
309
+ }
310
+ async manageOpen(oldOpen) {
311
+ var _a;
312
+ if (!this.isConnected && this.open)
313
+ return;
314
+ if (!this.hasUpdated) {
315
+ await this.updateComplete;
316
+ }
317
+ if (this.open) {
318
+ overlayStack.add(this);
319
+ if (this.willPreventClose) {
320
+ document.addEventListener(
321
+ "pointerup",
322
+ () => {
323
+ this.dialogEl.classList.toggle(
324
+ "not-immediately-closable",
325
+ false
326
+ );
327
+ this.willPreventClose = false;
328
+ },
329
+ { once: true }
330
+ );
331
+ this.dialogEl.classList.toggle(
332
+ "not-immediately-closable",
333
+ true
334
+ );
335
+ }
336
+ } else {
337
+ if (oldOpen) {
338
+ this.dispose();
339
+ }
340
+ overlayStack.remove(this);
341
+ }
342
+ if (this.usesDialog) {
343
+ this.manageDialogOpen();
344
+ } else {
345
+ this.managePopoverOpen();
346
+ }
347
+ if (!this.open) {
348
+ const getAncestors = () => {
349
+ var _a2;
350
+ const ancestors = [];
351
+ let currentNode = document.activeElement;
352
+ while ((currentNode == null ? void 0 : currentNode.shadowRoot) && currentNode.shadowRoot.activeElement) {
353
+ currentNode = currentNode.shadowRoot.activeElement;
354
+ }
355
+ while (currentNode) {
356
+ const ancestor = currentNode.assignedSlot || currentNode.parentElement || ((_a2 = currentNode.getRootNode()) == null ? void 0 : _a2.host);
357
+ if (ancestor) {
358
+ ancestors.push(ancestor);
359
+ }
360
+ currentNode = ancestor;
361
+ }
362
+ return ancestors;
363
+ };
364
+ if (((_a = this.triggerElement) == null ? void 0 : _a.focus) && (this.contains(
365
+ this.getRootNode().activeElement
366
+ ) || getAncestors().includes(this))) {
367
+ this.triggerElement.focus();
368
+ }
369
+ }
370
+ }
371
+ unbindEvents() {
372
+ var _a;
373
+ (_a = this.abortController) == null ? void 0 : _a.abort();
374
+ }
375
+ bindEvents() {
376
+ if (!this.hasNonVirtualTrigger)
377
+ return;
378
+ this.abortController = new AbortController();
379
+ const nextTriggerElement = this.triggerElement;
380
+ switch (this.triggerInteraction) {
381
+ case "click":
382
+ this.bindClickEvents(nextTriggerElement);
383
+ return;
384
+ case "longpress":
385
+ this.bindLongpressEvents(nextTriggerElement);
386
+ return;
387
+ case "hover":
388
+ this.bindHoverEvents(nextTriggerElement);
389
+ return;
390
+ }
391
+ }
392
+ bindClickEvents(triggerElement) {
393
+ const options = { signal: this.abortController.signal };
394
+ triggerElement.addEventListener("click", this.handleClick, options);
395
+ triggerElement.addEventListener(
396
+ "pointerdown",
397
+ this.handlePointerdownForClick,
398
+ options
399
+ );
400
+ }
401
+ bindLongpressEvents(triggerElement) {
402
+ const options = { signal: this.abortController.signal };
403
+ triggerElement.addEventListener(
404
+ "pointerdown",
405
+ this.handlePointerdown,
406
+ options
407
+ );
408
+ triggerElement.addEventListener("keydown", this.handleKeydown, options);
409
+ triggerElement.addEventListener("keyup", this.handleKeyup, options);
410
+ triggerElement.addEventListener(
411
+ "longpress",
412
+ this.handleLongpress,
413
+ options
414
+ );
415
+ this.prepareLongpressDescription(triggerElement);
416
+ }
417
+ bindHoverEvents(triggerElement) {
418
+ const options = { signal: this.abortController.signal };
419
+ triggerElement.addEventListener("focusin", this.handleFocusin, options);
420
+ triggerElement.addEventListener(
421
+ "focusout",
422
+ this.handleFocusout,
423
+ options
424
+ );
425
+ triggerElement.addEventListener(
426
+ "pointerenter",
427
+ this.handlePointerenter,
428
+ options
429
+ );
430
+ triggerElement.addEventListener(
431
+ "pointerleave",
432
+ this.handlePointerleave,
433
+ options
434
+ );
435
+ this.addEventListener(
436
+ "pointerleave",
437
+ this.handleOverlayPointerleave,
438
+ options
439
+ );
440
+ if (this.receivesFocus === "true")
441
+ return;
442
+ this.prepareAriaDescribedby(triggerElement);
443
+ }
444
+ manageTriggerElement(triggerElement) {
445
+ if (triggerElement) {
446
+ this.unbindEvents();
447
+ this.releaseAriaDescribedby();
448
+ }
449
+ const missingOrVirtual = !this.triggerElement || this.triggerElement instanceof VirtualTrigger;
450
+ if (missingOrVirtual) {
451
+ return;
452
+ }
453
+ this.bindEvents();
454
+ }
455
+ prepareLongpressDescription(trigger) {
456
+ if (
457
+ // only "longpress" relationships are described this way
458
+ this.triggerInteraction !== "longpress" || // do not reapply until target it recycled
459
+ this.releaseLongpressDescribedby !== noop || // require "longpress content" to apply relationship
460
+ !this.elements.length
461
+ ) {
462
+ return;
463
+ }
464
+ const longpressDescription = document.createElement("div");
465
+ longpressDescription.id = `longpress-describedby-descriptor-${crypto.randomUUID().slice(0, 8)}`;
466
+ const messageType = isIOS() || isAndroid() ? "touch" : "keyboard";
467
+ longpressDescription.textContent = LONGPRESS_INSTRUCTIONS[messageType];
468
+ longpressDescription.slot = "longpress-describedby-descriptor";
469
+ trigger.insertAdjacentElement("afterend", longpressDescription);
470
+ const releaseLongpressDescribedby = conditionAttributeWithId(
471
+ trigger,
472
+ "aria-describedby",
473
+ [longpressDescription.id]
474
+ );
475
+ this.releaseLongpressDescribedby = () => {
476
+ releaseLongpressDescribedby();
477
+ longpressDescription.remove();
478
+ this.releaseLongpressDescribedby = noop;
479
+ };
480
+ }
481
+ prepareAriaDescribedby(trigger) {
482
+ if (
483
+ // only "hover" relationships establed described by content
484
+ this.triggerInteraction !== "hover" || // do not reapply until target is recycled
485
+ this.releaseAriaDescribedby !== noop || // require "hover content" to apply relationship
486
+ !this.elements.length
487
+ ) {
488
+ return;
489
+ }
490
+ const triggerRoot = trigger.getRootNode();
491
+ const contentRoot = this.elements[0].getRootNode();
492
+ const overlayRoot = this.getRootNode();
493
+ if (triggerRoot == overlayRoot) {
494
+ const releaseAriaDescribedby = conditionAttributeWithId(
495
+ trigger,
496
+ "aria-describedby",
497
+ [this.id]
498
+ );
499
+ this.releaseAriaDescribedby = () => {
500
+ releaseAriaDescribedby();
501
+ this.releaseAriaDescribedby = noop;
502
+ };
503
+ } else if (triggerRoot === contentRoot) {
504
+ this.elementIds = this.elements.map((el) => el.id);
505
+ const appliedIds = this.elements.map((el) => {
506
+ if (!el.id) {
507
+ el.id = `${this.tagName.toLowerCase()}-helper-${crypto.randomUUID().slice(0, 8)}`;
508
+ }
509
+ return el.id;
510
+ });
511
+ const releaseAriaDescribedby = conditionAttributeWithId(
512
+ trigger,
513
+ "aria-describedby",
514
+ appliedIds
515
+ );
516
+ this.releaseAriaDescribedby = () => {
517
+ releaseAriaDescribedby();
518
+ this.elements.map((el, index) => {
519
+ el.id = this.elementIds[index];
64
520
  });
521
+ this.releaseAriaDescribedby = noop;
522
+ };
523
+ }
524
+ }
525
+ doPointerleave() {
526
+ this.pointerentered = false;
527
+ const triggerElement = this.triggerElement;
528
+ if (this.focusedin && triggerElement.matches(":focus-visible"))
529
+ return;
530
+ this.open = false;
531
+ }
532
+ handleBeforetoggle(event) {
533
+ if (event.newState !== "open") {
534
+ this.handleBrowserClose();
535
+ }
536
+ }
537
+ handleBrowserClose() {
538
+ this.open = false;
539
+ }
540
+ handleSlotchange() {
541
+ if (this.triggerElement) {
542
+ this.prepareAriaDescribedby(this.triggerElement);
543
+ }
544
+ if (!this.elements.length) {
545
+ this.releaseLongpressDescribedby();
546
+ } else if (this.hasNonVirtualTrigger) {
547
+ this.prepareLongpressDescription(
548
+ this.triggerElement
549
+ );
550
+ }
551
+ }
552
+ shouldPreventClose() {
553
+ const shouldPreventClose = this.willPreventClose;
554
+ this.willPreventClose = false;
555
+ return shouldPreventClose;
556
+ }
557
+ willUpdate(changes) {
558
+ var _a;
559
+ if (!this.hasUpdated) {
560
+ this.addEventListener("focusout", (event) => {
561
+ if (this.type !== "auto") {
562
+ return;
563
+ }
564
+ if (!event.relatedTarget) {
565
+ return;
566
+ }
567
+ const relationEvent = new Event("overlay-relation-query", {
568
+ bubbles: true,
569
+ composed: true
570
+ });
571
+ event.relatedTarget.addEventListener(
572
+ relationEvent.type,
573
+ (event2) => {
574
+ if (!event2.composedPath().includes(this)) {
575
+ this.open = false;
576
+ }
577
+ }
578
+ );
579
+ event.relatedTarget.dispatchEvent(relationEvent);
65
580
  });
66
- return overlay;
67
- } else if (overlayContent && options) {
68
- const target = targetOrContent;
69
- const interaction = interactionOrOptions;
70
- overlay.receivesFocus = (_b = options.receivesFocus) != null ? _b : "auto";
71
- overlay.triggerElement = options.virtualTrigger || target;
72
- overlay.type = interaction === "modal" ? "modal" : interaction === "hover" ? "hint" : "auto";
73
- overlay.offset = (_c = options.offset) != null ? _c : 6;
74
- overlay.placement = options.placement;
75
- overlay.willPreventClose = !!options.notImmediatelyClosable;
76
- const parent = target.getRootNode();
77
- if (parent === document) {
78
- target.insertAdjacentElement("afterend", overlay);
581
+ }
582
+ if (!this.hasAttribute("id")) {
583
+ this.setAttribute(
584
+ "id",
585
+ `${this.tagName.toLowerCase()}-${crypto.randomUUID().slice(0, 8)}`
586
+ );
587
+ }
588
+ if (changes.has("open") && (typeof changes.get("open") !== "undefined" || this.open)) {
589
+ this.manageOpen(changes.get("open"));
590
+ }
591
+ if (changes.has("trigger")) {
592
+ const [id, interaction] = ((_a = this.trigger) == null ? void 0 : _a.split("@")) || [];
593
+ this.elementResolver.selector = id ? `#${id}` : "";
594
+ this.triggerInteraction = interaction;
595
+ }
596
+ const oldTrigger = this.triggerElement;
597
+ if (changes.has(elementResolverUpdatedSymbol)) {
598
+ this.triggerElement = this.elementResolver.element;
599
+ this.manageTriggerElement(oldTrigger);
600
+ }
601
+ if (changes.has("triggerElement")) {
602
+ this.manageTriggerElement(changes.get("triggerElement"));
603
+ }
604
+ }
605
+ updated(changes) {
606
+ super.updated(changes);
607
+ if (changes.has("placement")) {
608
+ if (this.placement) {
609
+ this.dialogEl.setAttribute("actual-placement", this.placement);
79
610
  } else {
80
- parent.append(overlay);
611
+ this.dialogEl.removeAttribute("actual-placement");
612
+ }
613
+ if (this.open && typeof changes.get("placement") !== "undefined") {
614
+ this.placementController.resetOverlayPosition();
81
615
  }
82
- await new Promise(
83
- (res) => requestAnimationFrame(() => requestAnimationFrame(() => res()))
84
- );
85
- overlay.open = true;
86
- return overlay.dispose;
87
616
  }
88
- return overlay;
89
617
  }
90
- }
618
+ renderContent() {
619
+ return html`
620
+ <div style=${styleMap(this.dialogStyleMap)} part="content">
621
+ <slot @slotchange=${this.handleSlotchange}></slot>
622
+ </div>
623
+ `;
624
+ }
625
+ get dialogStyleMap() {
626
+ return {
627
+ "--swc-overlay-open-count": _Overlay.openCount.toString()
628
+ };
629
+ }
630
+ renderDialog() {
631
+ return html`
632
+ <dialog
633
+ class="dialog"
634
+ part="dialog"
635
+ @close=${this.handleBrowserClose}
636
+ @cancel=${this.handleBrowserClose}
637
+ @beforetoggle=${this.handleBeforetoggle}
638
+ ?is-visible=${this.isVisible}
639
+ >
640
+ ${this.renderContent()}
641
+ </dialog>
642
+ `;
643
+ }
644
+ renderPopover() {
645
+ const hasPopoverAttribute = "popover" in this;
646
+ const popoverValue = hasPopoverAttribute ? this.popoverValue : void 0;
647
+ return html`
648
+ <div
649
+ class="dialog"
650
+ part="dialog"
651
+ popover=${ifDefined(popoverValue)}
652
+ @beforetoggle=${this.handleBeforetoggle}
653
+ @close=${this.handleBrowserClose}
654
+ ?is-visible=${this.isVisible}
655
+ >
656
+ ${this.renderContent()}
657
+ </div>
658
+ `;
659
+ }
660
+ render() {
661
+ const isDialog = this.type === "modal" || this.type === "page";
662
+ return html`
663
+ ${isDialog ? this.renderDialog() : this.renderPopover()}
664
+ <slot name="longpress-describedby-descriptor"></slot>
665
+ `;
666
+ }
667
+ connectedCallback() {
668
+ super.connectedCallback();
669
+ this.addEventListener("close", () => {
670
+ this.open = false;
671
+ });
672
+ if (this.hasNonVirtualTrigger) {
673
+ this.bindEvents();
674
+ }
675
+ }
676
+ disconnectedCallback() {
677
+ if (this.hasNonVirtualTrigger) {
678
+ this.unbindEvents();
679
+ }
680
+ this.open = false;
681
+ super.disconnectedCallback();
682
+ }
683
+ };
684
+ export let Overlay = _Overlay;
685
+ Overlay.styles = [styles];
686
+ Overlay.openCount = 1;
687
+ __decorateClass([
688
+ property({ type: Boolean })
689
+ ], Overlay.prototype, "delayed", 2);
690
+ __decorateClass([
691
+ query(".dialog")
692
+ ], Overlay.prototype, "dialogEl", 2);
693
+ __decorateClass([
694
+ property({ type: Boolean })
695
+ ], Overlay.prototype, "disabled", 1);
696
+ __decorateClass([
697
+ queryAssignedElements({
698
+ flatten: true,
699
+ selector: ':not([slot="longpress-describedby-descriptor"])'
700
+ // gather only elements slotted into the default slot
701
+ })
702
+ ], Overlay.prototype, "elements", 2);
703
+ __decorateClass([
704
+ state()
705
+ ], Overlay.prototype, "isVisible", 2);
706
+ __decorateClass([
707
+ property({ type: Number })
708
+ ], Overlay.prototype, "offset", 2);
709
+ __decorateClass([
710
+ property({ type: Boolean, reflect: true })
711
+ ], Overlay.prototype, "open", 1);
712
+ __decorateClass([
713
+ property()
714
+ ], Overlay.prototype, "placement", 2);
715
+ __decorateClass([
716
+ property({ attribute: "receives-focus" })
717
+ ], Overlay.prototype, "receivesFocus", 2);
718
+ __decorateClass([
719
+ query("slot")
720
+ ], Overlay.prototype, "slotEl", 2);
721
+ __decorateClass([
722
+ property({ type: Number, attribute: "tip-padding" })
723
+ ], Overlay.prototype, "tipPadding", 2);
724
+ __decorateClass([
725
+ property()
726
+ ], Overlay.prototype, "trigger", 2);
727
+ __decorateClass([
728
+ property({ attribute: false })
729
+ ], Overlay.prototype, "triggerElement", 2);
730
+ __decorateClass([
731
+ property({ attribute: false })
732
+ ], Overlay.prototype, "triggerInteraction", 2);
733
+ __decorateClass([
734
+ property()
735
+ ], Overlay.prototype, "type", 2);
91
736
  //# sourceMappingURL=Overlay.dev.js.map