@spectrum-web-components/menu 0.31.1-overlay.29 → 0.31.1-react.21

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.
@@ -2,7 +2,6 @@
2
2
  import "@spectrum-web-components/menu/sp-menu.js";
3
3
  import "@spectrum-web-components/menu/sp-menu-item.js";
4
4
  import {
5
- aTimeout,
6
5
  elementUpdated,
7
6
  expect,
8
7
  fixture,
@@ -20,40 +19,7 @@ import "@spectrum-web-components/menu/sp-menu-group.js";
20
19
  import "@spectrum-web-components/icons-workflow/icons/sp-icon-show-menu.js";
21
20
  async function styledFixture(story, dir = "ltr") {
22
21
  const test = await fixture(html`
23
- <sp-theme dir=${dir} scale="medium" color="dark">
24
- ${story}
25
- <style>
26
- sp-theme {
27
- --spectrum-global-animation-duration-100: 50ms;
28
- --spectrum-global-animation-duration-200: 50ms;
29
- --spectrum-global-animation-duration-300: 50ms;
30
- --spectrum-global-animation-duration-400: 50ms;
31
- --spectrum-global-animation-duration-500: 50ms;
32
- --spectrum-global-animation-duration-600: 50ms;
33
- --spectrum-global-animation-duration-700: 50ms;
34
- --spectrum-global-animation-duration-800: 50ms;
35
- --spectrum-global-animation-duration-900: 50ms;
36
- --spectrum-global-animation-duration-1000: 50ms;
37
- --spectrum-global-animation-duration-2000: 50ms;
38
- --spectrum-global-animation-duration-4000: 50ms;
39
- --spectrum-animation-duration-0: 50ms;
40
- --spectrum-animation-duration-100: 50ms;
41
- --spectrum-animation-duration-200: 50ms;
42
- --spectrum-animation-duration-300: 50ms;
43
- --spectrum-animation-duration-400: 50ms;
44
- --spectrum-animation-duration-500: 50ms;
45
- --spectrum-animation-duration-600: 50ms;
46
- --spectrum-animation-duration-700: 50ms;
47
- --spectrum-animation-duration-800: 50ms;
48
- --spectrum-animation-duration-900: 50ms;
49
- --spectrum-animation-duration-1000: 50ms;
50
- --spectrum-animation-duration-2000: 50ms;
51
- --spectrum-animation-duration-4000: 50ms;
52
- --spectrum-coachmark-animation-indicator-ring-duration: 50ms;
53
- --swc-test-duration: 1ms;
54
- }
55
- </style>
56
- </sp-theme>
22
+ <sp-theme dir=${dir} scale="medium" color="dark">${story}</sp-theme>
57
23
  `);
58
24
  document.documentElement.dir = dir;
59
25
  return test.children[0];
@@ -124,8 +90,9 @@ describe("Submenu", () => {
124
90
  ]
125
91
  });
126
92
  await closed;
127
- expect(submenuChanged.withArgs("Two").calledOnce, "submenu changed").to.be.true;
128
- expect(rootChanged.withArgs("Has submenu").calledOnce, "root changed").to.be.true;
93
+ await nextFrame();
94
+ expect(rootChanged.calledWith("Has submenu"), "root changed").to.be.true;
95
+ expect(submenuChanged.calledWith("Two"), "submenu changed").to.be.true;
129
96
  });
130
97
  it("closes deep tree on selection", async () => {
131
98
  const rootChanged = spy();
@@ -176,12 +143,11 @@ describe("Submenu", () => {
176
143
  </sp-menu>
177
144
  `
178
145
  );
146
+ await elementUpdated(el);
179
147
  const rootItem = el.querySelector(".root");
180
148
  const rootItemBoundingRect = rootItem.getBoundingClientRect();
181
- const item2 = document.querySelector(".submenu-item-2");
182
- const itemC = document.querySelector(".sub-submenu-item-3");
183
149
  expect(rootItem.open).to.be.false;
184
- let opened = oneEvent(rootItem, "sp-opened");
150
+ const opened = oneEvent(rootItem, "sp-opened");
185
151
  sendMouse({
186
152
  steps: [
187
153
  {
@@ -195,8 +161,9 @@ describe("Submenu", () => {
195
161
  });
196
162
  await opened;
197
163
  expect(rootItem.open).to.be.true;
164
+ const item2 = document.querySelector(".submenu-item-2");
198
165
  const item2BoundingRect = item2.getBoundingClientRect();
199
- opened = oneEvent(item2, "sp-opened");
166
+ let closed = oneEvent(item2, "sp-opened");
200
167
  sendMouse({
201
168
  steps: [
202
169
  {
@@ -208,11 +175,25 @@ describe("Submenu", () => {
208
175
  }
209
176
  ]
210
177
  });
211
- await opened;
178
+ await closed;
179
+ await nextFrame();
212
180
  expect(item2.open).to.be.true;
213
- const closed = oneEvent(rootItem, "sp-closed");
214
- itemC.click();
181
+ const itemC = document.querySelector(".sub-submenu-item-3");
182
+ const itemCBoundingRect = itemC.getBoundingClientRect();
183
+ closed = oneEvent(rootItem, "sp-closed");
184
+ sendMouse({
185
+ steps: [
186
+ {
187
+ type: "click",
188
+ position: [
189
+ itemCBoundingRect.left + itemCBoundingRect.width / 2,
190
+ itemCBoundingRect.top + itemCBoundingRect.height / 2
191
+ ]
192
+ }
193
+ ]
194
+ });
215
195
  await closed;
196
+ await nextFrame();
216
197
  expect(rootChanged.calledWith("Has submenu"), "root changed").to.be.true;
217
198
  expect(submenuChanged.calledWith("Two"), "submenu changed").to.be.true;
218
199
  expect(subSubmenuChanged.calledWith("C"), "sub submenu changed").to.be.true;
@@ -230,13 +211,11 @@ describe("Submenu", () => {
230
211
  }
231
212
  ].map((testData) => {
232
213
  it(`selects - keyboard: ${testData.dir}`, async () => {
233
- var _a, _b;
234
214
  const rootChanged = spy();
235
215
  const submenuChanged = spy();
236
216
  const el = await styledFixture(
237
217
  html`
238
218
  <sp-menu
239
- id="base"
240
219
  @change=${(event) => {
241
220
  rootChanged(event.target.value);
242
221
  }}
@@ -244,7 +223,6 @@ describe("Submenu", () => {
244
223
  <sp-menu-item class="root">
245
224
  Has submenu
246
225
  <sp-menu
247
- id="sub"
248
226
  slot="submenu"
249
227
  @change=${(event) => {
250
228
  submenuChanged(event.target.value);
@@ -267,7 +245,6 @@ describe("Submenu", () => {
267
245
  );
268
246
  await elementUpdated(el);
269
247
  const rootItem = el.querySelector(".root");
270
- const submenu = el.querySelector('[slot="submenu"]');
271
248
  expect(rootItem.open).to.be.false;
272
249
  el.focus();
273
250
  await elementUpdated(el);
@@ -277,20 +254,12 @@ describe("Submenu", () => {
277
254
  });
278
255
  await opened;
279
256
  expect(rootItem.open).to.be.true;
280
- expect(
281
- submenu === document.activeElement,
282
- `${(_a = document.activeElement) == null ? void 0 : _a.id}`
283
- ).to.be.true;
284
257
  let closed = oneEvent(rootItem, "sp-closed");
285
258
  sendKeys({
286
259
  press: testData.closeKey
287
260
  });
288
261
  await closed;
289
262
  expect(rootItem.open).to.be.false;
290
- expect(
291
- el === document.activeElement,
292
- `${(_b = document.activeElement) == null ? void 0 : _b.id}`
293
- ).to.be.true;
294
263
  opened = oneEvent(rootItem, "sp-opened");
295
264
  sendKeys({
296
265
  press: testData.openKey
@@ -305,12 +274,8 @@ describe("Submenu", () => {
305
274
  press: "Enter"
306
275
  });
307
276
  await closed;
277
+ expect(rootChanged.calledWith("Has submenu"), "root changed").to.be.true;
308
278
  expect(submenuChanged.calledWith("Two"), "submenu changed").to.be.true;
309
- expect(rootChanged.called, "root has changed").to.be.true;
310
- expect(
311
- rootChanged.calledWith("Has submenu"),
312
- "root specifically changed"
313
- ).to.be.true;
314
279
  });
315
280
  });
316
281
  it("closes on `pointerleave`", async () => {
@@ -442,8 +407,7 @@ describe("Submenu", () => {
442
407
  });
443
408
  await closed;
444
409
  });
445
- it("continues to open when mousing between menu item and submenu", async () => {
446
- const clickSpy = spy();
410
+ it("stays open when mousing between menu item and submenu", async () => {
447
411
  const el = await styledFixture(
448
412
  html`
449
413
  <sp-menu>
@@ -453,10 +417,7 @@ describe("Submenu", () => {
453
417
  <sp-menu-item class="submenu-item-1">
454
418
  One
455
419
  </sp-menu-item>
456
- <sp-menu-item
457
- class="submenu-item-2"
458
- @click=${() => clickSpy()}
459
- >
420
+ <sp-menu-item class="submenu-item-2">
460
421
  Two
461
422
  </sp-menu-item>
462
423
  <sp-menu-item class="submenu-item-3">
@@ -469,7 +430,6 @@ describe("Submenu", () => {
469
430
  );
470
431
  await elementUpdated(el);
471
432
  const rootItem = el.querySelector(".root");
472
- const subItem = el.querySelector(".submenu-item-2");
473
433
  const rootItemBoundingRect = rootItem.getBoundingClientRect();
474
434
  expect(rootItem.open).to.be.false;
475
435
  const opened = oneEvent(rootItem, "sp-opened");
@@ -484,114 +444,30 @@ describe("Submenu", () => {
484
444
  }
485
445
  ]
486
446
  });
487
- await nextFrame();
488
- await nextFrame();
489
- const subItemBoundingRect = subItem.getBoundingClientRect();
490
447
  await sendMouse({
491
448
  steps: [
492
449
  {
493
450
  type: "move",
494
451
  position: [
495
- subItemBoundingRect.left + subItemBoundingRect.width / 2,
496
- subItemBoundingRect.top + subItemBoundingRect.height / 2
497
- ]
498
- }
499
- ]
500
- });
501
- await opened;
502
- expect(rootItem.open).to.be.true;
503
- await aTimeout(150);
504
- expect(rootItem.open).to.be.true;
505
- const closed = oneEvent(rootItem, "sp-closed");
506
- sendMouse({
507
- steps: [
508
- {
509
- type: "click",
510
- position: [
511
- subItemBoundingRect.left + subItemBoundingRect.width / 2,
512
- subItemBoundingRect.top + subItemBoundingRect.height / 2
452
+ rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
453
+ rootItemBoundingRect.top + rootItemBoundingRect.height * 2
513
454
  ]
514
455
  }
515
456
  ]
516
457
  });
517
- await closed;
518
- expect(clickSpy.callCount).to.equal(1);
519
- });
520
- it("stays open when mousing between menu item and submenu", async () => {
521
- const clickSpy = spy();
522
- const el = await styledFixture(
523
- html`
524
- <sp-menu>
525
- <sp-menu-item class="root">
526
- Has submenu
527
- <sp-menu slot="submenu">
528
- <sp-menu-item class="submenu-item-1">
529
- One
530
- </sp-menu-item>
531
- <sp-menu-item
532
- class="submenu-item-2"
533
- @click=${() => clickSpy()}
534
- >
535
- Two
536
- </sp-menu-item>
537
- <sp-menu-item class="submenu-item-3">
538
- Three
539
- </sp-menu-item>
540
- </sp-menu>
541
- </sp-menu-item>
542
- </sp-menu>
543
- `
544
- );
545
- await elementUpdated(el);
546
- const rootItem = el.querySelector(".root");
547
- const subItem = el.querySelector(".submenu-item-2");
548
- const rootItemBoundingRect = rootItem.getBoundingClientRect();
549
- expect(rootItem.open).to.be.false;
550
- const opened = oneEvent(rootItem, "sp-opened");
551
458
  await sendMouse({
552
459
  steps: [
553
460
  {
554
461
  type: "move",
555
462
  position: [
556
- rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
463
+ rootItemBoundingRect.left + rootItemBoundingRect.width * 1.5,
557
464
  rootItemBoundingRect.top + rootItemBoundingRect.height / 2
558
465
  ]
559
466
  }
560
467
  ]
561
468
  });
562
469
  await opened;
563
- await nextFrame();
564
- await nextFrame();
565
- const subItemBoundingRect = subItem.getBoundingClientRect();
566
- expect(rootItem.open).to.be.true;
567
- await sendMouse({
568
- steps: [
569
- {
570
- type: "move",
571
- position: [
572
- subItemBoundingRect.left + subItemBoundingRect.width / 2,
573
- subItemBoundingRect.top + subItemBoundingRect.height / 2
574
- ]
575
- }
576
- ]
577
- });
578
- expect(rootItem.open).to.be.true;
579
- await aTimeout(150);
580
470
  expect(rootItem.open).to.be.true;
581
- const closed = oneEvent(rootItem, "sp-closed");
582
- sendMouse({
583
- steps: [
584
- {
585
- type: "click",
586
- position: [
587
- subItemBoundingRect.left + subItemBoundingRect.width / 2,
588
- subItemBoundingRect.top + subItemBoundingRect.height / 2
589
- ]
590
- }
591
- ]
592
- });
593
- await closed;
594
- expect(clickSpy.callCount).to.equal(1);
595
471
  });
596
472
  it("not opens if disabled", async () => {
597
473
  const el = await styledFixture(
@@ -636,15 +512,15 @@ describe("Submenu", () => {
636
512
  const el = await styledFixture(html`
637
513
  <sp-action-menu>
638
514
  <sp-icon-show-menu slot="icon"></sp-icon-show-menu>
639
- <sp-menu-group role="none" id="group">
515
+ <sp-menu-group role="none">
640
516
  <span slot="header">New York</span>
641
517
  <sp-menu-item>Bronx</sp-menu-item>
642
518
  <sp-menu-item id="submenu-item-1">
643
519
  Brooklyn
644
- <sp-menu slot="submenu" id="submenu-1">
520
+ <sp-menu slot="submenu">
645
521
  <sp-menu-item id="submenu-item-2">
646
522
  Ft. Greene
647
- <sp-menu slot="submenu" id="submenu-2">
523
+ <sp-menu slot="submenu">
648
524
  <sp-menu-item>S. Oxford St</sp-menu-item>
649
525
  <sp-menu-item>S. Portland Ave</sp-menu-item>
650
526
  <sp-menu-item>S. Elliot Pl</sp-menu-item>
@@ -656,7 +532,7 @@ describe("Submenu", () => {
656
532
  </sp-menu-item>
657
533
  <sp-menu-item id="submenu-item-3">
658
534
  Manhattan
659
- <sp-menu slot="submenu" id="submenu-3">
535
+ <sp-menu slot="submenu">
660
536
  <sp-menu-item disabled>SoHo</sp-menu-item>
661
537
  <sp-menu-item>
662
538
  Union Square
@@ -680,27 +556,33 @@ describe("Submenu", () => {
680
556
  el.click();
681
557
  await opened;
682
558
  expect(el.open).to.be.true;
559
+ let activeOverlays = document.querySelectorAll("active-overlay");
560
+ expect(activeOverlays.length).to.equal(1);
683
561
  opened = oneEvent(rootMenu1, "sp-opened");
684
562
  rootMenu1.dispatchEvent(
685
563
  new PointerEvent("pointerenter", { bubbles: true })
686
564
  );
687
565
  await opened;
688
- expect(rootMenu1.open).to.be.true;
566
+ activeOverlays = document.querySelectorAll("active-overlay");
567
+ expect(activeOverlays.length).to.equal(2);
689
568
  opened = oneEvent(childMenu2, "sp-opened");
690
569
  childMenu2.dispatchEvent(
691
570
  new PointerEvent("pointerenter", { bubbles: true })
692
571
  );
693
572
  await opened;
694
- expect(childMenu2.open).to.be.true;
695
- const childMenu2Closed = oneEvent(childMenu2, "sp-closed");
696
- const rootMenu1Closed = oneEvent(rootMenu1, "sp-closed");
697
- const rootMenu2Opened = oneEvent(rootMenu2, "sp-opened");
573
+ activeOverlays = document.querySelectorAll("active-overlay");
574
+ expect(activeOverlays.length).to.equal(3);
575
+ const overlaysManaged = Promise.all([
576
+ oneEvent(childMenu2, "sp-closed"),
577
+ oneEvent(rootMenu1, "sp-closed"),
578
+ oneEvent(rootMenu2, "sp-opened")
579
+ ]);
698
580
  rootMenu2.dispatchEvent(
699
581
  new PointerEvent("pointerenter", { bubbles: true })
700
582
  );
701
- await childMenu2Closed;
702
- await rootMenu1Closed;
703
- await rootMenu2Opened;
583
+ await overlaysManaged;
584
+ activeOverlays = document.querySelectorAll("active-overlay");
585
+ expect(activeOverlays.length).to.equal(2);
704
586
  });
705
587
  it("closes back to the first overlay without a `root` when clicking away", async () => {
706
588
  const el = await styledFixture(html`
@@ -749,30 +631,31 @@ describe("Submenu", () => {
749
631
  el.click();
750
632
  await opened;
751
633
  expect(el.open).to.be.true;
634
+ let activeOverlays = document.querySelectorAll("active-overlay");
635
+ expect(activeOverlays.length).to.equal(1);
752
636
  opened = oneEvent(rootMenu1, "sp-opened");
753
637
  rootMenu1.dispatchEvent(
754
638
  new PointerEvent("pointerenter", { bubbles: true })
755
639
  );
756
640
  await opened;
641
+ activeOverlays = document.querySelectorAll("active-overlay");
642
+ expect(activeOverlays.length).to.equal(2);
757
643
  opened = oneEvent(childMenu2, "sp-opened");
758
644
  childMenu2.dispatchEvent(
759
645
  new PointerEvent("pointerenter", { bubbles: true })
760
646
  );
761
647
  await opened;
648
+ activeOverlays = document.querySelectorAll("active-overlay");
649
+ expect(activeOverlays.length).to.equal(3);
762
650
  const closed = Promise.all([
763
651
  oneEvent(childMenu2, "sp-closed"),
764
652
  oneEvent(rootMenu1, "sp-closed"),
765
653
  oneEvent(el, "sp-closed")
766
654
  ]);
767
- sendMouse({
768
- steps: [
769
- {
770
- type: "click",
771
- position: [600, 5]
772
- }
773
- ]
774
- });
655
+ document.body.click();
775
656
  await closed;
657
+ activeOverlays = document.querySelectorAll("active-overlay");
658
+ expect(activeOverlays.length).to.equal(0);
776
659
  });
777
660
  it("closes decendent menus when Menu Item in ancestor without a submenu is pointerentered", async () => {
778
661
  const el = await styledFixture(html`
@@ -811,16 +694,22 @@ describe("Submenu", () => {
811
694
  el.click();
812
695
  await opened;
813
696
  expect(el.open).to.be.true;
697
+ let activeOverlays = document.querySelectorAll("active-overlay");
698
+ expect(activeOverlays.length).to.equal(1);
814
699
  opened = oneEvent(rootMenu, "sp-opened");
815
700
  rootMenu.dispatchEvent(
816
701
  new PointerEvent("pointerenter", { bubbles: true })
817
702
  );
818
703
  await opened;
704
+ activeOverlays = document.querySelectorAll("active-overlay");
705
+ expect(activeOverlays.length).to.equal(2);
819
706
  const closed = oneEvent(rootMenu, "sp-closed");
820
707
  noSubmenu.dispatchEvent(
821
708
  new PointerEvent("pointerenter", { bubbles: true })
822
709
  );
823
710
  await closed;
711
+ activeOverlays = document.querySelectorAll("active-overlay");
712
+ expect(activeOverlays.length).to.equal(1);
824
713
  });
825
714
  it("closes decendent menus when Menu Item in ancestor is clicked", async () => {
826
715
  const el = await styledFixture(html`
@@ -864,7 +753,6 @@ describe("Submenu", () => {
864
753
  </sp-menu-group>
865
754
  </sp-action-menu>
866
755
  `);
867
- await nextFrame();
868
756
  const rootMenu1 = el.querySelector("#submenu-item-1");
869
757
  const childMenu2 = el.querySelector("#submenu-item-2");
870
758
  const ancestorItem = el.querySelector("#ancestor-item");
@@ -873,39 +761,33 @@ describe("Submenu", () => {
873
761
  el.click();
874
762
  await opened;
875
763
  expect(el.open).to.be.true;
764
+ let activeOverlays = document.querySelectorAll("active-overlay");
765
+ expect(activeOverlays.length).to.equal(1);
876
766
  opened = oneEvent(rootMenu1, "sp-opened");
877
767
  rootMenu1.dispatchEvent(
878
768
  new PointerEvent("pointerenter", { bubbles: true })
879
769
  );
880
770
  await opened;
771
+ activeOverlays = document.querySelectorAll("active-overlay");
772
+ expect(activeOverlays.length).to.equal(2);
881
773
  opened = oneEvent(childMenu2, "sp-opened");
882
774
  childMenu2.dispatchEvent(
883
775
  new PointerEvent("pointerenter", { bubbles: true })
884
776
  );
885
777
  await opened;
778
+ activeOverlays = document.querySelectorAll("active-overlay");
779
+ expect(activeOverlays.length).to.equal(3);
886
780
  const closed = Promise.all([
887
781
  oneEvent(childMenu2, "sp-closed"),
888
782
  oneEvent(rootMenu1, "sp-closed"),
889
783
  oneEvent(el, "sp-closed")
890
784
  ]);
891
- const rect = ancestorItem.getBoundingClientRect();
892
- await sendMouse({
893
- steps: [
894
- {
895
- type: "click",
896
- position: [
897
- rect.left + rect.width / 2,
898
- rect.top + rect.height / 2
899
- ]
900
- }
901
- ]
902
- });
785
+ ancestorItem.click();
903
786
  await closed;
787
+ activeOverlays = document.querySelectorAll("active-overlay");
788
+ expect(activeOverlays.length).to.equal(0);
904
789
  });
905
790
  it('cleans up submenus that close before they are "open"', async () => {
906
- if ("showPopover" in document.createElement("div")) {
907
- return;
908
- }
909
791
  await sendMouse({
910
792
  steps: [
911
793
  {
@@ -955,6 +837,7 @@ describe("Submenu", () => {
955
837
  expect(rootItem2.open, "initially closed 2").to.be.false;
956
838
  const rootItemBoundingRect1 = rootItem1.getBoundingClientRect();
957
839
  const rootItemBoundingRect2 = rootItem2.getBoundingClientRect();
840
+ let activeOverlay;
958
841
  await sendMouse({
959
842
  steps: [
960
843
  {
@@ -999,12 +882,6 @@ describe("Submenu", () => {
999
882
  }
1000
883
  ]
1001
884
  });
1002
- await nextFrame();
1003
- await nextFrame();
1004
- await nextFrame();
1005
- await nextFrame();
1006
- await nextFrame();
1007
- await nextFrame();
1008
885
  const closed = oneEvent(rootItem2, "sp-closed");
1009
886
  await sendMouse({
1010
887
  steps: [
@@ -1012,12 +889,20 @@ describe("Submenu", () => {
1012
889
  type: "move",
1013
890
  position: [
1014
891
  rootItemBoundingRect2.left + rootItemBoundingRect2.width / 2,
1015
- rootItemBoundingRect2.top + rootItemBoundingRect2.height * 2
892
+ rootItemBoundingRect2.top + rootItemBoundingRect2.top + rootItemBoundingRect2.height / 2
1016
893
  ]
1017
894
  }
1018
895
  ]
1019
896
  });
897
+ activeOverlay = document.querySelector(
898
+ "active-overlay"
899
+ );
900
+ expect(activeOverlay).to.not.be.null;
1020
901
  await closed;
902
+ activeOverlay = document.querySelector(
903
+ "active-overlay"
904
+ );
905
+ expect(activeOverlay).to.be.null;
1021
906
  expect(rootItem1.open, "finally closed 1").to.be.false;
1022
907
  expect(rootItem2.open, "finally closed 2").to.be.false;
1023
908
  });