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