@spectrum-web-components/overlay 1.0.2 → 1.0.3

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 (74) hide show
  1. package/LICENSE +201 -0
  2. package/custom-elements.json +189 -73
  3. package/package.json +8 -7
  4. package/src/Overlay.d.ts +348 -18
  5. package/src/Overlay.dev.js +271 -12
  6. package/src/Overlay.dev.js.map +2 -2
  7. package/src/Overlay.js +4 -4
  8. package/src/Overlay.js.map +3 -3
  9. package/src/PlacementController.d.ts +118 -1
  10. package/src/PlacementController.dev.js +75 -0
  11. package/src/PlacementController.dev.js.map +2 -2
  12. package/src/PlacementController.js.map +2 -2
  13. package/src/overlay.css.dev.js +1 -1
  14. package/src/overlay.css.dev.js.map +1 -1
  15. package/src/overlay.css.js +1 -1
  16. package/src/overlay.css.js.map +1 -1
  17. package/stories/index.js +48 -0
  18. package/stories/index.js.map +7 -0
  19. package/stories/overlay-directive.stories.js +324 -0
  20. package/stories/overlay-directive.stories.js.map +7 -0
  21. package/stories/overlay-element.stories.js +675 -0
  22. package/stories/overlay-element.stories.js.map +7 -0
  23. package/stories/overlay-story-components.js +338 -0
  24. package/stories/overlay-story-components.js.map +7 -0
  25. package/stories/overlay.stories.js +1397 -0
  26. package/stories/overlay.stories.js.map +7 -0
  27. package/test/benchmark/basic-test.js +40 -0
  28. package/test/benchmark/basic-test.js.map +7 -0
  29. package/test/benchmark/directive-test.js +43 -0
  30. package/test/benchmark/directive-test.js.map +7 -0
  31. package/test/benchmark/element-test.js +40 -0
  32. package/test/benchmark/element-test.js.map +7 -0
  33. package/test/benchmark/lazy-test.js +47 -0
  34. package/test/benchmark/lazy-test.js.map +7 -0
  35. package/test/index.js +605 -0
  36. package/test/index.js.map +7 -0
  37. package/test/overlay-directive.test-vrt.js +5 -0
  38. package/test/overlay-directive.test-vrt.js.map +7 -0
  39. package/test/overlay-directive.test.js +162 -0
  40. package/test/overlay-directive.test.js.map +7 -0
  41. package/test/overlay-element.test-vrt.js +5 -0
  42. package/test/overlay-element.test-vrt.js.map +7 -0
  43. package/test/overlay-element.test.js +934 -0
  44. package/test/overlay-element.test.js.map +7 -0
  45. package/test/overlay-lifecycle.test.js +139 -0
  46. package/test/overlay-lifecycle.test.js.map +7 -0
  47. package/test/overlay-memory.test.js +10 -0
  48. package/test/overlay-memory.test.js.map +7 -0
  49. package/test/overlay-timer.test.js +118 -0
  50. package/test/overlay-timer.test.js.map +7 -0
  51. package/test/overlay-trigger-click.test.js +164 -0
  52. package/test/overlay-trigger-click.test.js.map +7 -0
  53. package/test/overlay-trigger-directive.test.js +75 -0
  54. package/test/overlay-trigger-directive.test.js.map +7 -0
  55. package/test/overlay-trigger-extended.test.js +235 -0
  56. package/test/overlay-trigger-extended.test.js.map +7 -0
  57. package/test/overlay-trigger-hover-click.test.js +225 -0
  58. package/test/overlay-trigger-hover-click.test.js.map +7 -0
  59. package/test/overlay-trigger-hover.test.js +308 -0
  60. package/test/overlay-trigger-hover.test.js.map +7 -0
  61. package/test/overlay-trigger-longpress.test.js +549 -0
  62. package/test/overlay-trigger-longpress.test.js.map +7 -0
  63. package/test/overlay-trigger-sync.test.js +5 -0
  64. package/test/overlay-trigger-sync.test.js.map +7 -0
  65. package/test/overlay-trigger.test.js +5 -0
  66. package/test/overlay-trigger.test.js.map +7 -0
  67. package/test/overlay-update.test.js +28 -0
  68. package/test/overlay-update.test.js.map +7 -0
  69. package/test/overlay-v1.test.js +569 -0
  70. package/test/overlay-v1.test.js.map +7 -0
  71. package/test/overlay.test-vrt.js +5 -0
  72. package/test/overlay.test-vrt.js.map +7 -0
  73. package/test/overlay.test.js +776 -0
  74. package/test/overlay.test.js.map +7 -0
@@ -0,0 +1,1397 @@
1
+ "use strict";
2
+ import { html } from "@spectrum-web-components/base";
3
+ import { ifDefined } from "@spectrum-web-components/base/src/directives.js";
4
+ import {
5
+ openOverlay,
6
+ Overlay,
7
+ VirtualTrigger
8
+ } from "@spectrum-web-components/overlay";
9
+ import "@spectrum-web-components/action-button/sp-action-button.js";
10
+ import "@spectrum-web-components/action-group/sp-action-group.js";
11
+ import "@spectrum-web-components/button/sp-button.js";
12
+ import "@spectrum-web-components/dialog/sp-dialog.js";
13
+ import "@spectrum-web-components/dialog/sp-dialog-wrapper.js";
14
+ import "@spectrum-web-components/field-label/sp-field-label.js";
15
+ import "@spectrum-web-components/icons-workflow/icons/sp-icon-magnify.js";
16
+ import "@spectrum-web-components/icons-workflow/icons/sp-icon-open-in.js";
17
+ import "@spectrum-web-components/overlay/overlay-trigger.js";
18
+ import "@spectrum-web-components/picker/sp-picker.js";
19
+ import "@spectrum-web-components/overlay/sp-overlay.js";
20
+ import "@spectrum-web-components/menu/sp-menu.js";
21
+ import "@spectrum-web-components/menu/sp-menu-item.js";
22
+ import "@spectrum-web-components/menu/sp-menu-group.js";
23
+ import "@spectrum-web-components/menu/sp-menu-divider.js";
24
+ import "@spectrum-web-components/popover/sp-popover.js";
25
+ import "@spectrum-web-components/slider/sp-slider.js";
26
+ import "@spectrum-web-components/radio/sp-radio.js";
27
+ import "@spectrum-web-components/radio/sp-radio-group.js";
28
+ import "@spectrum-web-components/tooltip/sp-tooltip.js";
29
+ import "@spectrum-web-components/theme/sp-theme.js";
30
+ import "@spectrum-web-components/theme/src/themes.js";
31
+ import "@spectrum-web-components/accordion/sp-accordion.js";
32
+ import "@spectrum-web-components/accordion/sp-accordion-item.js";
33
+ import "@spectrum-web-components/button-group/sp-button-group.js";
34
+ import "../../../projects/story-decorator/src/types.js";
35
+ import "./overlay-story-components.js";
36
+ import { render } from "lit-html";
37
+ const storyStyles = html`
38
+ <style>
39
+ html,
40
+ body,
41
+ #root,
42
+ #root-inner,
43
+ sp-story-decorator {
44
+ height: 100%;
45
+ margin: 0;
46
+ }
47
+
48
+ sp-story-decorator::part(container) {
49
+ display: flex;
50
+ flex-direction: column;
51
+ width: 100%;
52
+ height: 100%;
53
+ align-items: center;
54
+ justify-content: center;
55
+ }
56
+
57
+ overlay-trigger {
58
+ flex: none;
59
+ }
60
+
61
+ #styled-div {
62
+ background-color: var(--styled-div-background-color, blue);
63
+ color: white;
64
+ padding: 4px 10px;
65
+ margin-bottom: 10px;
66
+ }
67
+
68
+ #inner-trigger {
69
+ display: inline-block;
70
+ }
71
+ </style>
72
+ `;
73
+ export default {
74
+ title: "Overlay",
75
+ argTypes: {
76
+ offset: { control: "number" },
77
+ placement: {
78
+ control: {
79
+ type: "inline-radio",
80
+ options: [
81
+ "top",
82
+ "top-start",
83
+ "top-end",
84
+ "bottom",
85
+ "bottom-start",
86
+ "bottom-end",
87
+ "left",
88
+ "left-start",
89
+ "left-end",
90
+ "right",
91
+ "right-start",
92
+ "right-end",
93
+ "auto",
94
+ "auto-start",
95
+ "auto-end",
96
+ "none"
97
+ ]
98
+ }
99
+ },
100
+ type: {
101
+ control: {
102
+ type: "inline-radio",
103
+ options: ["modal", "replace", "inline"]
104
+ }
105
+ },
106
+ colorStop: {
107
+ control: {
108
+ type: "inline-radio",
109
+ options: ["light", "dark"]
110
+ }
111
+ }
112
+ },
113
+ args: {
114
+ placement: "bottom",
115
+ offset: 0,
116
+ colorStop: "light"
117
+ }
118
+ };
119
+ const template = ({
120
+ placement,
121
+ offset,
122
+ open,
123
+ type
124
+ }) => {
125
+ return html`
126
+ ${storyStyles}
127
+ <overlay-trigger
128
+ content="click hover"
129
+ id="trigger"
130
+ placement="${placement}"
131
+ offset="${offset}"
132
+ open=${ifDefined(open)}
133
+ type=${ifDefined(type)}
134
+ >
135
+ <sp-button variant="primary" slot="trigger">Show Popover</sp-button>
136
+ <sp-popover slot="click-content" placement="${placement}" tip>
137
+ <sp-dialog no-divider>
138
+ <sp-slider
139
+ value="5"
140
+ step="0.5"
141
+ min="0"
142
+ max="20"
143
+ label="Awesomeness"
144
+ default-value="10"
145
+ ></sp-slider>
146
+ <div id="styled-div">
147
+ The background of this div should be blue
148
+ </div>
149
+ <overlay-trigger id="inner-trigger" placement="bottom">
150
+ <sp-button slot="trigger">Press Me</sp-button>
151
+ <sp-popover slot="click-content" placement="bottom" tip>
152
+ <sp-dialog size="s" no-divider>
153
+ Another Popover
154
+ </sp-dialog>
155
+ </sp-popover>
156
+
157
+ <sp-tooltip slot="hover-content" delayed tip="bottom">
158
+ Click to open another popover.
159
+ </sp-tooltip>
160
+ </overlay-trigger>
161
+ </sp-dialog>
162
+ </sp-popover>
163
+ <sp-tooltip
164
+ slot="hover-content"
165
+ ?delayed=${open !== "hover"}
166
+ tip="bottom"
167
+ >
168
+ Click to open a popover.
169
+ </sp-tooltip>
170
+ </overlay-trigger>
171
+ `;
172
+ };
173
+ const extraText = html`
174
+ <p>This is some text.</p>
175
+ <p>This is some text.</p>
176
+ <p>
177
+ This is a
178
+ <a href="#anchor">link</a>
179
+ .
180
+ </p>
181
+ `;
182
+ function nextFrame() {
183
+ return new Promise((res) => requestAnimationFrame(() => res()));
184
+ }
185
+ export const Default = (args) => template(args);
186
+ export const accordion = () => {
187
+ return html`
188
+ <overlay-trigger type="modal" placement="top-start">
189
+ <style>
190
+ sp-button {
191
+ margin-top: 70vh;
192
+ }
193
+ </style>
194
+ <sp-button variant="primary" slot="trigger">
195
+ Open overlay w/ accordion
196
+ </sp-button>
197
+ <sp-popover
198
+ slot="click-content"
199
+ style="overflow-y: scroll;position: static;"
200
+ >
201
+ <sp-dialog size="s" no-divider>
202
+ <sp-accordion allow-multiple>
203
+ <sp-accordion-item label="Some things">
204
+ <p>
205
+ Thing
206
+ <br />
207
+ <br />
208
+ <br />
209
+ <br />
210
+ <br />
211
+ <br />
212
+ <br />
213
+ more things
214
+ </p>
215
+ </sp-accordion-item>
216
+ <sp-accordion-item label="Other things">
217
+ <p>
218
+ Thing
219
+ <br />
220
+ <br />
221
+ <br />
222
+ <br />
223
+ <br />
224
+ <br />
225
+ <br />
226
+ more things
227
+ </p>
228
+ </sp-accordion-item>
229
+ <sp-accordion-item label="More things">
230
+ <p>
231
+ Thing
232
+ <br />
233
+ <br />
234
+ <br />
235
+ <br />
236
+ <br />
237
+ <br />
238
+ <br />
239
+ more things
240
+ </p>
241
+ </sp-accordion-item>
242
+ <sp-accordion-item label="Additional things">
243
+ <p>
244
+ Thing
245
+ <br />
246
+ <br />
247
+ <br />
248
+ <br />
249
+ <br />
250
+ <br />
251
+ <br />
252
+ more things
253
+ </p>
254
+ </sp-accordion-item>
255
+ </sp-accordion>
256
+ </sp-dialog>
257
+ </sp-popover>
258
+ </overlay-trigger>
259
+ `;
260
+ };
261
+ accordion.swc_vrt = {
262
+ skip: true
263
+ };
264
+ export const clickAndHoverTargets = () => {
265
+ return html`
266
+ <div>
267
+ ${storyStyles}
268
+ <style>
269
+ .friendly-target {
270
+ padding: 4px;
271
+ margin: 6px;
272
+ border: 2px solid black;
273
+ border-radius: 6px;
274
+ cursor: default;
275
+ }
276
+ </style>
277
+ <overlay-trigger placement="right">
278
+ <div class="friendly-target" slot="trigger" tabindex="0">
279
+ Click me
280
+ </div>
281
+ <sp-tooltip slot="click-content" tip="right">
282
+ Ok, now hover the other trigger
283
+ </sp-tooltip>
284
+ </overlay-trigger>
285
+ <overlay-trigger placement="left">
286
+ <div class="friendly-target" slot="trigger" tabindex="0">
287
+ Then hover me
288
+ </div>
289
+ <sp-tooltip slot="hover-content" tip="right">
290
+ Now click my trigger -- I should stay open, but the other
291
+ overlay should close
292
+ </sp-tooltip>
293
+ </overlay-trigger>
294
+ </div>
295
+ `;
296
+ };
297
+ clickAndHoverTargets.swc_vrt = {
298
+ skip: true
299
+ };
300
+ class ScrollForcer extends HTMLElement {
301
+ constructor() {
302
+ super();
303
+ this.doScroll = async () => {
304
+ var _a;
305
+ (_a = this.previousElementSibling) == null ? void 0 : _a.addEventListener(
306
+ "sp-opened",
307
+ this.doScroll
308
+ );
309
+ await nextFrame();
310
+ await nextFrame();
311
+ await nextFrame();
312
+ await nextFrame();
313
+ if (document.scrollingElement) {
314
+ document.scrollingElement.scrollTop = 100;
315
+ }
316
+ await nextFrame();
317
+ await nextFrame();
318
+ this.ready(true);
319
+ };
320
+ this.readyPromise = Promise.resolve(false);
321
+ this.readyPromise = new Promise((res) => {
322
+ this.ready = res;
323
+ });
324
+ this.setup();
325
+ }
326
+ async setup() {
327
+ var _a, _b;
328
+ await nextFrame();
329
+ await nextFrame();
330
+ (_a = this.previousElementSibling) == null ? void 0 : _a.addEventListener(
331
+ "sp-opened",
332
+ this.doScroll
333
+ );
334
+ await nextFrame();
335
+ await nextFrame();
336
+ ((_b = this.previousElementSibling) == null ? void 0 : _b.lastElementChild).open = "click";
337
+ }
338
+ get updateComplete() {
339
+ return this.readyPromise;
340
+ }
341
+ }
342
+ customElements.define("scroll-forcer", ScrollForcer);
343
+ export const clickContentClosedOnScroll = (args) => html`
344
+ <div style="margin: 50vh 0 100vh;">
345
+ ${template({
346
+ ...args
347
+ })}
348
+ </div>
349
+ `;
350
+ clickContentClosedOnScroll.decorators = [
351
+ (story) => html`
352
+ <style>
353
+ html,
354
+ body,
355
+ #root,
356
+ #root-inner,
357
+ sp-story-decorator {
358
+ height: auto !important;
359
+ }
360
+ </style>
361
+ ${story()}
362
+ <scroll-forcer></scroll-forcer>
363
+ `
364
+ ];
365
+ class ComplexModalReady extends HTMLElement {
366
+ constructor() {
367
+ super();
368
+ this.handleTriggerOpened = async () => {
369
+ await nextFrame();
370
+ const picker = document.querySelector("#test-picker");
371
+ picker.addEventListener("sp-opened", this.handlePickerOpen);
372
+ picker.open = true;
373
+ };
374
+ this.handlePickerOpen = async () => {
375
+ const picker = document.querySelector("#test-picker");
376
+ const actions = [nextFrame, picker.updateComplete];
377
+ await Promise.all(actions);
378
+ this.ready(true);
379
+ };
380
+ this.readyPromise = Promise.resolve(false);
381
+ this.readyPromise = new Promise((res) => {
382
+ this.ready = res;
383
+ this.setup();
384
+ });
385
+ }
386
+ async setup() {
387
+ await nextFrame();
388
+ const overlay = document.querySelector(
389
+ `overlay-trigger`
390
+ );
391
+ overlay.addEventListener("sp-opened", this.handleTriggerOpened);
392
+ }
393
+ get updateComplete() {
394
+ return this.readyPromise;
395
+ }
396
+ }
397
+ customElements.define("complex-modal-ready", ComplexModalReady);
398
+ const complexModalDecorator = (story) => {
399
+ return html`
400
+ ${story()}
401
+ <complex-modal-ready></complex-modal-ready>
402
+ `;
403
+ };
404
+ export const complexModal = () => {
405
+ return html`
406
+ <style>
407
+ body {
408
+ --swc-margin-test: 10px;
409
+ margin: var(--swc-margin-test);
410
+ }
411
+ sp-story-decorator::part(container) {
412
+ min-height: calc(100vh - (2 * var(--swc-margin-test)));
413
+ padding: 0;
414
+ display: grid;
415
+ place-content: center;
416
+ }
417
+ active-overlay > * {
418
+ --spectrum-global-animation-duration-100: 0ms;
419
+ --spectrum-global-animation-duration-200: 0ms;
420
+ --spectrum-global-animation-duration-300: 0ms;
421
+ --spectrum-global-animation-duration-400: 0ms;
422
+ --spectrum-global-animation-duration-500: 0ms;
423
+ --spectrum-global-animation-duration-600: 0ms;
424
+ --spectrum-global-animation-duration-700: 0ms;
425
+ --spectrum-global-animation-duration-800: 0ms;
426
+ --spectrum-global-animation-duration-900: 0ms;
427
+ --spectrum-global-animation-duration-1000: 0ms;
428
+ --spectrum-global-animation-duration-2000: 0ms;
429
+ --spectrum-global-animation-duration-4000: 0ms;
430
+ --spectrum-animation-duration-0: 0ms;
431
+ --spectrum-animation-duration-100: 0ms;
432
+ --spectrum-animation-duration-200: 0ms;
433
+ --spectrum-animation-duration-300: 0ms;
434
+ --spectrum-animation-duration-400: 0ms;
435
+ --spectrum-animation-duration-500: 0ms;
436
+ --spectrum-animation-duration-600: 0ms;
437
+ --spectrum-animation-duration-700: 0ms;
438
+ --spectrum-animation-duration-800: 0ms;
439
+ --spectrum-animation-duration-900: 0ms;
440
+ --spectrum-animation-duration-1000: 0ms;
441
+ --spectrum-animation-duration-2000: 0ms;
442
+ --spectrum-animation-duration-4000: 0ms;
443
+ --spectrum-coachmark-animation-indicator-ring-duration: 0ms;
444
+ --swc-test-duration: 1ms;
445
+ }
446
+ </style>
447
+ <overlay-trigger type="modal" open="click">
448
+ <sp-dialog-wrapper
449
+ slot="click-content"
450
+ headline="Dialog title"
451
+ dismissable
452
+ underlay
453
+ footer="Content for footer"
454
+ >
455
+ <sp-field-label for="test-picker">
456
+ Selection type:
457
+ </sp-field-label>
458
+ <sp-picker id="test-picker">
459
+ <sp-menu-item>Deselect</sp-menu-item>
460
+ <sp-menu-item>Select inverse</sp-menu-item>
461
+ <sp-menu-item>Feather...</sp-menu-item>
462
+ <sp-menu-item>Select and mask...</sp-menu-item>
463
+ <sp-menu-divider></sp-menu-divider>
464
+ <sp-menu-item>Save selection</sp-menu-item>
465
+ <sp-menu-item disabled>Make work path</sp-menu-item>
466
+ </sp-picker>
467
+ </sp-dialog-wrapper>
468
+ <sp-button slot="trigger" variant="primary">
469
+ Toggle Dialog
470
+ </sp-button>
471
+ </overlay-trigger>
472
+ `;
473
+ };
474
+ complexModal.decorators = [complexModalDecorator];
475
+ export const customizedClickContent = (args) => html`
476
+ <style>
477
+ sp-popover {
478
+ --styled-div-background-color: var(
479
+ --spectrum-accent-background-color-default
480
+ );
481
+ --mod-button-background-color-default: rebeccapurple;
482
+ }
483
+ </style>
484
+ ${template({
485
+ ...args,
486
+ open: "click"
487
+ })}
488
+ `;
489
+ export const deep = () => html`
490
+ <overlay-trigger>
491
+ <sp-button variant="primary" slot="trigger">
492
+ Open popover 1 with buttons + selfmanaged Tooltips
493
+ </sp-button>
494
+ <sp-popover slot="click-content" direction="bottom" tip>
495
+ <sp-dialog size="s" no-divider>
496
+ <sp-action-button>
497
+ <sp-tooltip self-managed placement="bottom">
498
+ My Tooltip 1
499
+ </sp-tooltip>
500
+ A
501
+ </sp-action-button>
502
+ <sp-action-button>
503
+ <sp-tooltip self-managed placement="bottom">
504
+ My Tooltip 1
505
+ </sp-tooltip>
506
+ B
507
+ </sp-action-button>
508
+ </sp-dialog>
509
+ </sp-popover>
510
+ </overlay-trigger>
511
+
512
+ <overlay-trigger>
513
+ <sp-button variant="primary" slot="trigger">
514
+ Open popover 2 with buttons without ToolTips
515
+ </sp-button>
516
+ <sp-popover slot="click-content" direction="bottom" tip>
517
+ <sp-dialog size="s" no-divider>
518
+ <sp-action-button>X</sp-action-button>
519
+ <sp-action-button>Y</sp-action-button>
520
+ </sp-dialog>
521
+ </sp-popover>
522
+ </overlay-trigger>
523
+ `;
524
+ deep.swc_vrt = {
525
+ skip: true
526
+ };
527
+ export const deepChildTooltip = () => html`
528
+ <overlay-trigger>
529
+ <sp-button variant="primary" slot="trigger">Open popover</sp-button>
530
+ <sp-popover slot="click-content" direction="bottom" tip>
531
+ <sp-dialog no-divider>
532
+ <p>Let us open another overlay here</p>
533
+ <overlay-trigger>
534
+ <sp-button variant="primary" slot="trigger">
535
+ Open sub popover
536
+ </sp-button>
537
+ <sp-popover slot="click-content" direction="bottom" tip>
538
+ <sp-dialog no-divider>
539
+ <p>
540
+ Render an action button with tooltips. Clicking
541
+ the action button shouldn't close everything
542
+ </p>
543
+ <sp-action-button>
544
+ Button with self-managed tooltip
545
+ <sp-tooltip self-managed placement="top">
546
+ Deep Child ToolTip
547
+ </sp-tooltip>
548
+ </sp-action-button>
549
+ <sp-action-button>Just a button</sp-action-button>
550
+ </sp-dialog>
551
+ </sp-popover>
552
+ </overlay-trigger>
553
+ </sp-dialog>
554
+ </sp-popover>
555
+ </overlay-trigger>
556
+ `;
557
+ export const deepNesting = () => {
558
+ const color = window.__swc_hack_knobs__.defaultColor;
559
+ const outter = color === "light" ? "dark" : "light";
560
+ return html`
561
+ ${storyStyles}
562
+ <sp-theme
563
+ color=${outter}
564
+ system=${window.__swc_hack_knobs__.defaultSystemVariant}
565
+ scale=${window.__swc_hack_knobs__.defaultScale}
566
+ dir=${window.__swc_hack_knobs__.defaultDirection}
567
+ >
568
+ <sp-theme
569
+ color=${color}
570
+ system=${window.__swc_hack_knobs__.defaultSystemVariant}
571
+ scale=${window.__swc_hack_knobs__.defaultScale}
572
+ dir=${window.__swc_hack_knobs__.defaultDirection}
573
+ >
574
+ <recursive-popover
575
+ tabindex=""
576
+ style="
577
+ background-color: var(--spectrum-gray-100);
578
+ color: var(--spectrum-gray-800);
579
+ padding: calc(var(--swc-scale-factor) * 22px);
580
+ "
581
+ ></recursive-popover>
582
+ </sp-theme>
583
+ </sp-theme>
584
+ `;
585
+ };
586
+ class DefinedOverlayReady extends HTMLElement {
587
+ constructor() {
588
+ super(...arguments);
589
+ this.handleTriggerOpened = async () => {
590
+ this.overlayElement.removeEventListener(
591
+ "sp-opened",
592
+ this.handleTriggerOpened
593
+ );
594
+ await nextFrame();
595
+ await nextFrame();
596
+ await nextFrame();
597
+ await nextFrame();
598
+ this.popoverElement = document.querySelector(
599
+ "popover-content"
600
+ );
601
+ if (!this.popoverElement) {
602
+ return;
603
+ }
604
+ this.popoverElement.addEventListener(
605
+ "sp-opened",
606
+ this.handlePopoverOpen
607
+ );
608
+ await nextFrame();
609
+ await nextFrame();
610
+ this.popoverElement.button.click();
611
+ };
612
+ this.handlePopoverOpen = async () => {
613
+ await nextFrame();
614
+ this.ready(true);
615
+ };
616
+ this.readyPromise = Promise.resolve(false);
617
+ }
618
+ connectedCallback() {
619
+ if (!!this.ready) return;
620
+ this.readyPromise = new Promise((res) => {
621
+ this.ready = res;
622
+ this.setup();
623
+ });
624
+ }
625
+ async setup() {
626
+ await nextFrame();
627
+ await nextFrame();
628
+ this.overlayElement = document.querySelector(
629
+ `overlay-trigger`
630
+ );
631
+ const button = document.querySelector(
632
+ `[slot="trigger"]`
633
+ );
634
+ this.overlayElement.addEventListener(
635
+ "sp-opened",
636
+ this.handleTriggerOpened
637
+ );
638
+ await nextFrame();
639
+ await nextFrame();
640
+ button.click();
641
+ }
642
+ disconnectedCallback() {
643
+ this.overlayElement.removeEventListener(
644
+ "sp-opened",
645
+ this.handleTriggerOpened
646
+ );
647
+ this.popoverElement.removeEventListener(
648
+ "sp-opened",
649
+ this.handlePopoverOpen
650
+ );
651
+ }
652
+ get updateComplete() {
653
+ return this.readyPromise;
654
+ }
655
+ }
656
+ customElements.define("defined-overlay-ready", DefinedOverlayReady);
657
+ const definedOverlayDecorator = (story) => {
658
+ return html`
659
+ ${story()}
660
+ <defined-overlay-ready></defined-overlay-ready>
661
+ `;
662
+ };
663
+ export const definedOverlayElement = () => {
664
+ return html`
665
+ <overlay-trigger placement="bottom" type="modal">
666
+ <sp-button variant="primary" slot="trigger">Open popover</sp-button>
667
+ <sp-popover slot="click-content" direction="bottom">
668
+ <sp-dialog no-divider>
669
+ <popover-content></popover-content>
670
+ </sp-dialog>
671
+ </sp-popover>
672
+ </overlay-trigger>
673
+ `;
674
+ };
675
+ definedOverlayElement.decorators = [definedOverlayDecorator];
676
+ export const detachedElement = () => {
677
+ let overlay;
678
+ const openDetachedOverlayContent = async ({
679
+ target
680
+ }) => {
681
+ if (overlay) {
682
+ overlay.open = false;
683
+ overlay = void 0;
684
+ return;
685
+ }
686
+ const div = document.createElement("div");
687
+ div.open = false;
688
+ div.textContent = "This div is overlaid";
689
+ div.setAttribute(
690
+ "style",
691
+ `
692
+ background-color: var(--spectrum-gray-50);
693
+ color: var(--spectrum-gray-800);
694
+ border: 1px solid;
695
+ padding: 2em;
696
+ `
697
+ );
698
+ overlay = await Overlay.open(div, {
699
+ type: "auto",
700
+ trigger: target,
701
+ receivesFocus: "auto",
702
+ placement: "bottom",
703
+ offset: 0
704
+ });
705
+ overlay.addEventListener("sp-closed", () => {
706
+ overlay = void 0;
707
+ });
708
+ target.insertAdjacentElement("afterend", overlay);
709
+ };
710
+ requestAnimationFrame(() => {
711
+ openDetachedOverlayContent({
712
+ target: document.querySelector(
713
+ "#detached-content-trigger"
714
+ )
715
+ });
716
+ });
717
+ return html`
718
+ <style>
719
+ sp-overlay div:not([placement]) {
720
+ visibility: hidden;
721
+ }
722
+ </style>
723
+ <sp-action-button
724
+ id="detached-content-trigger"
725
+ @click=${openDetachedOverlayContent}
726
+ >
727
+ <sp-icon-open-in
728
+ slot="icon"
729
+ label="Open in overlay"
730
+ ></sp-icon-open-in>
731
+ </sp-action-button>
732
+ `;
733
+ };
734
+ export const edges = () => {
735
+ return html`
736
+ <style>
737
+ .demo {
738
+ position: absolute;
739
+ }
740
+ .top-left {
741
+ top: 0;
742
+ left: 0;
743
+ }
744
+ .top-right {
745
+ top: 0;
746
+ right: 0;
747
+ }
748
+ .bottom-right {
749
+ bottom: 0;
750
+ right: 0;
751
+ }
752
+ .bottom-left {
753
+ bottom: 0;
754
+ left: 0;
755
+ }
756
+ </style>
757
+ <overlay-trigger class="demo top-left" placement="bottom">
758
+ <sp-button slot="trigger">
759
+ Top/
760
+ <br />
761
+ Left
762
+ </sp-button>
763
+ <sp-tooltip slot="hover-content" delayed tip="bottom">
764
+ Triskaidekaphobia and More
765
+ </sp-tooltip>
766
+ </overlay-trigger>
767
+ <overlay-trigger class="demo top-right" placement="bottom">
768
+ <sp-button slot="trigger">
769
+ Top/
770
+ <br />
771
+ Right
772
+ </sp-button>
773
+ <sp-tooltip slot="hover-content" delayed tip="bottom">
774
+ Triskaidekaphobia and More
775
+ </sp-tooltip>
776
+ </overlay-trigger>
777
+ <overlay-trigger class="demo bottom-left" placement="top">
778
+ <sp-button slot="trigger">
779
+ Bottom/
780
+ <br />
781
+ Left
782
+ </sp-button>
783
+ <sp-tooltip slot="hover-content" delayed tip="top">
784
+ Triskaidekaphobia and More
785
+ </sp-tooltip>
786
+ </overlay-trigger>
787
+ <overlay-trigger placement="top" class="demo bottom-right">
788
+ <sp-button slot="trigger">
789
+ Bottom/
790
+ <br />
791
+ Right
792
+ </sp-button>
793
+ <sp-tooltip slot="hover-content" delayed tip="top">
794
+ Triskaidekaphobia and More
795
+ </sp-tooltip>
796
+ </overlay-trigger>
797
+ `;
798
+ };
799
+ export const inline = () => {
800
+ const closeEvent = new Event("close", { bubbles: true, composed: true });
801
+ return html`
802
+ <overlay-trigger type="inline">
803
+ <sp-button slot="trigger">Open</sp-button>
804
+ <sp-popover slot="click-content">
805
+ <sp-button
806
+ @click=${(event) => {
807
+ event.target.dispatchEvent(closeEvent);
808
+ }}
809
+ >
810
+ Close
811
+ </sp-button>
812
+ </sp-popover>
813
+ </overlay-trigger>
814
+ ${extraText}
815
+ `;
816
+ };
817
+ export const longpress = () => {
818
+ return html`
819
+ <overlay-trigger placement="right-start">
820
+ <sp-action-button slot="trigger" hold-affordance>
821
+ <sp-icon-magnify slot="icon"></sp-icon-magnify>
822
+ </sp-action-button>
823
+ <sp-tooltip slot="hover-content">Search real hard...</sp-tooltip>
824
+ <sp-popover slot="longpress-content" tip>
825
+ <sp-action-group
826
+ @change=${(event) => event.target.dispatchEvent(
827
+ new Event("close", { bubbles: true })
828
+ )}
829
+ selects="single"
830
+ vertical
831
+ style="margin: calc(var(--spectrum-actiongroup-button-gap-y,calc(var(--swc-scale-factor) * 10px)) / 2);"
832
+ >
833
+ <sp-action-button>
834
+ <sp-icon-magnify slot="icon"></sp-icon-magnify>
835
+ </sp-action-button>
836
+ <sp-action-button>
837
+ <sp-icon-magnify slot="icon"></sp-icon-magnify>
838
+ </sp-action-button>
839
+ <sp-action-button>
840
+ <sp-icon-magnify slot="icon"></sp-icon-magnify>
841
+ </sp-action-button>
842
+ </sp-action-group>
843
+ </sp-popover>
844
+ </overlay-trigger>
845
+ `;
846
+ };
847
+ export const modalLoose = () => {
848
+ const closeEvent = new Event("close", { bubbles: true, composed: true });
849
+ return html`
850
+ <overlay-trigger type="modal">
851
+ <sp-button slot="trigger">Open</sp-button>
852
+ <sp-dialog
853
+ size="s"
854
+ dismissable
855
+ slot="click-content"
856
+ @closed=${(event) => event.target.dispatchEvent(closeEvent)}
857
+ >
858
+ <h2 slot="heading">Loose Dialog</h2>
859
+ <p>
860
+ The
861
+ <code>sp-dialog</code>
862
+ element is not "meant" to be a modal alone. In that way it
863
+ does not manage its own
864
+ <code>open</code>
865
+ attribute or outline when it should have
866
+ <code>pointer-events: auto</code>
867
+ . It's a part of this test suite to prove that content in
868
+ this way can be used in an
869
+ <code>overlay-trigger</code>
870
+ element.
871
+ </p>
872
+ </sp-dialog>
873
+ </overlay-trigger>
874
+ ${extraText}
875
+ `;
876
+ };
877
+ export const modalNoFocus = () => {
878
+ const closeEvent = new Event("close", { bubbles: true, composed: true });
879
+ return html`
880
+ <overlay-trigger type="modal" receives-focus="false">
881
+ <sp-button slot="trigger">Open</sp-button>
882
+ <sp-dialog-wrapper
883
+ underlay
884
+ slot="click-content"
885
+ headline="Wrapped Dialog w/ Hero Image"
886
+ size="s"
887
+ >
888
+ <p>
889
+ The
890
+ <code>sp-dialog-wrapper</code>
891
+ element has been prepared for use in an
892
+ <code>overlay-trigger</code>
893
+ element by it's combination of modal, underlay, etc. styles
894
+ and features.
895
+ </p>
896
+ <sp-button-group style="margin-inline-start: auto">
897
+ <sp-button
898
+ data-test-id="dialog-cancel-btn"
899
+ variant="secondary"
900
+ treatment="outline"
901
+ size="l"
902
+ @click=${(event) => event.target.dispatchEvent(closeEvent)}
903
+ >
904
+ ${"Cancel"}
905
+ </sp-button>
906
+ <sp-button
907
+ data-test-id="dialog-override-btn"
908
+ variant="negative"
909
+ size="l"
910
+ @click=${(event) => event.target.dispatchEvent(closeEvent)}
911
+ >
912
+ ${"Override"}
913
+ </sp-button>
914
+ </sp-button-group>
915
+ </sp-dialog-wrapper>
916
+ </overlay-trigger>
917
+ `;
918
+ };
919
+ export const modalManaged = () => {
920
+ const closeEvent = new Event("close", { bubbles: true, composed: true });
921
+ return html`
922
+ <overlay-trigger type="modal">
923
+ <sp-button slot="trigger">Open</sp-button>
924
+ <sp-dialog-wrapper
925
+ underlay
926
+ slot="click-content"
927
+ headline="Wrapped Dialog w/ Hero Image"
928
+ confirm-label="Keep Both"
929
+ secondary-label="Replace"
930
+ cancel-label="Cancel"
931
+ footer="Content for footer"
932
+ @confirm=${(event) => {
933
+ event.target.dispatchEvent(closeEvent);
934
+ }}
935
+ @secondary=${(event) => {
936
+ event.target.dispatchEvent(closeEvent);
937
+ }}
938
+ @cancel=${(event) => {
939
+ event.target.dispatchEvent(closeEvent);
940
+ }}
941
+ >
942
+ <p>
943
+ The
944
+ <code>sp-dialog-wrapper</code>
945
+ element has been prepared for use in an
946
+ <code>overlay-trigger</code>
947
+ element by it's combination of modal, underlay, etc. styles
948
+ and features.
949
+ </p>
950
+ </sp-dialog-wrapper>
951
+ </overlay-trigger>
952
+ ${extraText}
953
+ `;
954
+ };
955
+ export const modalWithinNonModal = () => {
956
+ return html`
957
+ <overlay-trigger type="inline">
958
+ <sp-button variant="primary" slot="trigger">
959
+ Open inline overlay
960
+ </sp-button>
961
+ <sp-popover slot="click-content">
962
+ <sp-dialog size="s" no-divider>
963
+ <overlay-trigger type="modal">
964
+ <sp-button variant="primary" slot="trigger">
965
+ Open modal overlay
966
+ </sp-button>
967
+ <sp-popover slot="click-content">
968
+ <sp-dialog size="s" no-divider>
969
+ Modal overlay
970
+ </sp-dialog>
971
+ </sp-popover>
972
+ </overlay-trigger>
973
+ </sp-dialog>
974
+ </sp-popover>
975
+ </overlay-trigger>
976
+ `;
977
+ };
978
+ export const noCloseOnResize = (args) => html`
979
+ <style>
980
+ sp-button:hover {
981
+ border: 10px solid;
982
+ width: 100px;
983
+ }
984
+ </style>
985
+ ${template({
986
+ ...args,
987
+ open: "click"
988
+ })}
989
+ `;
990
+ noCloseOnResize.swc_vrt = {
991
+ skip: true
992
+ };
993
+ export const openClickContent = (args) => template({
994
+ ...args,
995
+ open: "click"
996
+ });
997
+ export const openHoverContent = (args) => template({
998
+ ...args,
999
+ open: "hover"
1000
+ });
1001
+ export const replace = () => {
1002
+ const closeEvent = new Event("close", { bubbles: true, composed: true });
1003
+ return html`
1004
+ <overlay-trigger type="replace">
1005
+ <sp-button slot="trigger">Open</sp-button>
1006
+ <sp-popover slot="click-content">
1007
+ <sp-button
1008
+ @click=${(event) => {
1009
+ event.target.dispatchEvent(closeEvent);
1010
+ }}
1011
+ >
1012
+ Close
1013
+ </sp-button>
1014
+ </sp-popover>
1015
+ </overlay-trigger>
1016
+ ${extraText}
1017
+ `;
1018
+ };
1019
+ export const sideHoverDraggable = () => {
1020
+ return html`
1021
+ ${storyStyles}
1022
+ <style>
1023
+ sp-tooltip {
1024
+ transition: none;
1025
+ }
1026
+ </style>
1027
+ <overlay-drag>
1028
+ <overlay-trigger placement="right">
1029
+ <overlay-target-icon slot="trigger"></overlay-target-icon>
1030
+ <sp-tooltip slot="hover-content" delayed tip="right">
1031
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
1032
+ Vivamus egestas sed enim sed condimentum. Nunc facilisis
1033
+ scelerisque massa sed luctus. Orci varius natoque penatibus
1034
+ et magnis dis parturient montes, nascetur ridiculus mus.
1035
+ Suspendisse sagittis sodales purus vitae ultricies. Integer
1036
+ at dui sem. Sed quam tortor, ornare in nisi et, rhoncus
1037
+ lacinia mauris. Sed vel rutrum mauris, ac pellentesque nibh.
1038
+ Sed feugiat semper libero, sit amet vehicula orci fermentum
1039
+ id. Vivamus imperdiet egestas luctus. Mauris tincidunt
1040
+ malesuada ante, faucibus viverra nunc blandit a. Fusce et
1041
+ nisl nisi. Aenean dictum quam id mollis faucibus. Nulla a
1042
+ ultricies dui. In hac habitasse platea dictumst. Curabitur
1043
+ gravida lobortis vestibulum.
1044
+ </sp-tooltip>
1045
+ </overlay-trigger>
1046
+ </overlay-drag>
1047
+ `;
1048
+ };
1049
+ export const superComplexModal = () => {
1050
+ return html`
1051
+ <overlay-trigger type="modal">
1052
+ <sp-button slot="trigger" variant="accent">Toggle Dialog</sp-button>
1053
+ <sp-popover slot="click-content">
1054
+ <sp-dialog size="s">
1055
+ <overlay-trigger>
1056
+ <sp-button slot="trigger" variant="primary">
1057
+ Toggle Dialog
1058
+ </sp-button>
1059
+ <sp-popover slot="click-content">
1060
+ <sp-dialog size="s" no-divider>
1061
+ <overlay-trigger type="modal">
1062
+ <sp-button
1063
+ slot="trigger"
1064
+ variant="secondary"
1065
+ >
1066
+ Toggle Dialog
1067
+ </sp-button>
1068
+ <sp-popover slot="click-content">
1069
+ <sp-dialog size="s" no-divider>
1070
+ <p>
1071
+ When you get this deep, this
1072
+ ActiveOverlay should be the only
1073
+ one in [slot="open"].
1074
+ </p>
1075
+ <p>
1076
+ All of the rest of the
1077
+ ActiveOverlay elements should
1078
+ have had their [slot] attribute
1079
+ removed.
1080
+ </p>
1081
+ <p>
1082
+ Closing this ActiveOverlay
1083
+ should replace them...
1084
+ </p>
1085
+ </sp-dialog>
1086
+ </sp-popover>
1087
+ </overlay-trigger>
1088
+ </sp-dialog>
1089
+ </sp-popover>
1090
+ </overlay-trigger>
1091
+ </sp-dialog>
1092
+ </sp-popover>
1093
+ </overlay-trigger>
1094
+ `;
1095
+ };
1096
+ export const updated = () => {
1097
+ return html`
1098
+ ${storyStyles}
1099
+ <style>
1100
+ sp-tooltip {
1101
+ transition: none;
1102
+ }
1103
+ </style>
1104
+ <overlay-drag>
1105
+ <overlay-trigger class="demo top-left" placement="bottom">
1106
+ <overlay-target-icon
1107
+ slot="trigger"
1108
+ style="translate(400px, 300px)"
1109
+ ></overlay-target-icon>
1110
+ <sp-tooltip slot="hover-content" delayed tip="bottom">
1111
+ Click to open popover
1112
+ </sp-tooltip>
1113
+ <sp-popover slot="click-content" position="bottom" tip>
1114
+ <sp-dialog size="s" no-divider>
1115
+ <sp-slider
1116
+ value="5"
1117
+ step="0.5"
1118
+ min="0"
1119
+ max="20"
1120
+ label="Awesomeness"
1121
+ ></sp-slider>
1122
+ <div id="styled-div">
1123
+ The background of this div should be blue
1124
+ </div>
1125
+ <overlay-trigger id="inner-trigger" placement="bottom">
1126
+ <sp-button slot="trigger">Press Me</sp-button>
1127
+ <sp-popover
1128
+ slot="click-content"
1129
+ placement="bottom"
1130
+ tip
1131
+ >
1132
+ <sp-dialog size="s" no-divider>
1133
+ Another Popover
1134
+ </sp-dialog>
1135
+ </sp-popover>
1136
+
1137
+ <sp-tooltip
1138
+ slot="hover-content"
1139
+ delayed
1140
+ tip="bottom"
1141
+ >
1142
+ Click to open another popover.
1143
+ </sp-tooltip>
1144
+ </overlay-trigger>
1145
+ </sp-dialog>
1146
+ </sp-popover>
1147
+ </overlay-trigger>
1148
+ </overlay-drag>
1149
+ `;
1150
+ };
1151
+ export const updating = () => {
1152
+ const update = () => {
1153
+ const button = document.querySelector('[slot="trigger"]');
1154
+ button.style.left = `${Math.floor(Math.random() * 200)}px`;
1155
+ button.style.top = `${Math.floor(Math.random() * 200)}px`;
1156
+ button.style.position = "fixed";
1157
+ };
1158
+ return html`
1159
+ <overlay-trigger type="click">
1160
+ <sp-button variant="primary" slot="trigger">
1161
+ Open inline overlay
1162
+ </sp-button>
1163
+ <sp-popover slot="click-content">
1164
+ <sp-dialog size="s" no-divider>
1165
+ <sp-button variant="primary" @click=${update}>
1166
+ Update trigger location.
1167
+ </sp-button>
1168
+ </sp-dialog>
1169
+ </sp-popover>
1170
+ </overlay-trigger>
1171
+ `;
1172
+ };
1173
+ updating.swc_vrt = {
1174
+ skip: true
1175
+ };
1176
+ class StartEndContextmenu extends HTMLElement {
1177
+ constructor() {
1178
+ super();
1179
+ this.attachShadow({ mode: "open" });
1180
+ this.shadowRoot.innerHTML = `
1181
+ <style>
1182
+ :host {
1183
+ display: flex;
1184
+ align-items: stretch;
1185
+ }
1186
+ div {
1187
+ width: 50%;
1188
+ height: 100%;
1189
+ }
1190
+ </style>
1191
+ <div id="start"></div>
1192
+ <div id="end"></div>
1193
+ `;
1194
+ }
1195
+ }
1196
+ customElements.define("start-end-contextmenu", StartEndContextmenu);
1197
+ export const virtualElementV1 = (args) => {
1198
+ const contextMenuTemplate = (kind = "") => html`
1199
+ <sp-popover
1200
+ style="width:300px;"
1201
+ @click=${(event) => {
1202
+ var _a;
1203
+ if (event.target.localName === "sp-menu-item") {
1204
+ (_a = event.target) == null ? void 0 : _a.dispatchEvent(
1205
+ new Event("close", { bubbles: true })
1206
+ );
1207
+ }
1208
+ }}
1209
+ >
1210
+ <sp-menu>
1211
+ <sp-menu-group>
1212
+ <span slot="header">Menu source: ${kind}</span>
1213
+ <sp-menu-item>Deselect</sp-menu-item>
1214
+ <sp-menu-item>Select inverse</sp-menu-item>
1215
+ <sp-menu-item>Feather...</sp-menu-item>
1216
+ <sp-menu-item>Select and mask...</sp-menu-item>
1217
+ <sp-menu-divider></sp-menu-divider>
1218
+ <sp-menu-item>Save selection</sp-menu-item>
1219
+ <sp-menu-item disabled>Make work path</sp-menu-item>
1220
+ </sp-menu-group>
1221
+ </sp-menu>
1222
+ </sp-popover>
1223
+ `;
1224
+ const handleContextmenu = async (event) => {
1225
+ event.preventDefault();
1226
+ event.stopPropagation();
1227
+ const source = event.composedPath()[0];
1228
+ const { id } = source;
1229
+ const trigger = event.target;
1230
+ const virtualTrigger = new VirtualTrigger(event.clientX, event.clientY);
1231
+ const fragment = document.createDocumentFragment();
1232
+ render(contextMenuTemplate(id), fragment);
1233
+ const popover = fragment.querySelector("sp-popover");
1234
+ openOverlay(trigger, "click", popover, {
1235
+ placement: args.placement,
1236
+ receivesFocus: "auto",
1237
+ virtualTrigger,
1238
+ offset: 0,
1239
+ notImmediatelyClosable: true
1240
+ });
1241
+ };
1242
+ return html`
1243
+ <style>
1244
+ .app-root {
1245
+ position: absolute;
1246
+ inset: 0;
1247
+ }
1248
+ </style>
1249
+ <start-end-contextmenu
1250
+ class="app-root"
1251
+ @contextmenu=${{
1252
+ capture: true,
1253
+ handleEvent: handleContextmenu
1254
+ }}
1255
+ ></start-end-contextmenu>
1256
+ `;
1257
+ };
1258
+ virtualElementV1.args = {
1259
+ placement: "right-start"
1260
+ };
1261
+ export const virtualElement = (args) => {
1262
+ const contextMenuTemplate = (kind = "") => html`
1263
+ <sp-popover
1264
+ style="width:300px;"
1265
+ @click=${(event) => {
1266
+ var _a;
1267
+ if (event.target.localName === "sp-menu-item") {
1268
+ (_a = event.target) == null ? void 0 : _a.dispatchEvent(
1269
+ new Event("close", { bubbles: true })
1270
+ );
1271
+ }
1272
+ }}
1273
+ >
1274
+ <sp-menu>
1275
+ <sp-menu-group>
1276
+ <span slot="header">Menu source: ${kind}</span>
1277
+ <sp-menu-item>Deselect</sp-menu-item>
1278
+ <sp-menu-item>Select inverse</sp-menu-item>
1279
+ <sp-menu-item>Feather...</sp-menu-item>
1280
+ <sp-menu-item>Select and mask...</sp-menu-item>
1281
+ <sp-menu-divider></sp-menu-divider>
1282
+ <sp-menu-item>Save selection</sp-menu-item>
1283
+ <sp-menu-item disabled>Make work path</sp-menu-item>
1284
+ </sp-menu-group>
1285
+ </sp-menu>
1286
+ </sp-popover>
1287
+ `;
1288
+ const handleContextmenu = async (event) => {
1289
+ event.preventDefault();
1290
+ event.stopPropagation();
1291
+ const source = event.composedPath()[0];
1292
+ const { id } = source;
1293
+ const trigger = event.target;
1294
+ const virtualTrigger = new VirtualTrigger(event.clientX, event.clientY);
1295
+ const fragment = document.createDocumentFragment();
1296
+ render(contextMenuTemplate(id), fragment);
1297
+ const popover = fragment.querySelector("sp-popover");
1298
+ const overlay = await openOverlay(popover, {
1299
+ trigger: virtualTrigger,
1300
+ placement: args.placement,
1301
+ offset: 0,
1302
+ notImmediatelyClosable: true,
1303
+ type: "auto"
1304
+ });
1305
+ trigger.insertAdjacentElement("afterend", overlay);
1306
+ };
1307
+ return html`
1308
+ <style>
1309
+ .app-root {
1310
+ position: absolute;
1311
+ inset: 0;
1312
+ }
1313
+ </style>
1314
+ <start-end-contextmenu
1315
+ class="app-root"
1316
+ @contextmenu=${{
1317
+ capture: true,
1318
+ handleEvent: handleContextmenu
1319
+ }}
1320
+ ></start-end-contextmenu>
1321
+ `;
1322
+ };
1323
+ virtualElement.args = {
1324
+ placement: "right-start"
1325
+ };
1326
+ export const virtualElementDeclaratively = (args) => {
1327
+ const handleContextmenu = async (event) => {
1328
+ event.preventDefault();
1329
+ event.stopPropagation();
1330
+ const overlay2 = document.querySelector(
1331
+ "sp-overlay:not([open])"
1332
+ );
1333
+ if (overlay2.triggerElement instanceof VirtualTrigger) {
1334
+ overlay2.triggerElement.updateBoundingClientRect(
1335
+ event.clientX,
1336
+ event.clientY
1337
+ );
1338
+ }
1339
+ overlay2.willPreventClose = true;
1340
+ overlay2.open = true;
1341
+ };
1342
+ const overlay = () => html`
1343
+ <sp-overlay
1344
+ offset="0"
1345
+ type="auto"
1346
+ placement=${args.placement}
1347
+ .triggerElement=${new VirtualTrigger(0, 0)}
1348
+ >
1349
+ <sp-popover
1350
+ style="width:300px;"
1351
+ @change=${(event) => {
1352
+ var _a;
1353
+ (_a = event.target) == null ? void 0 : _a.dispatchEvent(
1354
+ new Event("close", { bubbles: true })
1355
+ );
1356
+ }}
1357
+ >
1358
+ <sp-menu>
1359
+ <sp-menu-group>
1360
+ <span slot="header">Menu</span>
1361
+ <sp-menu-item>Deselect</sp-menu-item>
1362
+ <sp-menu-item>Select inverse</sp-menu-item>
1363
+ <sp-menu-item>Feather...</sp-menu-item>
1364
+ <sp-menu-item>Select and mask...</sp-menu-item>
1365
+ <sp-menu-divider></sp-menu-divider>
1366
+ <sp-menu-item>Save selection</sp-menu-item>
1367
+ <sp-menu-item disabled>Make work path</sp-menu-item>
1368
+ </sp-menu-group>
1369
+ </sp-menu>
1370
+ </sp-popover>
1371
+ </sp-overlay>
1372
+ `;
1373
+ return html`
1374
+ <style>
1375
+ .app-root {
1376
+ position: absolute;
1377
+ inset: 0;
1378
+ }
1379
+ </style>
1380
+ <div
1381
+ class="app-root"
1382
+ @contextmenu=${{
1383
+ capture: true,
1384
+ handleEvent: handleContextmenu
1385
+ }}
1386
+ >
1387
+ ${overlay()} ${overlay()}
1388
+ </div>
1389
+ `;
1390
+ };
1391
+ virtualElementDeclaratively.args = {
1392
+ placement: "right-start"
1393
+ };
1394
+ virtualElementDeclaratively.swc_vrt = {
1395
+ skip: true
1396
+ };
1397
+ //# sourceMappingURL=overlay.stories.js.map