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

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 (155) hide show
  1. package/README.md +227 -152
  2. package/custom-elements.json +1401 -541
  3. package/package.json +48 -22
  4. package/sp-overlay.d.ts +6 -0
  5. package/sp-overlay.dev.js +5 -0
  6. package/{active-overlay.dev.js.map → sp-overlay.dev.js.map} +3 -3
  7. package/sp-overlay.js +2 -0
  8. package/{active-overlay.js.map → sp-overlay.js.map} +4 -4
  9. package/src/Overlay.d.ts +29 -0
  10. package/src/Overlay.dev.js +91 -0
  11. package/src/Overlay.dev.js.map +7 -0
  12. package/src/Overlay.js +2 -0
  13. package/src/Overlay.js.map +7 -0
  14. package/src/OverlayBase.d.ts +124 -0
  15. package/src/OverlayBase.dev.js +744 -0
  16. package/src/OverlayBase.dev.js.map +7 -0
  17. package/src/OverlayBase.js +31 -0
  18. package/src/OverlayBase.js.map +7 -0
  19. package/src/OverlayDialog.d.ts +8 -0
  20. package/src/OverlayDialog.dev.js +160 -0
  21. package/src/OverlayDialog.dev.js.map +7 -0
  22. package/src/OverlayDialog.js +2 -0
  23. package/src/OverlayDialog.js.map +7 -0
  24. package/src/OverlayNoPopover.d.ts +8 -0
  25. package/src/OverlayNoPopover.dev.js +149 -0
  26. package/src/OverlayNoPopover.dev.js.map +7 -0
  27. package/src/OverlayNoPopover.js +2 -0
  28. package/src/OverlayNoPopover.js.map +7 -0
  29. package/src/OverlayPopover.d.ts +8 -0
  30. package/src/OverlayPopover.dev.js +199 -0
  31. package/src/OverlayPopover.dev.js.map +7 -0
  32. package/src/OverlayPopover.js +2 -0
  33. package/src/OverlayPopover.js.map +7 -0
  34. package/src/OverlayStack.d.ts +29 -0
  35. package/src/OverlayStack.dev.js +126 -0
  36. package/src/OverlayStack.dev.js.map +7 -0
  37. package/src/OverlayStack.js +2 -0
  38. package/src/OverlayStack.js.map +7 -0
  39. package/src/OverlayTrigger.d.ts +23 -31
  40. package/src/OverlayTrigger.dev.js +135 -245
  41. package/src/OverlayTrigger.dev.js.map +3 -3
  42. package/src/OverlayTrigger.js +52 -22
  43. package/src/OverlayTrigger.js.map +3 -3
  44. package/src/PlacementController.d.ts +36 -0
  45. package/src/PlacementController.dev.js +191 -0
  46. package/src/PlacementController.dev.js.map +7 -0
  47. package/src/PlacementController.js +2 -0
  48. package/src/PlacementController.js.map +7 -0
  49. package/src/VirtualTrigger.dev.js +0 -2
  50. package/src/VirtualTrigger.dev.js.map +2 -2
  51. package/src/VirtualTrigger.js +1 -1
  52. package/src/VirtualTrigger.js.map +3 -3
  53. package/src/fullSizePlugin.d.ts +12 -0
  54. package/src/fullSizePlugin.dev.js +39 -0
  55. package/src/fullSizePlugin.dev.js.map +7 -0
  56. package/src/fullSizePlugin.js +2 -0
  57. package/src/fullSizePlugin.js.map +7 -0
  58. package/src/index.d.ts +2 -3
  59. package/src/index.dev.js +2 -3
  60. package/src/index.dev.js.map +2 -2
  61. package/src/index.js +1 -1
  62. package/src/index.js.map +2 -2
  63. package/src/loader.d.ts +2 -2
  64. package/src/loader.dev.js +2 -19
  65. package/src/loader.dev.js.map +2 -2
  66. package/src/loader.js +1 -1
  67. package/src/loader.js.map +3 -3
  68. package/src/overlay-base.css.dev.js +9 -0
  69. package/src/overlay-base.css.dev.js.map +7 -0
  70. package/src/overlay-base.css.js +6 -0
  71. package/src/overlay-base.css.js.map +7 -0
  72. package/src/overlay-trigger.css.dev.js +1 -1
  73. package/src/overlay-trigger.css.dev.js.map +1 -1
  74. package/src/overlay-trigger.css.js +1 -1
  75. package/src/overlay-trigger.css.js.map +1 -1
  76. package/src/overlay-types.d.ts +7 -5
  77. package/src/overlay-types.dev.js +1 -0
  78. package/src/overlay-types.dev.js.map +3 -3
  79. package/src/overlay-types.js +1 -1
  80. package/src/overlay-types.js.map +3 -3
  81. package/src/topLayerOverTransforms.d.ts +23 -0
  82. package/src/topLayerOverTransforms.dev.js +170 -0
  83. package/src/topLayerOverTransforms.dev.js.map +7 -0
  84. package/src/topLayerOverTransforms.js +2 -0
  85. package/src/topLayerOverTransforms.js.map +7 -0
  86. package/stories/overlay-element.stories.js +247 -0
  87. package/stories/overlay-element.stories.js.map +7 -0
  88. package/stories/overlay-story-components.js +9 -8
  89. package/stories/overlay-story-components.js.map +2 -2
  90. package/stories/overlay.stories.js +780 -683
  91. package/stories/overlay.stories.js.map +2 -2
  92. package/sync/overlay-trigger.d.ts +4 -0
  93. package/sync/overlay-trigger.dev.js +1 -4
  94. package/sync/overlay-trigger.dev.js.map +2 -2
  95. package/sync/overlay-trigger.js +1 -1
  96. package/sync/overlay-trigger.js.map +3 -3
  97. package/test/benchmark/basic-test.js +1 -1
  98. package/test/benchmark/basic-test.js.map +1 -1
  99. package/test/index.js +407 -376
  100. package/test/index.js.map +3 -3
  101. package/test/overlay-element.test-vrt.js +5 -0
  102. package/test/overlay-element.test-vrt.js.map +7 -0
  103. package/test/overlay-element.test.js +682 -0
  104. package/test/overlay-element.test.js.map +7 -0
  105. package/test/overlay-lifecycle.test.js +34 -106
  106. package/test/overlay-lifecycle.test.js.map +2 -2
  107. package/test/overlay-trigger-click.test.js +11 -5
  108. package/test/overlay-trigger-click.test.js.map +2 -2
  109. package/test/overlay-trigger-extended.test.js +1 -6
  110. package/test/overlay-trigger-extended.test.js.map +2 -2
  111. package/test/overlay-trigger-hover-click.test.js +23 -23
  112. package/test/overlay-trigger-hover-click.test.js.map +2 -2
  113. package/test/overlay-trigger-hover.test.js +40 -34
  114. package/test/overlay-trigger-hover.test.js.map +2 -2
  115. package/test/overlay-trigger-longpress.test.js +98 -80
  116. package/test/overlay-trigger-longpress.test.js.map +2 -2
  117. package/test/overlay-trigger-sync.test.js +1 -1
  118. package/test/overlay-trigger-sync.test.js.map +2 -2
  119. package/test/overlay-trigger.test.js +1 -1
  120. package/test/overlay-trigger.test.js.map +2 -2
  121. package/test/overlay-update.test.js +4 -4
  122. package/test/overlay-update.test.js.map +2 -2
  123. package/test/{overlay.test.js → overlay-v1.test.js} +267 -249
  124. package/test/overlay-v1.test.js.map +7 -0
  125. package/test/overlay-v2.test.js +720 -0
  126. package/test/overlay-v2.test.js.map +7 -0
  127. package/active-overlay.d.ts +0 -6
  128. package/active-overlay.dev.js +0 -5
  129. package/active-overlay.js +0 -2
  130. package/src/ActiveOverlay.d.ts +0 -84
  131. package/src/ActiveOverlay.dev.js +0 -517
  132. package/src/ActiveOverlay.dev.js.map +0 -7
  133. package/src/ActiveOverlay.js +0 -16
  134. package/src/ActiveOverlay.js.map +0 -7
  135. package/src/active-overlay.css.dev.js +0 -13
  136. package/src/active-overlay.css.dev.js.map +0 -7
  137. package/src/active-overlay.css.js +0 -10
  138. package/src/active-overlay.css.js.map +0 -7
  139. package/src/overlay-stack.d.ts +0 -50
  140. package/src/overlay-stack.dev.js +0 -515
  141. package/src/overlay-stack.dev.js.map +0 -7
  142. package/src/overlay-stack.js +0 -34
  143. package/src/overlay-stack.js.map +0 -7
  144. package/src/overlay-utils.d.ts +0 -3
  145. package/src/overlay-utils.dev.js +0 -31
  146. package/src/overlay-utils.dev.js.map +0 -7
  147. package/src/overlay-utils.js +0 -2
  148. package/src/overlay-utils.js.map +0 -7
  149. package/src/overlay.d.ts +0 -59
  150. package/src/overlay.dev.js +0 -127
  151. package/src/overlay.dev.js.map +0 -7
  152. package/src/overlay.js +0 -2
  153. package/src/overlay.js.map +0 -7
  154. package/test/overlay.test.js.map +0 -7
  155. /package/src/{active-overlay.css.d.ts → overlay-base.css.d.ts} +0 -0
@@ -1,32 +1,49 @@
1
1
  "use strict";
2
2
  import "@spectrum-web-components/button/sp-button.js";
3
3
  import "@spectrum-web-components/dialog/sp-dialog.js";
4
+ import "@spectrum-web-components/overlay/sp-overlay.js";
5
+ import "@spectrum-web-components/overlay/overlay-trigger.js";
6
+ import "@spectrum-web-components/tooltip/sp-tooltip.js";
4
7
  import "@spectrum-web-components/popover/sp-popover.js";
5
8
  import { setViewport } from "@web/test-runner-commands";
6
9
  import {
7
10
  Overlay
8
11
  } from "@spectrum-web-components/overlay";
9
- import { isVisible } from "../../../test/testing-helpers.js";
10
12
  import {
11
13
  elementUpdated,
12
14
  expect,
13
- fixture,
14
15
  html,
15
16
  nextFrame,
16
- oneEvent,
17
- waitUntil
17
+ oneEvent
18
18
  } from "@open-wc/testing";
19
19
  import { sendKeys } from "@web/test-runner-commands";
20
20
  import {
21
21
  definedOverlayElement,
22
- virtualElement
22
+ virtualElementV1
23
23
  } from "../stories/overlay.stories";
24
24
  import { sendMouse } from "../../../test/plugins/browser.js";
25
- describe("Overlays", () => {
25
+ import { spy } from "sinon";
26
+ import "@spectrum-web-components/theme/sp-theme.js";
27
+ import "@spectrum-web-components/theme/src/themes.js";
28
+ import { render } from "@spectrum-web-components/base";
29
+ import {
30
+ fixture,
31
+ isInteractive,
32
+ isOnTopLayer
33
+ } from "../../../test/testing-helpers.js";
34
+ async function styledFixture(story) {
35
+ const test = await fixture(html`
36
+ <sp-theme theme="spectrum" scale="medium" color="dark">
37
+ ${story}
38
+ </sp-theme>
39
+ `);
40
+ return test.children[0];
41
+ }
42
+ describe("Overlays, v1", () => {
26
43
  let testDiv;
27
44
  let openOverlays = [];
28
45
  beforeEach(async () => {
29
- testDiv = await fixture(
46
+ testDiv = await styledFixture(
30
47
  html`
31
48
  <div id="top">
32
49
  <style>
@@ -48,31 +65,28 @@ describe("Overlays", () => {
48
65
  display: none;
49
66
  }
50
67
  </style>
51
- <sp-button
52
- id="first-button"
53
- variant="primary"
54
- slot="trigger"
55
- >
68
+ <sp-button id="first-button" variant="primary">
56
69
  Show Popover
57
70
  </sp-button>
58
71
  <div id="overlay-content">
59
- <sp-popover
60
- id="outer-popover"
61
- slot="click-content"
62
- direction="bottom"
63
- tip
64
- open
65
- >
66
- <sp-dialog class="options-popover-content">
67
- A popover message
72
+ <sp-popover id="outer-popover" direction="bottom" tip>
73
+ <sp-dialog no-divider>
74
+ <div class="options-popover-content">
75
+ A popover message
76
+ </div>
77
+ <sp-button id="outer-focus-target">
78
+ Test 1
79
+ </sp-button>
80
+ <sp-button>Test 2</sp-button>
81
+ <sp-button>Test 3</sp-button>
68
82
  </sp-dialog>
69
83
  </sp-popover>
70
- <div id="hover-1" class="hover-content">
84
+ <sp-tooltip id="hover-1" class="hover-content">
71
85
  Hover message
72
- </div>
73
- <div id="hover-2" class="hover-content">
86
+ </sp-tooltip>
87
+ <sp-tooltip id="hover-2" class="hover-content">
74
88
  Other hover message
75
- </div>
89
+ </sp-tooltip>
76
90
  </div>
77
91
  </div>
78
92
  `
@@ -100,21 +114,19 @@ describe("Overlays", () => {
100
114
  ].map((direction) => {
101
115
  const placement = direction;
102
116
  it(`opens a popover - ${placement}`, async () => {
117
+ const clickSpy = spy();
103
118
  const button = testDiv.querySelector(
104
119
  "#first-button"
105
120
  );
106
121
  const outerPopover = testDiv.querySelector(
107
122
  "#outer-popover"
108
123
  );
109
- expect(outerPopover.parentElement).to.exist;
110
- if (outerPopover.parentElement) {
111
- expect(outerPopover.parentElement.id).to.equal(
112
- "overlay-content"
113
- );
114
- }
115
- expect(isVisible(outerPopover)).to.be.false;
124
+ outerPopover.addEventListener("click", () => {
125
+ clickSpy();
126
+ });
127
+ expect(await isInteractive(outerPopover)).to.be.false;
116
128
  expect(button).to.exist;
117
- const opened = oneEvent(button, "sp-opened");
129
+ const opened = oneEvent(outerPopover, "sp-opened");
118
130
  openOverlays.push(
119
131
  await Overlay.open(button, "click", outerPopover, {
120
132
  delayed: false,
@@ -123,25 +135,52 @@ describe("Overlays", () => {
123
135
  })
124
136
  );
125
137
  await opened;
126
- expect(outerPopover.parentElement).to.exist;
127
- if (outerPopover.parentElement) {
128
- expect(outerPopover.parentElement.id).not.to.equal(
129
- "overlay-content"
130
- );
131
- }
132
- expect(isVisible(outerPopover)).to.be.true;
138
+ expect(await isInteractive(outerPopover)).to.be.true;
139
+ });
140
+ });
141
+ it(`opens a modal dialog`, async () => {
142
+ const button = testDiv.querySelector("#first-button");
143
+ const outerPopover = testDiv.querySelector("#outer-popover");
144
+ expect(await isInteractive(outerPopover)).to.be.false;
145
+ expect(button).to.exist;
146
+ const opened = oneEvent(outerPopover, "sp-opened");
147
+ openOverlays.push(
148
+ await Overlay.open(button, "modal", outerPopover, {
149
+ delayed: false
150
+ })
151
+ );
152
+ await opened;
153
+ const firstFocused = outerPopover.querySelector(
154
+ "#outer-focus-target"
155
+ );
156
+ expect(document.activeElement === firstFocused).to.be.true;
157
+ await sendKeys({
158
+ press: "Tab"
159
+ });
160
+ expect(document.activeElement === button).to.be.false;
161
+ await sendKeys({
162
+ press: "Tab"
133
163
  });
164
+ expect(document.activeElement === button).to.be.false;
165
+ await sendKeys({
166
+ press: "Shift+Tab"
167
+ });
168
+ expect(document.activeElement === button).to.be.false;
169
+ await sendKeys({
170
+ press: "Shift+Tab"
171
+ });
172
+ expect(document.activeElement === button).to.be.false;
173
+ await sendKeys({
174
+ press: "Shift+Tab"
175
+ });
176
+ expect(document.activeElement === button).to.be.false;
134
177
  });
135
178
  it(`updates a popover`, async () => {
136
179
  const button = testDiv.querySelector("#first-button");
137
180
  const outerPopover = testDiv.querySelector("#outer-popover");
138
- expect(outerPopover.parentElement).to.exist;
139
- if (outerPopover.parentElement) {
140
- expect(outerPopover.parentElement.id).to.equal("overlay-content");
141
- }
142
- expect(isVisible(outerPopover)).to.be.false;
181
+ expect(await isInteractive(outerPopover)).to.be.false;
143
182
  expect(button).to.exist;
144
- const opened = oneEvent(button, "sp-opened");
183
+ const opened = oneEvent(outerPopover, "sp-opened");
145
184
  openOverlays.push(
146
185
  await Overlay.open(button, "click", outerPopover, {
147
186
  delayed: false,
@@ -149,20 +188,16 @@ describe("Overlays", () => {
149
188
  })
150
189
  );
151
190
  await opened;
152
- expect(isVisible(outerPopover)).to.be.true;
191
+ expect(await isInteractive(outerPopover)).to.be.true;
153
192
  Overlay.update();
154
- expect(isVisible(outerPopover)).to.be.true;
193
+ expect(await isInteractive(outerPopover)).to.be.true;
155
194
  });
156
195
  it(`opens a popover w/ delay`, async () => {
157
196
  const button = testDiv.querySelector("#first-button");
158
197
  const outerPopover = testDiv.querySelector("#outer-popover");
159
- expect(outerPopover.parentElement).to.exist;
160
- if (outerPopover.parentElement) {
161
- expect(outerPopover.parentElement.id).to.equal("overlay-content");
162
- }
163
- expect(isVisible(outerPopover)).to.be.false;
198
+ expect(await isInteractive(outerPopover)).to.be.false;
164
199
  expect(button).to.exist;
165
- const opened = oneEvent(button, "sp-opened");
200
+ const opened = oneEvent(outerPopover, "sp-opened");
166
201
  openOverlays.push(
167
202
  await Overlay.open(button, "click", outerPopover, {
168
203
  delayed: true,
@@ -170,13 +205,7 @@ describe("Overlays", () => {
170
205
  })
171
206
  );
172
207
  await opened;
173
- expect(outerPopover.parentElement).to.exist;
174
- if (outerPopover.parentElement) {
175
- expect(outerPopover.parentElement.id).not.to.equal(
176
- "overlay-content"
177
- );
178
- }
179
- expect(isVisible(outerPopover)).to.be.true;
208
+ expect(await isInteractive(outerPopover)).to.be.true;
180
209
  });
181
210
  it("opens hover overlay", async () => {
182
211
  const button = testDiv.querySelector("#first-button");
@@ -184,9 +213,9 @@ describe("Overlays", () => {
184
213
  const clickOverlay = testDiv.querySelector(
185
214
  "#outer-popover"
186
215
  );
187
- expect(isVisible(hoverOverlay)).to.be.false;
188
- expect(isVisible(clickOverlay)).to.be.false;
189
- let opened = oneEvent(button, "sp-opened");
216
+ expect(await isOnTopLayer(hoverOverlay)).to.be.false;
217
+ expect(await isOnTopLayer(clickOverlay)).to.be.false;
218
+ let opened = oneEvent(hoverOverlay, "sp-opened");
190
219
  openOverlays.push(
191
220
  await Overlay.open(button, "hover", hoverOverlay, {
192
221
  delayed: false,
@@ -195,14 +224,9 @@ describe("Overlays", () => {
195
224
  })
196
225
  );
197
226
  await opened;
198
- expect(hoverOverlay.parentElement).to.exist;
199
- if (hoverOverlay.parentElement) {
200
- expect(hoverOverlay.parentElement.id).not.to.equal(
201
- "overlay-content"
202
- );
203
- }
204
- expect(isVisible(hoverOverlay)).to.be.true;
205
- opened = oneEvent(button, "sp-opened");
227
+ expect(await isOnTopLayer(hoverOverlay)).to.be.true;
228
+ opened = oneEvent(clickOverlay, "sp-opened");
229
+ const closed = oneEvent(hoverOverlay, "sp-closed");
206
230
  openOverlays.push(
207
231
  await Overlay.open(button, "click", clickOverlay, {
208
232
  delayed: false,
@@ -211,11 +235,12 @@ describe("Overlays", () => {
211
235
  })
212
236
  );
213
237
  await opened;
214
- if (hoverOverlay.parentElement) {
215
- expect(hoverOverlay.parentElement.id).to.equal("overlay-content");
216
- }
217
- expect(isVisible(hoverOverlay)).to.be.false;
218
- expect(isVisible(clickOverlay)).to.be.true;
238
+ await closed;
239
+ expect(
240
+ await isInteractive(clickOverlay),
241
+ "click overlay not interactive"
242
+ ).to.be.true;
243
+ expect(await isOnTopLayer(hoverOverlay), "hover overlay interactive").to.be.false;
219
244
  });
220
245
  it("opens custom overlay", async () => {
221
246
  const button = testDiv.querySelector("#first-button");
@@ -225,9 +250,9 @@ describe("Overlays", () => {
225
250
  );
226
251
  expect(button).to.exist;
227
252
  expect(customOverlay).to.exist;
228
- expect(isVisible(customOverlay)).to.be.false;
229
- expect(isVisible(clickOverlay)).to.be.false;
230
- let opened = oneEvent(button, "sp-opened");
253
+ expect(await isOnTopLayer(customOverlay)).to.be.false;
254
+ expect(await isOnTopLayer(clickOverlay)).to.be.false;
255
+ let opened = oneEvent(customOverlay, "sp-opened");
231
256
  openOverlays.push(
232
257
  await Overlay.open(button, "custom", customOverlay, {
233
258
  delayed: false,
@@ -236,14 +261,8 @@ describe("Overlays", () => {
236
261
  })
237
262
  );
238
263
  await opened;
239
- expect(customOverlay.parentElement).to.exist;
240
- if (customOverlay.parentElement) {
241
- expect(customOverlay.parentElement.id).not.to.equal(
242
- "overlay-content"
243
- );
244
- }
245
- expect(isVisible(customOverlay)).to.be.true;
246
- opened = oneEvent(button, "sp-opened");
264
+ expect(await isOnTopLayer(customOverlay)).to.be.true;
265
+ opened = oneEvent(clickOverlay, "sp-opened");
247
266
  openOverlays.push(
248
267
  await Overlay.open(button, "click", clickOverlay, {
249
268
  delayed: false,
@@ -252,52 +271,58 @@ describe("Overlays", () => {
252
271
  })
253
272
  );
254
273
  await opened;
255
- expect(isVisible(customOverlay)).to.be.true;
256
- expect(isVisible(clickOverlay)).to.be.true;
274
+ expect(await isOnTopLayer(clickOverlay), "click content open").to.be.true;
257
275
  });
258
276
  it("closes via events", async () => {
259
- const el = await fixture(html`
260
- <div id="root">
261
- <sp-dialog dismissable></sp-dialog>
277
+ const test = await fixture(html`
278
+ <div>
279
+ <sp-popover id="root">
280
+ <sp-dialog dismissable>
281
+ Some Content for the Dialog.
282
+ </sp-dialog>
283
+ </sp-popover>
262
284
  </div>
263
285
  `);
286
+ const el = test.querySelector("sp-popover");
264
287
  const dialog = el.querySelector("sp-dialog");
265
288
  const opened = oneEvent(el, "sp-opened");
266
289
  openOverlays.push(
267
- await Overlay.open(el, "click", dialog, {
290
+ await Overlay.open(test, "click", el, {
268
291
  delayed: false,
269
292
  placement: "bottom",
270
293
  offset: 10
271
294
  })
272
295
  );
273
296
  await opened;
297
+ expect(await isInteractive(el)).to.be.true;
298
+ const closed = oneEvent(el, "sp-closed");
274
299
  dialog.close();
275
- await waitUntil(
276
- () => !!dialog.parentElement && dialog.parentElement.tagName !== "ACTIVE-OVERLAY",
277
- "content is returned"
278
- );
300
+ await closed;
301
+ expect(await isInteractive(el)).to.be.false;
279
302
  });
280
303
  it("closes an inline overlay when tabbing past the content", async () => {
281
304
  const el = await fixture(html`
282
305
  <div>
283
306
  <sp-button class="trigger">Trigger</sp-button>
284
- <div class="content">
307
+ <sp-popover class="content">
285
308
  <input />
286
- </div>
309
+ </sp-popover>
287
310
  <input value="After" id="after" />
288
311
  </div>
289
312
  `);
290
313
  const trigger = el.querySelector(".trigger");
291
314
  const content = el.querySelector(".content");
292
315
  const input = el.querySelector("input");
293
- const after = el.querySelector("#after");
294
- openOverlays.push(await Overlay.open(trigger, "inline", content, {}));
295
- trigger.focus();
296
- await sendKeys({
297
- press: "Tab"
298
- });
316
+ const after2 = el.querySelector("#after");
317
+ const opened = oneEvent(content, "sp-opened");
318
+ openOverlays.push(
319
+ await Overlay.open(trigger, "inline", content, {
320
+ receivesFocus: "auto"
321
+ })
322
+ );
323
+ await opened;
324
+ expect(await isInteractive(content)).to.be.true;
299
325
  expect(document.activeElement).to.equal(input);
300
- expect(input.closest("active-overlay") !== null);
301
326
  await sendKeys({
302
327
  press: "Shift+Tab"
303
328
  });
@@ -306,13 +331,13 @@ describe("Overlays", () => {
306
331
  press: "Tab"
307
332
  });
308
333
  expect(document.activeElement).to.equal(input);
334
+ const closed = oneEvent(content, "sp-closed");
309
335
  await sendKeys({
310
336
  press: "Tab"
311
337
  });
312
- expect(document.activeElement).to.equal(after);
313
- await waitUntil(
314
- () => document.querySelector("active-overlay") === null
315
- );
338
+ expect(document.activeElement).to.equal(after2);
339
+ await closed;
340
+ expect(await isInteractive(content)).to.be.false;
316
341
  });
317
342
  it("closes an inline overlay when tabbing before the trigger", async () => {
318
343
  const el = await fixture(html`
@@ -330,14 +355,13 @@ describe("Overlays", () => {
330
355
  const trigger = el.querySelector(".trigger");
331
356
  const content = el.querySelector(".content");
332
357
  const input = el.querySelector(".content input");
333
- const before = el.querySelector("#before");
358
+ const before2 = el.querySelector("#before");
334
359
  openOverlays.push(await Overlay.open(trigger, "inline", content, {}));
335
360
  trigger.focus();
336
361
  await sendKeys({
337
362
  press: "Tab"
338
363
  });
339
364
  expect(document.activeElement).to.equal(input);
340
- expect(input.closest("active-overlay") !== null);
341
365
  await sendKeys({
342
366
  press: "Shift+Tab"
343
367
  });
@@ -345,10 +369,7 @@ describe("Overlays", () => {
345
369
  await sendKeys({
346
370
  press: "Shift+Tab"
347
371
  });
348
- expect(document.activeElement).to.equal(before);
349
- await waitUntil(
350
- () => document.querySelector("active-overlay") === null
351
- );
372
+ expect(document.activeElement).to.equal(before2);
352
373
  });
353
374
  it("opens detached content", async () => {
354
375
  const textContent = "This is a detached element that has been overlaid";
@@ -357,118 +378,127 @@ describe("Overlays", () => {
357
378
  <button>Trigger</button>
358
379
  `
359
380
  );
360
- const content = document.createElement("div");
381
+ const content = document.createElement("sp-popover");
361
382
  content.textContent = textContent;
362
- const opened = oneEvent(el, "sp-opened");
383
+ const opened = oneEvent(content, "sp-opened");
363
384
  const closeOverlay = await Overlay.open(el, "click", content, {
364
385
  placement: "bottom"
365
386
  });
366
387
  await opened;
367
- let activeOverlay = document.querySelector("active-overlay");
368
- if (activeOverlay) {
369
- expect(activeOverlay.textContent).to.equal(textContent);
370
- } else {
371
- expect(activeOverlay).to.not.be.null;
372
- }
373
- const closed = oneEvent(el, "sp-closed");
388
+ expect(await isInteractive(content)).to.be.true;
389
+ const closed = oneEvent(content, "sp-closed");
374
390
  closeOverlay();
375
391
  await closed;
376
- activeOverlay = document.querySelector("active-overlay");
377
- expect(activeOverlay).to.be.null;
392
+ expect(await isInteractive(content)).to.be.false;
378
393
  content.remove();
379
394
  });
380
395
  });
381
- describe('Overlay - type="modal"', () => {
382
- it("closes on `contextmenu` and passes that to the underlying page", async () => {
383
- await fixture(html`
384
- ${virtualElement({
385
- ...virtualElement.args,
386
- offset: 6
387
- })}
388
- `);
389
- const width = window.innerWidth;
390
- const height = window.innerHeight;
391
- let opened = oneEvent(document, "sp-opened");
392
- sendMouse({
393
- steps: [
394
- {
395
- type: "move",
396
- position: [width / 2 + 50, height / 2]
397
- },
398
- {
399
- type: "click",
400
- options: {
401
- button: "right"
402
- },
403
- position: [width / 2 + 50, height / 2]
404
- }
405
- ]
396
+ describe('Overlay - type="modal", v1', () => {
397
+ describe("handle multiple separate `contextmenu` events", async () => {
398
+ let width = 0;
399
+ let height = 0;
400
+ let firstMenu;
401
+ let firstRect;
402
+ let secondMenu;
403
+ let secondRect;
404
+ before(async () => {
405
+ render(
406
+ html`
407
+ <sp-theme color="light" scale="large">
408
+ ${virtualElementV1({
409
+ ...virtualElementV1.args,
410
+ offset: 6
411
+ })}
412
+ </sp-theme>
413
+ `,
414
+ document.body
415
+ );
416
+ width = window.innerWidth;
417
+ height = window.innerHeight;
406
418
  });
407
- await opened;
408
- const firstOverlay = document.querySelector(
409
- "active-overlay"
410
- );
411
- const firstHeadline = firstOverlay.querySelector(
412
- '[slot="header"]'
413
- );
414
- expect(firstOverlay, "first overlay").to.not.be.null;
415
- expect(firstOverlay.isConnected).to.be.true;
416
- expect(firstHeadline.textContent).to.equal("Menu source: end");
417
- let closed = oneEvent(document, "sp-closed");
418
- opened = oneEvent(document, "sp-opened");
419
- sendMouse({
420
- steps: [
421
- {
422
- type: "move",
423
- position: [width / 4, height / 4]
424
- },
425
- {
426
- type: "click",
427
- options: {
428
- button: "right"
419
+ after(() => {
420
+ var _a;
421
+ (_a = document.querySelector("sp-theme")) == null ? void 0 : _a.remove();
422
+ });
423
+ it('opens the first "contextmenu" overlay', async () => {
424
+ const opened = oneEvent(document, "sp-opened");
425
+ await sendMouse({
426
+ steps: [
427
+ {
428
+ type: "move",
429
+ position: [width / 2 + 50, height / 2]
429
430
  },
430
- position: [width / 4, height / 4]
431
- }
432
- ]
431
+ {
432
+ type: "click",
433
+ options: {
434
+ button: "right"
435
+ },
436
+ position: [width / 2 + 50, height / 2]
437
+ }
438
+ ]
439
+ });
440
+ await opened;
441
+ firstMenu = document.querySelector("sp-popover");
442
+ expect(firstMenu.textContent).to.include("Menu source: end");
443
+ firstRect = firstMenu.getBoundingClientRect();
444
+ expect(firstMenu).to.not.be.null;
433
445
  });
434
- await closed;
435
- await opened;
436
- const secondOverlay = document.querySelector(
437
- "active-overlay"
438
- );
439
- const secondHeadline = secondOverlay.querySelector(
440
- '[slot="header"]'
441
- );
442
- expect(secondOverlay, "second overlay").to.not.be.null;
443
- expect(secondOverlay).to.not.equal(firstOverlay);
444
- expect(firstOverlay.isConnected).to.be.false;
445
- expect(secondOverlay.isConnected).to.be.true;
446
- expect(secondHeadline.textContent).to.equal("Menu source: start");
447
- closed = oneEvent(document, "sp-closed");
448
- sendMouse({
449
- steps: [
450
- {
451
- type: "move",
452
- position: [width / 8, height / 8]
453
- },
454
- {
455
- type: "click",
456
- position: [width / 8, height / 8]
457
- }
458
- ]
446
+ it('closes the first "contextmenu" when opening a second', async () => {
447
+ var _a, _b, _c, _d;
448
+ const closed = oneEvent(document, "sp-closed");
449
+ const opened = oneEvent(document, "sp-opened");
450
+ const trigger = document.querySelector(
451
+ "start-end-contextmenu"
452
+ );
453
+ (_b = (_a = trigger.shadowRoot) == null ? void 0 : _a.querySelector("#start")) == null ? void 0 : _b.dispatchEvent(
454
+ new Event("contextmenu", {
455
+ composed: true
456
+ })
457
+ );
458
+ await nextFrame();
459
+ (_d = (_c = trigger.shadowRoot) == null ? void 0 : _c.querySelector("#start")) == null ? void 0 : _d.dispatchEvent(
460
+ new Event("pointerup", {
461
+ composed: true,
462
+ bubbles: true
463
+ })
464
+ );
465
+ await closed;
466
+ await opened;
467
+ secondMenu = document.querySelector("sp-popover");
468
+ expect(secondMenu.textContent).to.include("Menu source: start");
469
+ secondRect = secondMenu.getBoundingClientRect();
470
+ expect(secondMenu).to.not.be.null;
471
+ });
472
+ it('closes the second "contextmenu" when clicking away', async () => {
473
+ const closed = oneEvent(document, "sp-closed");
474
+ sendMouse({
475
+ steps: [
476
+ {
477
+ type: "click",
478
+ position: [width - width / 8, height - height / 8]
479
+ }
480
+ ]
481
+ });
482
+ await closed;
483
+ expect(firstRect.top).to.not.equal(secondRect.top);
484
+ expect(firstRect.left).to.not.equal(secondRect.left);
459
485
  });
460
- await closed;
461
- await nextFrame();
462
486
  });
463
487
  it("does not open content off of the viewport", async () => {
488
+ before(async () => {
489
+ await setViewport({ width: 360, height: 640 });
490
+ await nextFrame();
491
+ });
492
+ after(async () => {
493
+ await setViewport({ width: 800, height: 600 });
494
+ await nextFrame();
495
+ });
464
496
  await fixture(html`
465
- ${virtualElement({
466
- ...virtualElement.args,
497
+ ${virtualElementV1({
498
+ ...virtualElementV1.args,
467
499
  offset: 6
468
500
  })}
469
501
  `);
470
- await setViewport({ width: 360, height: 640 });
471
- await nextFrame();
472
502
  const opened = oneEvent(document, "sp-opened");
473
503
  sendMouse({
474
504
  steps: [
@@ -486,19 +516,15 @@ describe('Overlay - type="modal"', () => {
486
516
  ]
487
517
  });
488
518
  await opened;
489
- const activeOverlay = document.querySelector(
490
- "active-overlay"
491
- );
492
- expect(activeOverlay.placement).to.equal("right-start");
493
- expect(activeOverlay.getAttribute("actual-placement")).to.equal(
494
- "bottom"
495
- );
519
+ const firstMenu = document.querySelector("sp-menu");
520
+ expect(firstMenu).to.not.be.null;
521
+ expect(await isInteractive(firstMenu)).to.be.true;
496
522
  const closed = oneEvent(document, "sp-closed");
497
523
  sendKeys({
498
524
  press: "Escape"
499
525
  });
500
526
  await closed;
501
- await nextFrame();
527
+ expect(await isInteractive(firstMenu)).to.be.false;
502
528
  });
503
529
  it("opens children in the modal stack through shadow roots", async () => {
504
530
  const el = await fixture(definedOverlayElement());
@@ -508,51 +534,47 @@ describe('Overlay - type="modal"', () => {
508
534
  let open = oneEvent(el, "sp-opened");
509
535
  trigger.click();
510
536
  await open;
537
+ expect(el.open).to.equal("click");
511
538
  const content = document.querySelector(
512
539
  "popover-content"
513
540
  );
514
541
  open = oneEvent(content, "sp-opened");
515
542
  content.button.click();
516
543
  await open;
517
- const activeOverlays = document.querySelectorAll("active-overlay");
518
- activeOverlays.forEach((overlay) => {
519
- expect(overlay.slot).to.equal("open");
520
- });
544
+ expect(content.trigger.open).to.equal("click");
521
545
  let close = oneEvent(content, "sp-closed");
522
546
  content.trigger.removeAttribute("open");
523
547
  await close;
548
+ expect(content.trigger.open).to.be.null;
524
549
  close = oneEvent(el, "sp-closed");
525
550
  el.removeAttribute("open");
526
551
  await close;
552
+ expect(el.open).to.be.null;
527
553
  });
528
554
  });
529
- describe("Overlay - timing", () => {
555
+ describe("Overlay - timing, v1", () => {
530
556
  it("manages multiple modals in a row without preventing them from closing", async () => {
531
557
  const test = await fixture(html`
532
558
  <div>
533
- <overlay-trigger>
559
+ <overlay-trigger id="test-1" placement="right">
534
560
  <sp-button slot="trigger">Trigger 1</sp-button>
535
561
  <sp-popover slot="hover-content">
536
562
  <p>Hover contentent for "Trigger 1".</p>
537
563
  </sp-popover>
538
564
  </overlay-trigger>
539
- <overlay-trigger>
565
+ <overlay-trigger id="test-2" placement="right">
540
566
  <sp-button slot="trigger">Trigger 2</sp-button>
541
- <sp-popover slot="hover-content">
542
- <p>Hover contentent for "Trigger 2".</p>
543
- </sp-popover>
544
567
  <sp-popover slot="click-content">
545
568
  <p>Click contentent for "Trigger 2".</p>
546
569
  </sp-popover>
570
+ <sp-popover slot="hover-content">
571
+ <p>Hover contentent for "Trigger 2".</p>
572
+ </sp-popover>
547
573
  </overlay-trigger>
548
574
  </div>
549
575
  `);
550
- const overlayTrigger1 = test.querySelector(
551
- "overlay-trigger:first-child"
552
- );
553
- const overlayTrigger2 = test.querySelector(
554
- "overlay-trigger:last-child"
555
- );
576
+ const overlayTrigger1 = test.querySelector("#test-1");
577
+ const overlayTrigger2 = test.querySelector("#test-2");
556
578
  const trigger1 = overlayTrigger1.querySelector(
557
579
  '[slot="trigger"]'
558
580
  );
@@ -565,17 +587,13 @@ describe("Overlay - timing", () => {
565
587
  boundingRectTrigger1.left + boundingRectTrigger1.width / 2,
566
588
  boundingRectTrigger1.top + boundingRectTrigger1.height / 2
567
589
  ];
568
- const outsideTrigger1 = [
569
- boundingRectTrigger1.left + boundingRectTrigger1.width * 2,
570
- boundingRectTrigger1.top + boundingRectTrigger1.height * 2
590
+ const outsideTriggers = [
591
+ boundingRectTrigger1.left + boundingRectTrigger1.width / 2,
592
+ 300
571
593
  ];
572
594
  const trigger2Position = [
573
595
  boundingRectTrigger2.left + boundingRectTrigger2.width / 2,
574
- boundingRectTrigger2.top + boundingRectTrigger2.height / 2
575
- ];
576
- const outsideTrigger2 = [
577
- boundingRectTrigger2.left + boundingRectTrigger2.width * 2,
578
- boundingRectTrigger2.top + boundingRectTrigger2.height / 2
596
+ boundingRectTrigger2.top + boundingRectTrigger2.height / 4
579
597
  ];
580
598
  await sendMouse({
581
599
  steps: [
@@ -591,7 +609,7 @@ describe("Overlay - timing", () => {
591
609
  steps: [
592
610
  {
593
611
  type: "move",
594
- position: outsideTrigger1
612
+ position: outsideTriggers
595
613
  }
596
614
  ]
597
615
  });
@@ -608,7 +626,7 @@ describe("Overlay - timing", () => {
608
626
  await nextFrame();
609
627
  await nextFrame();
610
628
  const opened = oneEvent(trigger2, "sp-opened");
611
- sendMouse({
629
+ await sendMouse({
612
630
  steps: [
613
631
  {
614
632
  type: "click",
@@ -617,23 +635,23 @@ describe("Overlay - timing", () => {
617
635
  ]
618
636
  });
619
637
  await opened;
638
+ await nextFrame();
639
+ await nextFrame();
620
640
  expect(overlayTrigger1.hasAttribute("open")).to.be.false;
621
641
  expect(overlayTrigger2.hasAttribute("open")).to.be.true;
622
642
  expect(overlayTrigger2.getAttribute("open")).to.equal("click");
623
643
  const closed = oneEvent(overlayTrigger2, "sp-closed");
624
- sendMouse({
644
+ await sendMouse({
625
645
  steps: [
626
646
  {
627
647
  type: "click",
628
- position: outsideTrigger2
648
+ position: outsideTriggers
629
649
  }
630
650
  ]
631
651
  });
632
652
  await closed;
633
- for (let i = 0; i < 3; i++)
634
- await nextFrame();
635
653
  expect(overlayTrigger1.hasAttribute("open")).to.be.false;
636
- expect(overlayTrigger2.hasAttribute("open"), overlayTrigger2.open).to.be.false;
654
+ expect(overlayTrigger2.hasAttribute("open")).to.be.false;
637
655
  });
638
656
  });
639
- //# sourceMappingURL=overlay.test.js.map
657
+ //# sourceMappingURL=overlay-v1.test.js.map