@spectrum-web-components/menu 0.14.4 → 0.15.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 (110) hide show
  1. package/custom-elements.json +59 -59
  2. package/package.json +53 -19
  3. package/sp-menu-divider.dev.js +3 -0
  4. package/sp-menu-divider.dev.js.map +7 -0
  5. package/sp-menu-divider.js +3 -14
  6. package/sp-menu-divider.js.map +7 -1
  7. package/sp-menu-group.dev.js +3 -0
  8. package/sp-menu-group.dev.js.map +7 -0
  9. package/sp-menu-group.js +3 -14
  10. package/sp-menu-group.js.map +7 -1
  11. package/sp-menu-item.dev.js +3 -0
  12. package/sp-menu-item.dev.js.map +7 -0
  13. package/sp-menu-item.js +3 -14
  14. package/sp-menu-item.js.map +7 -1
  15. package/sp-menu.dev.js +3 -0
  16. package/sp-menu.dev.js.map +7 -0
  17. package/sp-menu.js +3 -14
  18. package/sp-menu.js.map +7 -1
  19. package/src/Menu.dev.js +495 -0
  20. package/src/Menu.dev.js.map +7 -0
  21. package/src/Menu.js +487 -574
  22. package/src/Menu.js.map +7 -1
  23. package/src/MenuDivider.dev.js +13 -0
  24. package/src/MenuDivider.dev.js.map +7 -0
  25. package/src/MenuDivider.js +11 -25
  26. package/src/MenuDivider.js.map +7 -1
  27. package/src/MenuGroup.dev.js +82 -0
  28. package/src/MenuGroup.dev.js.map +7 -0
  29. package/src/MenuGroup.js +67 -71
  30. package/src/MenuGroup.js.map +7 -1
  31. package/src/MenuItem.dev.js +424 -0
  32. package/src/MenuItem.dev.js.map +7 -0
  33. package/src/MenuItem.js +397 -432
  34. package/src/MenuItem.js.map +7 -1
  35. package/src/index.dev.js +5 -0
  36. package/src/index.dev.js.map +7 -0
  37. package/src/index.js +5 -16
  38. package/src/index.js.map +7 -1
  39. package/src/menu-divider.css.dev.js +6 -0
  40. package/src/menu-divider.css.dev.js.map +7 -0
  41. package/src/menu-divider.css.js +3 -14
  42. package/src/menu-divider.css.js.map +7 -1
  43. package/src/menu-group.css.dev.js +8 -0
  44. package/src/menu-group.css.dev.js.map +7 -0
  45. package/src/menu-group.css.js +3 -14
  46. package/src/menu-group.css.js.map +7 -1
  47. package/src/menu-item.css.dev.js +73 -0
  48. package/src/menu-item.css.dev.js.map +7 -0
  49. package/src/menu-item.css.js +3 -14
  50. package/src/menu-item.css.js.map +7 -1
  51. package/src/menu.css.dev.js +61 -0
  52. package/src/menu.css.dev.js.map +7 -0
  53. package/src/menu.css.js +3 -14
  54. package/src/menu.css.js.map +7 -1
  55. package/src/spectrum-checkmark.css.dev.js +10 -0
  56. package/src/spectrum-checkmark.css.dev.js.map +7 -0
  57. package/src/spectrum-checkmark.css.js +3 -14
  58. package/src/spectrum-checkmark.css.js.map +7 -1
  59. package/src/spectrum-chevron.css.dev.js +10 -0
  60. package/src/spectrum-chevron.css.dev.js.map +7 -0
  61. package/src/spectrum-chevron.css.js +3 -14
  62. package/src/spectrum-chevron.css.js.map +7 -1
  63. package/src/spectrum-itemLabel.css.dev.js +6 -0
  64. package/src/spectrum-itemLabel.css.dev.js.map +7 -0
  65. package/src/spectrum-itemLabel.css.js +3 -14
  66. package/src/spectrum-itemLabel.css.js.map +7 -1
  67. package/src/spectrum-menu-divider.css.dev.js +6 -0
  68. package/src/spectrum-menu-divider.css.dev.js.map +7 -0
  69. package/src/spectrum-menu-divider.css.js +3 -14
  70. package/src/spectrum-menu-divider.css.js.map +7 -1
  71. package/src/spectrum-menu-item.css.dev.js +65 -0
  72. package/src/spectrum-menu-item.css.dev.js.map +7 -0
  73. package/src/spectrum-menu-item.css.js +3 -14
  74. package/src/spectrum-menu-item.css.js.map +7 -1
  75. package/src/spectrum-menu-sectionHeading.css.dev.js +8 -0
  76. package/src/spectrum-menu-sectionHeading.css.dev.js.map +7 -0
  77. package/src/spectrum-menu-sectionHeading.css.js +3 -14
  78. package/src/spectrum-menu-sectionHeading.css.js.map +7 -1
  79. package/src/spectrum-menu.css.dev.js +61 -0
  80. package/src/spectrum-menu.css.dev.js.map +7 -0
  81. package/src/spectrum-menu.css.js +3 -14
  82. package/src/spectrum-menu.css.js.map +7 -1
  83. package/stories/menu-group.stories.js +51 -58
  84. package/stories/menu-group.stories.js.map +7 -1
  85. package/stories/menu-item.stories.js +12 -32
  86. package/stories/menu-item.stories.js.map +7 -1
  87. package/stories/menu.stories.js +22 -35
  88. package/stories/menu.stories.js.map +7 -1
  89. package/stories/submenu.stories.js +125 -136
  90. package/stories/submenu.stories.js.map +7 -1
  91. package/test/benchmark/test-basic.js +8 -19
  92. package/test/benchmark/test-basic.js.map +7 -1
  93. package/test/menu-group.test-vrt.js +4 -15
  94. package/test/menu-group.test-vrt.js.map +7 -1
  95. package/test/menu-group.test.js +178 -168
  96. package/test/menu-group.test.js.map +7 -1
  97. package/test/menu-item.test-vrt.js +4 -15
  98. package/test/menu-item.test-vrt.js.map +7 -1
  99. package/test/menu-item.test.js +93 -99
  100. package/test/menu-item.test.js.map +7 -1
  101. package/test/menu-selects.test.js +488 -494
  102. package/test/menu-selects.test.js.map +7 -1
  103. package/test/menu.test-vrt.js +4 -15
  104. package/test/menu.test-vrt.js.map +7 -1
  105. package/test/menu.test.js +248 -257
  106. package/test/menu.test.js.map +7 -1
  107. package/test/submenu.test-vrt.js +4 -15
  108. package/test/submenu.test-vrt.js.map +7 -1
  109. package/test/submenu.test.js +452 -486
  110. package/test/submenu.test.js.map +7 -1
package/test/menu.test.js CHANGED
@@ -1,86 +1,78 @@
1
- /*
2
- Copyright 2020 Adobe. All rights reserved.
3
- This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- you may not use this file except in compliance with the License. You may obtain a copy
5
- of the License at http://www.apache.org/licenses/LICENSE-2.0
6
-
7
- Unless required by applicable law or agreed to in writing, software distributed under
8
- the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
- OF ANY KIND, either express or implied. See the License for the specific language
10
- governing permissions and limitations under the License.
11
- */
12
- import '../sp-menu.js';
13
- import '../sp-menu-item.js';
14
- import '../sp-menu-group.js';
15
- import { elementUpdated, expect, fixture, html, nextFrame, waitUntil, } from '@open-wc/testing';
16
- import { arrowDownEvent, arrowUpEvent, tabEvent, tEvent, } from '../../../test/testing-helpers.js';
17
- import { spy } from 'sinon';
18
- import { sendKeys } from '@web/test-runner-commands';
19
- describe('Menu', () => {
20
- it('renders empty', async () => {
21
- const el = await fixture(html `
1
+ import "@spectrum-web-components/menu/sp-menu.js";
2
+ import "@spectrum-web-components/menu/sp-menu-item.js";
3
+ import "@spectrum-web-components/menu/sp-menu-group.js";
4
+ import {
5
+ elementUpdated,
6
+ expect,
7
+ fixture,
8
+ html,
9
+ nextFrame,
10
+ waitUntil
11
+ } from "@open-wc/testing";
12
+ import {
13
+ arrowDownEvent,
14
+ arrowUpEvent,
15
+ tabEvent,
16
+ testForLitDevWarnings,
17
+ tEvent
18
+ } from "../../../test/testing-helpers.js";
19
+ import { spy } from "sinon";
20
+ import { sendKeys } from "@web/test-runner-commands";
21
+ describe("Menu", () => {
22
+ it("renders empty", async () => {
23
+ const el = await fixture(html`
22
24
  <sp-menu tabindex="0"><a href="#anchor">Test</a></sp-menu>
23
25
  `);
24
- const anchor = el.querySelector('a');
25
- await elementUpdated(el);
26
- expect(document.activeElement === el, 'self not focused, 1').to.be
27
- .false;
28
- expect(document.activeElement === anchor, 'child not focused, 1').to.be
29
- .false;
30
- expect(el.getAttribute('role')).to.equal('menu');
31
- el.focus();
32
- await elementUpdated(el);
33
- expect(document.activeElement === el, 'self not focused, 2').to.be
34
- .false;
35
- expect(document.activeElement === anchor, 'child not focused, 2').to.be
36
- .false;
37
- anchor.focus();
38
- expect(document.activeElement === el, 'self not focused, 3').to.be
39
- .false;
40
- expect(document.activeElement === anchor, 'anchor').to.be.true;
41
- });
42
- it('renders w/ [disabled] menu items', async () => {
43
- const focusinSpy = spy();
44
- const el = await fixture(html `
26
+ const anchor = el.querySelector("a");
27
+ await elementUpdated(el);
28
+ expect(document.activeElement === el, "self not focused, 1").to.be.false;
29
+ expect(document.activeElement === anchor, "child not focused, 1").to.be.false;
30
+ expect(el.getAttribute("role")).to.equal("menu");
31
+ el.focus();
32
+ await elementUpdated(el);
33
+ expect(document.activeElement === el, "self not focused, 2").to.be.false;
34
+ expect(document.activeElement === anchor, "child not focused, 2").to.be.false;
35
+ anchor.focus();
36
+ expect(document.activeElement === el, "self not focused, 3").to.be.false;
37
+ expect(document.activeElement === anchor, "anchor").to.be.true;
38
+ });
39
+ it("renders w/ [disabled] menu items", async () => {
40
+ const focusinSpy = spy();
41
+ const el = await fixture(html`
45
42
  <sp-menu tabindex="0" @focusin=${() => focusinSpy()}>
46
43
  <sp-menu-item disabled>Disabled item</sp-menu-item>
47
44
  </sp-menu>
48
45
  `);
49
- await elementUpdated(el);
50
- expect(document.activeElement === el, 'self not focused, 1').to.be
51
- .false;
52
- el.focus();
53
- await elementUpdated(el);
54
- expect(document.activeElement === el, 'self not focused, 2').to.be
55
- .false;
56
- expect(focusinSpy.callCount).to.equal(0);
57
- });
58
- it('renders w/ all [disabled] menu items', async () => {
59
- const focusinSpy = spy();
60
- const el = await fixture(html `
46
+ await elementUpdated(el);
47
+ expect(document.activeElement === el, "self not focused, 1").to.be.false;
48
+ el.focus();
49
+ await elementUpdated(el);
50
+ expect(document.activeElement === el, "self not focused, 2").to.be.false;
51
+ expect(focusinSpy.callCount).to.equal(0);
52
+ });
53
+ it("renders w/ all [disabled] menu items", async () => {
54
+ const focusinSpy = spy();
55
+ const el = await fixture(html`
61
56
  <sp-menu tabindex="0" @focusin=${() => focusinSpy()}>
62
57
  <sp-menu-item disabled>Disabled item 1</sp-menu-item>
63
58
  <sp-menu-item disabled>Disabled item 2</sp-menu-item>
64
59
  </sp-menu>
65
60
  `);
66
- const firstItem = el.querySelector('sp-menu-item');
67
- await elementUpdated(el);
68
- expect(document.activeElement === el, 'self not focused, 1').to.be
69
- .false;
70
- el.focus();
71
- await elementUpdated(el);
72
- expect(document.activeElement === el, 'self not focused, 2').to.be
73
- .false;
74
- expect(focusinSpy.callCount).to.equal(0);
75
- firstItem.focus();
76
- await elementUpdated(el);
77
- expect(document.activeElement === el, 'self not focused, 2').to.be
78
- .false;
79
- expect(focusinSpy.callCount).to.equal(0);
80
- expect(el.matches(':focus-within')).to.be.false;
81
- });
82
- it('renders w/ menu items', async () => {
83
- const el = await fixture(html `
61
+ const firstItem = el.querySelector("sp-menu-item");
62
+ await elementUpdated(el);
63
+ expect(document.activeElement === el, "self not focused, 1").to.be.false;
64
+ el.focus();
65
+ await elementUpdated(el);
66
+ expect(document.activeElement === el, "self not focused, 2").to.be.false;
67
+ expect(focusinSpy.callCount).to.equal(0);
68
+ firstItem.focus();
69
+ await elementUpdated(el);
70
+ expect(document.activeElement === el, "self not focused, 2").to.be.false;
71
+ expect(focusinSpy.callCount).to.equal(0);
72
+ expect(el.matches(":focus-within")).to.be.false;
73
+ });
74
+ it("renders w/ menu items", async () => {
75
+ const el = await fixture(html`
84
76
  <sp-menu label="Pick an action:">
85
77
  <sp-menu-item>Deselect</sp-menu-item>
86
78
  <sp-menu-item>Select Inverse</sp-menu-item>
@@ -91,25 +83,32 @@ describe('Menu', () => {
91
83
  <sp-menu-item disabled>Make Work Path</sp-menu-item>
92
84
  </sp-menu>
93
85
  `);
94
- await waitUntil(() => el.childItems.length == 6, 'expected menu to manage 6 menu items');
95
- await elementUpdated(el);
96
- const inTabindexElement = el.querySelector('[tabindex]:not([tabindex="-1"])');
97
- expect(inTabindexElement).to.be.null;
98
- await expect(el).to.be.accessible();
99
- });
100
- it('renders w/ selected', async () => {
101
- const el = await fixture(html `
86
+ await waitUntil(() => el.childItems.length == 6, "expected menu to manage 6 menu items");
87
+ await elementUpdated(el);
88
+ const inTabindexElement = el.querySelector('[tabindex]:not([tabindex="-1"])');
89
+ expect(inTabindexElement).to.be.null;
90
+ await expect(el).to.be.accessible();
91
+ });
92
+ testForLitDevWarnings(async () => await fixture(html`
93
+ <sp-menu selects="single">
94
+ <sp-menu-item>Not Selected</sp-menu-item>
95
+ <sp-menu-item selected>Selected</sp-menu-item>
96
+ <sp-menu-item>Other</sp-menu-item>
97
+ </sp-menu>
98
+ `));
99
+ it("renders w/ selected", async () => {
100
+ const el = await fixture(html`
102
101
  <sp-menu selects="single">
103
102
  <sp-menu-item>Not Selected</sp-menu-item>
104
103
  <sp-menu-item selected>Selected</sp-menu-item>
105
104
  <sp-menu-item>Other</sp-menu-item>
106
105
  </sp-menu>
107
106
  `);
108
- await elementUpdated(el);
109
- await expect(el).to.be.accessible();
110
- });
111
- it('renders w/ hrefs', async () => {
112
- const el = await fixture(html `
107
+ await elementUpdated(el);
108
+ await expect(el).to.be.accessible();
109
+ });
110
+ it("renders w/ hrefs", async () => {
111
+ const el = await fixture(html`
113
112
  <sp-menu>
114
113
  <sp-menu-item href="not-selected.html">
115
114
  Not Selected
@@ -118,13 +117,13 @@ describe('Menu', () => {
118
117
  <sp-menu-item href="other.html">Other</sp-menu-item>
119
118
  </sp-menu>
120
119
  `);
121
- await waitUntil(() => el.childItems.length == 3, 'expected menu to manage 3 items');
122
- await elementUpdated(el);
123
- await expect(el).to.be.accessible();
124
- expect(el.getAttribute('role')).to.equal('menu');
125
- });
126
- it('handle focus and keyboard input', async () => {
127
- const el = await fixture(html `
120
+ await waitUntil(() => el.childItems.length == 3, "expected menu to manage 3 items");
121
+ await elementUpdated(el);
122
+ await expect(el).to.be.accessible();
123
+ expect(el.getAttribute("role")).to.equal("menu");
124
+ });
125
+ it("handle focus and keyboard input", async () => {
126
+ const el = await fixture(html`
128
127
  <sp-menu>
129
128
  <sp-menu-item>Deselect</sp-menu-item>
130
129
  <sp-menu-item>Select Inverse</sp-menu-item>
@@ -135,29 +134,28 @@ describe('Menu', () => {
135
134
  <sp-menu-item disabled>Make Work Path</sp-menu-item>
136
135
  </sp-menu>
137
136
  `);
138
- await waitUntil(() => el.childItems.length == 6, 'expected menu to manage 6 items');
139
- await elementUpdated(el);
140
- const firstItem = el.querySelector('sp-menu-item:nth-of-type(1)');
141
- const thirdToLastItem = el.querySelector('sp-menu-item:nth-last-of-type(3)');
142
- const secondToLastItem = el.querySelector('sp-menu-item:nth-last-of-type(2)');
143
- el.focus();
144
- await elementUpdated(el);
145
- // Activate :focus-visible
146
- await sendKeys({ press: 'ArrowDown' });
147
- await sendKeys({ press: 'ArrowUp' });
148
- expect(document.activeElement === el).to.be.true;
149
- expect(firstItem.focused).to.be.true;
150
- el.dispatchEvent(arrowUpEvent());
151
- el.dispatchEvent(arrowUpEvent());
152
- el.dispatchEvent(tEvent());
153
- expect(document.activeElement === el).to.be.true;
154
- expect(thirdToLastItem.focused).to.be.true;
155
- el.dispatchEvent(arrowDownEvent());
156
- expect(document.activeElement === el).to.be.true;
157
- expect(secondToLastItem.focused).to.be.true;
158
- });
159
- it('handle focus and late descendent additions', async () => {
160
- const el = await fixture(html `
137
+ await waitUntil(() => el.childItems.length == 6, "expected menu to manage 6 items");
138
+ await elementUpdated(el);
139
+ const firstItem = el.querySelector("sp-menu-item:nth-of-type(1)");
140
+ const thirdToLastItem = el.querySelector("sp-menu-item:nth-last-of-type(3)");
141
+ const secondToLastItem = el.querySelector("sp-menu-item:nth-last-of-type(2)");
142
+ el.focus();
143
+ await elementUpdated(el);
144
+ await sendKeys({ press: "ArrowDown" });
145
+ await sendKeys({ press: "ArrowUp" });
146
+ expect(document.activeElement === el).to.be.true;
147
+ expect(firstItem.focused).to.be.true;
148
+ el.dispatchEvent(arrowUpEvent());
149
+ el.dispatchEvent(arrowUpEvent());
150
+ el.dispatchEvent(tEvent());
151
+ expect(document.activeElement === el).to.be.true;
152
+ expect(thirdToLastItem.focused).to.be.true;
153
+ el.dispatchEvent(arrowDownEvent());
154
+ expect(document.activeElement === el).to.be.true;
155
+ expect(secondToLastItem.focused).to.be.true;
156
+ });
157
+ it("handle focus and late descendent additions", async () => {
158
+ const el = await fixture(html`
161
159
  <sp-menu>
162
160
  <sp-menu-group selects="inherit">
163
161
  <span slot="header">Options</span>
@@ -165,80 +163,73 @@ describe('Menu', () => {
165
163
  </sp-menu-group>
166
164
  </sp-menu>
167
165
  `);
168
- await waitUntil(() => el.childItems.length == 1, 'expected menu to manage 1 item');
169
- await elementUpdated(el);
170
- const firstItem = el.querySelector('sp-menu-item:nth-of-type(1)');
171
- el.focus();
172
- await elementUpdated(el);
173
- // Activate :focus-visible
174
- await sendKeys({ press: 'ArrowDown' });
175
- await sendKeys({ press: 'ArrowUp' });
176
- expect(document.activeElement === el, 'active element').to.be.true;
177
- expect(firstItem.focused, 'visually focused').to.be.true;
178
- el.blur();
179
- const group = el.querySelector('sp-menu-group');
180
- const prependedItem = document.createElement('sp-menu-item');
181
- prependedItem.textContent = 'Prepended Item';
182
- const appendedItem = document.createElement('sp-menu-item');
183
- appendedItem.textContent = 'Appended Item';
184
- group.prepend(prependedItem);
185
- group.append(appendedItem);
186
- await elementUpdated(el);
187
- await waitUntil(() => {
188
- return el.childItems.length == 3;
189
- }, 'expected menu to manage 3 items');
190
- await elementUpdated(el);
191
- expect(document.activeElement === el).to.be.false;
192
- expect(firstItem.focused).to.be.false;
193
- expect(prependedItem.focused).to.be.false;
194
- el.focus();
195
- // Activate :focus-visible
196
- await sendKeys({ press: 'ArrowDown' });
197
- await sendKeys({ press: 'ArrowUp' });
198
- expect(document.activeElement === el, 'another active element').to.be
199
- .true;
200
- expect(prependedItem.focused, 'another visibly focused').to.be.true;
201
- el.dispatchEvent(arrowUpEvent());
202
- expect(document.activeElement === el, 'last active element').to.be.true;
203
- expect(appendedItem.focused, 'last visibly focused').to.be.true;
204
- });
205
- it('cleans up when tabbing away', async () => {
206
- const el = await fixture(html `
166
+ await waitUntil(() => el.childItems.length == 1, "expected menu to manage 1 item");
167
+ await elementUpdated(el);
168
+ const firstItem = el.querySelector("sp-menu-item:nth-of-type(1)");
169
+ el.focus();
170
+ await elementUpdated(el);
171
+ await sendKeys({ press: "ArrowDown" });
172
+ await sendKeys({ press: "ArrowUp" });
173
+ expect(document.activeElement === el, "active element").to.be.true;
174
+ expect(firstItem.focused, "visually focused").to.be.true;
175
+ el.blur();
176
+ const group = el.querySelector("sp-menu-group");
177
+ const prependedItem = document.createElement("sp-menu-item");
178
+ prependedItem.textContent = "Prepended Item";
179
+ const appendedItem = document.createElement("sp-menu-item");
180
+ appendedItem.textContent = "Appended Item";
181
+ group.prepend(prependedItem);
182
+ group.append(appendedItem);
183
+ await elementUpdated(el);
184
+ await waitUntil(() => {
185
+ return el.childItems.length == 3;
186
+ }, "expected menu to manage 3 items");
187
+ await elementUpdated(el);
188
+ expect(document.activeElement === el).to.be.false;
189
+ expect(firstItem.focused).to.be.false;
190
+ expect(prependedItem.focused).to.be.false;
191
+ el.focus();
192
+ await sendKeys({ press: "ArrowDown" });
193
+ await sendKeys({ press: "ArrowUp" });
194
+ expect(document.activeElement === el, "another active element").to.be.true;
195
+ expect(prependedItem.focused, "another visibly focused").to.be.true;
196
+ el.dispatchEvent(arrowUpEvent());
197
+ expect(document.activeElement === el, "last active element").to.be.true;
198
+ expect(appendedItem.focused, "last visibly focused").to.be.true;
199
+ });
200
+ it("cleans up when tabbing away", async () => {
201
+ const el = await fixture(html`
207
202
  <sp-menu tabindex="0">
208
203
  <sp-menu-item>Deselect</sp-menu-item>
209
204
  <sp-menu-item>Select Inverse</sp-menu-item>
210
205
  <sp-menu-item>Third Item</sp-menu-item>
211
206
  </sp-menu>
212
207
  `);
213
- await waitUntil(() => el.childItems.length == 3, 'expected menu to manage 3 items');
214
- await elementUpdated(el);
215
- const firstItem = el.querySelector('sp-menu-item:nth-of-type(1)');
216
- const secondItem = el.querySelector('sp-menu-item:nth-of-type(2)');
217
- const thirdItem = el.querySelector('sp-menu-item:nth-of-type(3)');
218
- el.focus();
219
- // Activate :focus-visible
220
- await sendKeys({ press: 'ArrowDown' });
221
- await sendKeys({ press: 'ArrowUp' });
222
- expect(document.activeElement === el).to.be.true;
223
- expect(firstItem.focused, 'first').to.be.true;
224
- el.dispatchEvent(arrowDownEvent());
225
- el.dispatchEvent(arrowDownEvent());
226
- expect(thirdItem.focused, 'third').to.be.true;
227
- // imitate tabbing away
228
- el.dispatchEvent(tabEvent());
229
- el.dispatchEvent(new CustomEvent('focusout', {
230
- composed: true,
231
- bubbles: true,
232
- }));
233
- await nextFrame();
234
- // re-bind keyevents
235
- el.startListeningToKeyboard();
236
- // focus management should start again from the first item.
237
- el.dispatchEvent(arrowDownEvent());
238
- expect(secondItem.focused, 'second').to.be.true;
239
- });
240
- it('handles focus across focused MenuItem removals', async () => {
241
- const el = await fixture(html `
208
+ await waitUntil(() => el.childItems.length == 3, "expected menu to manage 3 items");
209
+ await elementUpdated(el);
210
+ const firstItem = el.querySelector("sp-menu-item:nth-of-type(1)");
211
+ const secondItem = el.querySelector("sp-menu-item:nth-of-type(2)");
212
+ const thirdItem = el.querySelector("sp-menu-item:nth-of-type(3)");
213
+ el.focus();
214
+ await sendKeys({ press: "ArrowDown" });
215
+ await sendKeys({ press: "ArrowUp" });
216
+ expect(document.activeElement === el).to.be.true;
217
+ expect(firstItem.focused, "first").to.be.true;
218
+ el.dispatchEvent(arrowDownEvent());
219
+ el.dispatchEvent(arrowDownEvent());
220
+ expect(thirdItem.focused, "third").to.be.true;
221
+ el.dispatchEvent(tabEvent());
222
+ el.dispatchEvent(new CustomEvent("focusout", {
223
+ composed: true,
224
+ bubbles: true
225
+ }));
226
+ await nextFrame();
227
+ el.startListeningToKeyboard();
228
+ el.dispatchEvent(arrowDownEvent());
229
+ expect(secondItem.focused, "second").to.be.true;
230
+ });
231
+ it("handles focus across focused MenuItem removals", async () => {
232
+ const el = await fixture(html`
242
233
  <sp-menu id="test">
243
234
  <sp-menu-item class="first">Deselect</sp-menu-item>
244
235
  <sp-menu-item>Invert Selection</sp-menu-item>
@@ -249,90 +240,90 @@ describe('Menu', () => {
249
240
  </sp-menu-item>
250
241
  </sp-menu>
251
242
  `);
252
- const firstItem = el.querySelector('.first');
253
- const selectedItem = el.querySelector('.selected');
254
- await elementUpdated(el);
255
- el.focus();
256
- expect(document.activeElement).to.equal(el);
257
- expect(selectedItem.focused).to.be.true;
258
- selectedItem.remove();
259
- await elementUpdated(el);
260
- expect(document.activeElement).to.equal(el);
261
- expect(firstItem.focused).to.be.true;
262
- });
263
- it('handles single selection', async () => {
264
- const el = await fixture(html `
243
+ const firstItem = el.querySelector(".first");
244
+ const selectedItem = el.querySelector(".selected");
245
+ await elementUpdated(el);
246
+ el.focus();
247
+ expect(document.activeElement).to.equal(el);
248
+ expect(selectedItem.focused).to.be.true;
249
+ selectedItem.remove();
250
+ await elementUpdated(el);
251
+ expect(document.activeElement).to.equal(el);
252
+ expect(firstItem.focused).to.be.true;
253
+ });
254
+ it("handles single selection", async () => {
255
+ const el = await fixture(html`
265
256
  <sp-menu selects="single">
266
257
  <sp-menu-item selected>First</sp-menu-item>
267
258
  <sp-menu-item>Second</sp-menu-item>
268
259
  <sp-menu-item>Third</sp-menu-item>
269
260
  </sp-menu>
270
261
  `);
271
- await waitUntil(() => el.childItems.length == 3, 'expected menu to manage 3 items');
272
- await waitUntil(() => el.selectedItems.length == 1, 'expected menu to have 1 selected item');
273
- await elementUpdated(el);
274
- const firstItem = el.querySelector('sp-menu-item:nth-of-type(1)');
275
- const secondItem = el.querySelector('sp-menu-item:nth-of-type(2)');
276
- expect(firstItem.getAttribute('role')).to.equal('menuitemradio');
277
- expect(secondItem.getAttribute('role')).to.equal('menuitemradio');
278
- expect(firstItem.selected).to.be.true;
279
- expect(secondItem.selected).to.be.false;
280
- expect(firstItem.getAttribute('aria-checked')).to.equal('true');
281
- expect(secondItem.getAttribute('aria-checked')).to.equal('false');
282
- expect(el.value).to.equal('First');
283
- secondItem.click();
284
- await elementUpdated(el);
285
- await elementUpdated(firstItem);
286
- await elementUpdated(secondItem);
287
- expect(firstItem.selected).to.be.false;
288
- expect(secondItem.selected).to.be.true;
289
- expect(firstItem.getAttribute('aria-checked')).to.equal('false');
290
- expect(secondItem.getAttribute('aria-checked')).to.equal('true');
291
- expect(el.value).to.equal('Second');
292
- });
293
- it('handles multiple selection', async () => {
294
- const changeSpy = spy();
295
- const el = await fixture(html `
262
+ await waitUntil(() => el.childItems.length == 3, "expected menu to manage 3 items");
263
+ await waitUntil(() => el.selectedItems.length == 1, "expected menu to have 1 selected item");
264
+ await elementUpdated(el);
265
+ const firstItem = el.querySelector("sp-menu-item:nth-of-type(1)");
266
+ const secondItem = el.querySelector("sp-menu-item:nth-of-type(2)");
267
+ expect(firstItem.getAttribute("role")).to.equal("menuitemradio");
268
+ expect(secondItem.getAttribute("role")).to.equal("menuitemradio");
269
+ expect(firstItem.selected).to.be.true;
270
+ expect(secondItem.selected).to.be.false;
271
+ expect(firstItem.getAttribute("aria-checked")).to.equal("true");
272
+ expect(secondItem.getAttribute("aria-checked")).to.equal("false");
273
+ expect(el.value).to.equal("First");
274
+ secondItem.click();
275
+ await elementUpdated(el);
276
+ await elementUpdated(firstItem);
277
+ await elementUpdated(secondItem);
278
+ expect(firstItem.selected).to.be.false;
279
+ expect(secondItem.selected).to.be.true;
280
+ expect(firstItem.getAttribute("aria-checked")).to.equal("false");
281
+ expect(secondItem.getAttribute("aria-checked")).to.equal("true");
282
+ expect(el.value).to.equal("Second");
283
+ });
284
+ it("handles multiple selection", async () => {
285
+ const changeSpy = spy();
286
+ const el = await fixture(html`
296
287
  <sp-menu selects="multiple" @change=${() => changeSpy()}>
297
288
  <sp-menu-item selected>First</sp-menu-item>
298
289
  <sp-menu-item>Second</sp-menu-item>
299
290
  <sp-menu-item>Third</sp-menu-item>
300
291
  </sp-menu>
301
292
  `);
302
- await waitUntil(() => el.childItems.length == 3, 'expected menu to manage 3 items');
303
- await elementUpdated(el);
304
- const firstItem = el.querySelector('sp-menu-item:nth-of-type(1)');
305
- const secondItem = el.querySelector('sp-menu-item:nth-of-type(2)');
306
- expect(firstItem.getAttribute('role')).to.equal('menuitemcheckbox');
307
- expect(secondItem.getAttribute('role')).to.equal('menuitemcheckbox');
308
- expect(firstItem.selected).to.be.true;
309
- expect(secondItem.selected).to.be.false;
310
- expect(firstItem.getAttribute('aria-checked')).to.equal('true');
311
- expect(secondItem.getAttribute('aria-checked')).to.equal('false');
312
- expect(el.value).to.equal('First');
313
- expect(el.selectedItems.length).to.equal(1);
314
- secondItem.click();
315
- await elementUpdated(el);
316
- await elementUpdated(firstItem);
317
- await elementUpdated(secondItem);
318
- expect(changeSpy.callCount, 'one change').to.equal(1);
319
- expect(firstItem.selected).to.be.true;
320
- expect(secondItem.selected).to.be.true;
321
- expect(firstItem.getAttribute('aria-checked')).to.equal('true');
322
- expect(secondItem.getAttribute('aria-checked')).to.equal('true');
323
- expect(el.value).to.equal('First,Second');
324
- expect(el.selectedItems.length).to.equal(2);
325
- firstItem.click();
326
- await elementUpdated(el);
327
- await elementUpdated(firstItem);
328
- await elementUpdated(secondItem);
329
- expect(changeSpy.callCount, 'two changes').to.equal(2);
330
- expect(firstItem.selected).to.be.false;
331
- expect(secondItem.selected).to.be.true;
332
- expect(firstItem.getAttribute('aria-checked')).to.equal('false');
333
- expect(secondItem.getAttribute('aria-checked')).to.equal('true');
334
- expect(el.value).to.equal('Second');
335
- expect(el.selectedItems.length).to.equal(1);
336
- });
293
+ await waitUntil(() => el.childItems.length == 3, "expected menu to manage 3 items");
294
+ await elementUpdated(el);
295
+ const firstItem = el.querySelector("sp-menu-item:nth-of-type(1)");
296
+ const secondItem = el.querySelector("sp-menu-item:nth-of-type(2)");
297
+ expect(firstItem.getAttribute("role")).to.equal("menuitemcheckbox");
298
+ expect(secondItem.getAttribute("role")).to.equal("menuitemcheckbox");
299
+ expect(firstItem.selected).to.be.true;
300
+ expect(secondItem.selected).to.be.false;
301
+ expect(firstItem.getAttribute("aria-checked")).to.equal("true");
302
+ expect(secondItem.getAttribute("aria-checked")).to.equal("false");
303
+ expect(el.value).to.equal("First");
304
+ expect(el.selectedItems.length).to.equal(1);
305
+ secondItem.click();
306
+ await elementUpdated(el);
307
+ await elementUpdated(firstItem);
308
+ await elementUpdated(secondItem);
309
+ expect(changeSpy.callCount, "one change").to.equal(1);
310
+ expect(firstItem.selected).to.be.true;
311
+ expect(secondItem.selected).to.be.true;
312
+ expect(firstItem.getAttribute("aria-checked")).to.equal("true");
313
+ expect(secondItem.getAttribute("aria-checked")).to.equal("true");
314
+ expect(el.value).to.equal("First,Second");
315
+ expect(el.selectedItems.length).to.equal(2);
316
+ firstItem.click();
317
+ await elementUpdated(el);
318
+ await elementUpdated(firstItem);
319
+ await elementUpdated(secondItem);
320
+ expect(changeSpy.callCount, "two changes").to.equal(2);
321
+ expect(firstItem.selected).to.be.false;
322
+ expect(secondItem.selected).to.be.true;
323
+ expect(firstItem.getAttribute("aria-checked")).to.equal("false");
324
+ expect(secondItem.getAttribute("aria-checked")).to.equal("true");
325
+ expect(el.value).to.equal("Second");
326
+ expect(el.selectedItems.length).to.equal(1);
327
+ });
337
328
  });
338
- //# sourceMappingURL=menu.test.js.map
329
+ //# sourceMappingURL=menu.test.js.map