@spectrum-web-components/menu 0.41.2 → 0.42.1
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.
- package/custom-elements.json +19 -17
- package/package.json +12 -11
- package/src/Menu.dev.js +2 -0
- package/src/Menu.dev.js.map +2 -2
- package/src/Menu.js +2 -2
- package/src/Menu.js.map +2 -2
- package/src/MenuItem.d.ts +3 -2
- package/src/MenuItem.dev.js +26 -34
- package/src/MenuItem.dev.js.map +2 -2
- package/src/MenuItem.js +10 -9
- package/src/MenuItem.js.map +3 -3
- package/src/menu-item.css.dev.js +1 -1
- package/src/menu-item.css.dev.js.map +1 -1
- package/src/menu-item.css.js +1 -1
- package/src/menu-item.css.js.map +1 -1
- package/src/spectrum-config.js +25 -1
- package/src/spectrum-menu-item.css.dev.js +1 -1
- package/src/spectrum-menu-item.css.dev.js.map +1 -1
- package/src/spectrum-menu-item.css.js +1 -1
- package/src/spectrum-menu-item.css.js.map +1 -1
- package/stories/submenu.stories.js +5 -1
- package/stories/submenu.stories.js.map +2 -2
- package/test/menu-memory.test.js +3 -40
- package/test/menu-memory.test.js.map +2 -2
- package/test/menu.test.js +15 -3
- package/test/menu.test.js.map +2 -2
- package/test/submenu.test.js +673 -763
- package/test/submenu.test.js.map +2 -2
package/test/submenu.test.js
CHANGED
|
@@ -17,79 +17,486 @@ import "@spectrum-web-components/action-menu/sp-action-menu.js";
|
|
|
17
17
|
import "@spectrum-web-components/menu/sp-menu-group.js";
|
|
18
18
|
import "@spectrum-web-components/overlay/sp-overlay.js";
|
|
19
19
|
import "@spectrum-web-components/icons-workflow/icons/sp-icon-show-menu.js";
|
|
20
|
+
import { slottableRequest } from "@spectrum-web-components/overlay/src/slottable-request-directive.js";
|
|
21
|
+
const selectsWithKeyboardData = [
|
|
22
|
+
{
|
|
23
|
+
dir: "ltr",
|
|
24
|
+
openKey: "ArrowRight",
|
|
25
|
+
closeKey: "ArrowLeft"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
dir: "rtl",
|
|
29
|
+
openKey: "ArrowLeft",
|
|
30
|
+
closeKey: "ArrowRight"
|
|
31
|
+
}
|
|
32
|
+
];
|
|
20
33
|
describe("Submenu", () => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
34
|
+
function selectWithPointer() {
|
|
35
|
+
it("with pointer", async function() {
|
|
36
|
+
const rootItemBoundingRect = this.rootItem.getBoundingClientRect();
|
|
37
|
+
expect(this.rootItem.open).to.be.false;
|
|
38
|
+
const opened = oneEvent(this.rootItem, "sp-opened");
|
|
39
|
+
await sendMouse({
|
|
40
|
+
steps: [
|
|
41
|
+
{
|
|
42
|
+
type: "move",
|
|
43
|
+
position: [
|
|
44
|
+
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
45
|
+
rootItemBoundingRect.top + rootItemBoundingRect.height / 2
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
});
|
|
50
|
+
await opened;
|
|
51
|
+
expect(this.rootItem.open).to.be.true;
|
|
52
|
+
const item2 = document.querySelector(".submenu-item-2");
|
|
53
|
+
const item2BoundingRect = item2.getBoundingClientRect();
|
|
54
|
+
const closed = oneEvent(this.rootItem, "sp-closed");
|
|
55
|
+
await sendMouse({
|
|
56
|
+
steps: [
|
|
57
|
+
{
|
|
58
|
+
type: "click",
|
|
59
|
+
position: [
|
|
60
|
+
item2BoundingRect.left + item2BoundingRect.width / 2,
|
|
61
|
+
item2BoundingRect.top + item2BoundingRect.height / 2
|
|
62
|
+
]
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
});
|
|
66
|
+
await closed;
|
|
67
|
+
expect(
|
|
68
|
+
this.submenuChanged.withArgs("Two").calledOnce,
|
|
69
|
+
`submenu changed ${this.submenuChanged.callCount} times`
|
|
70
|
+
).to.be.true;
|
|
71
|
+
expect(
|
|
72
|
+
this.rootChanged.withArgs("Has submenu").calledOnce,
|
|
73
|
+
"root changed"
|
|
74
|
+
).to.be.true;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function selectsWithKeyboard(testData) {
|
|
78
|
+
it(`with keyboard: ${testData.dir}`, async function() {
|
|
79
|
+
var _a, _b;
|
|
80
|
+
this.el.parentElement.dir = testData.dir;
|
|
81
|
+
await elementUpdated(this.el);
|
|
82
|
+
expect(this.rootItem.open).to.be.false;
|
|
83
|
+
const input = document.createElement("input");
|
|
84
|
+
this.el.insertAdjacentElement("beforebegin", input);
|
|
85
|
+
input.focus();
|
|
86
|
+
await sendKeys({
|
|
87
|
+
press: "Tab"
|
|
88
|
+
});
|
|
89
|
+
await sendKeys({
|
|
90
|
+
press: "ArrowDown"
|
|
91
|
+
});
|
|
92
|
+
await elementUpdated(this.rootItem);
|
|
93
|
+
expect(this.rootItem.focused).to.be.true;
|
|
94
|
+
let opened = oneEvent(this.rootItem, "sp-opened");
|
|
95
|
+
await sendKeys({
|
|
96
|
+
press: testData.openKey
|
|
97
|
+
});
|
|
98
|
+
await opened;
|
|
99
|
+
let submenu = this.el.querySelector('[slot="submenu"]');
|
|
100
|
+
let submenuItem = this.el.querySelector(
|
|
101
|
+
".submenu-item-2"
|
|
102
|
+
);
|
|
103
|
+
expect(this.rootItem.open).to.be.true;
|
|
104
|
+
expect(
|
|
105
|
+
submenu === document.activeElement,
|
|
106
|
+
`${(_a = document.activeElement) == null ? void 0 : _a.id}`
|
|
107
|
+
).to.be.true;
|
|
108
|
+
let closed = oneEvent(this.rootItem, "sp-closed");
|
|
109
|
+
await sendKeys({
|
|
110
|
+
press: testData.closeKey
|
|
111
|
+
});
|
|
112
|
+
await closed;
|
|
113
|
+
expect(this.rootItem.open).to.be.false;
|
|
114
|
+
expect(
|
|
115
|
+
this.el === document.activeElement,
|
|
116
|
+
`${(_b = document.activeElement) == null ? void 0 : _b.id}`
|
|
117
|
+
).to.be.true;
|
|
118
|
+
opened = oneEvent(this.rootItem, "sp-opened");
|
|
119
|
+
await sendKeys({
|
|
120
|
+
press: testData.openKey
|
|
121
|
+
});
|
|
122
|
+
await opened;
|
|
123
|
+
submenu = this.el.querySelector('[slot="submenu"]');
|
|
124
|
+
submenuItem = this.el.querySelector(".submenu-item-2");
|
|
125
|
+
expect(this.rootItem.open).to.be.true;
|
|
126
|
+
await sendKeys({
|
|
127
|
+
press: "ArrowDown"
|
|
128
|
+
});
|
|
129
|
+
await elementUpdated(submenu);
|
|
130
|
+
await elementUpdated(submenuItem);
|
|
131
|
+
expect(submenu.getAttribute("aria-activedescendant")).to.equal(
|
|
132
|
+
submenuItem.id
|
|
133
|
+
);
|
|
134
|
+
closed = oneEvent(this.rootItem, "sp-closed");
|
|
135
|
+
await sendKeys({
|
|
136
|
+
press: "Enter"
|
|
137
|
+
});
|
|
138
|
+
await closed;
|
|
139
|
+
expect(this.submenuChanged.calledWith("Two"), "submenu changed").to.be.true;
|
|
140
|
+
expect(this.rootChanged.called, "root has changed").to.be.true;
|
|
141
|
+
expect(
|
|
142
|
+
this.rootChanged.calledWith("Has submenu"),
|
|
143
|
+
"root specifically changed"
|
|
144
|
+
).to.be.true;
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function returnsFocusToRootWhenClosingSubmenu() {
|
|
148
|
+
it("returns visible focus when submenu closed", async function() {
|
|
149
|
+
const input = document.createElement("input");
|
|
150
|
+
this.el.insertAdjacentElement("beforebegin", input);
|
|
151
|
+
input.focus();
|
|
152
|
+
await sendKeys({
|
|
153
|
+
press: "Tab"
|
|
154
|
+
});
|
|
155
|
+
await sendKeys({
|
|
156
|
+
press: "ArrowDown"
|
|
157
|
+
});
|
|
158
|
+
await elementUpdated(this.rootItem);
|
|
159
|
+
expect(this.rootItem.active).to.be.false;
|
|
160
|
+
expect(this.rootItem.focused).to.be.true;
|
|
161
|
+
expect(this.rootItem.open).to.be.false;
|
|
162
|
+
const opened = oneEvent(this.rootItem, "sp-opened");
|
|
163
|
+
await sendKeys({
|
|
164
|
+
press: "ArrowRight"
|
|
165
|
+
});
|
|
166
|
+
await opened;
|
|
167
|
+
expect(this.rootItem.active).to.be.true;
|
|
168
|
+
expect(this.rootItem.focused).to.be.false;
|
|
169
|
+
expect(this.rootItem.open).to.be.true;
|
|
170
|
+
await sendKeys({
|
|
171
|
+
press: "ArrowDown"
|
|
172
|
+
});
|
|
173
|
+
expect(this.rootItem.active).to.be.true;
|
|
174
|
+
expect(this.rootItem.focused).to.be.false;
|
|
175
|
+
expect(this.rootItem.open).to.be.true;
|
|
176
|
+
const closed = oneEvent(this.rootItem, "sp-closed");
|
|
177
|
+
await sendKeys({
|
|
178
|
+
press: "ArrowLeft"
|
|
179
|
+
});
|
|
180
|
+
await closed;
|
|
181
|
+
expect(this.rootItem.active).to.be.false;
|
|
182
|
+
expect(this.rootItem.focused).to.be.true;
|
|
183
|
+
expect(this.rootItem.open).to.be.false;
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
function closesOnPointerLeave() {
|
|
187
|
+
it("closes on `pointerleave`", async function() {
|
|
188
|
+
const rootItemBoundingRect = this.rootItem.getBoundingClientRect();
|
|
189
|
+
expect(this.rootItem.open).to.be.false;
|
|
190
|
+
const opened = oneEvent(this.rootItem, "sp-opened");
|
|
191
|
+
await sendMouse({
|
|
192
|
+
steps: [
|
|
193
|
+
{
|
|
194
|
+
type: "move",
|
|
195
|
+
position: [
|
|
196
|
+
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
197
|
+
rootItemBoundingRect.top + rootItemBoundingRect.height / 2
|
|
198
|
+
]
|
|
199
|
+
}
|
|
200
|
+
]
|
|
201
|
+
});
|
|
202
|
+
await opened;
|
|
203
|
+
expect(this.rootItem.open).to.be.true;
|
|
204
|
+
const closed = oneEvent(this.rootItem, "sp-closed");
|
|
205
|
+
await sendMouse({
|
|
206
|
+
steps: [
|
|
207
|
+
{
|
|
208
|
+
type: "move",
|
|
209
|
+
position: [
|
|
210
|
+
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
211
|
+
rootItemBoundingRect.top + rootItemBoundingRect.height * 2
|
|
212
|
+
]
|
|
213
|
+
}
|
|
214
|
+
]
|
|
215
|
+
});
|
|
216
|
+
await closed;
|
|
217
|
+
expect(this.rootItem.open).to.be.false;
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
function persistsThroughMouseLeaveAndReturn() {
|
|
221
|
+
it("stays open when mousing off menu item and back again", async function() {
|
|
222
|
+
const rootItemBoundingRect = this.rootItem.getBoundingClientRect();
|
|
223
|
+
expect(this.rootItem.open).to.be.false;
|
|
224
|
+
const opened = oneEvent(this.rootItem, "sp-opened");
|
|
225
|
+
await sendMouse({
|
|
226
|
+
steps: [
|
|
227
|
+
{
|
|
228
|
+
type: "move",
|
|
229
|
+
position: [
|
|
230
|
+
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
231
|
+
rootItemBoundingRect.top + rootItemBoundingRect.height / 2
|
|
232
|
+
]
|
|
233
|
+
}
|
|
234
|
+
]
|
|
235
|
+
});
|
|
236
|
+
await sendMouse({
|
|
237
|
+
steps: [
|
|
238
|
+
{
|
|
239
|
+
type: "move",
|
|
240
|
+
position: [
|
|
241
|
+
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
242
|
+
rootItemBoundingRect.top + rootItemBoundingRect.height * 2
|
|
243
|
+
]
|
|
244
|
+
}
|
|
245
|
+
]
|
|
246
|
+
});
|
|
247
|
+
await sendMouse({
|
|
248
|
+
steps: [
|
|
249
|
+
{
|
|
250
|
+
type: "move",
|
|
251
|
+
position: [
|
|
252
|
+
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
253
|
+
rootItemBoundingRect.top + rootItemBoundingRect.height / 2
|
|
254
|
+
]
|
|
255
|
+
}
|
|
256
|
+
]
|
|
257
|
+
});
|
|
258
|
+
await opened;
|
|
259
|
+
expect(this.rootItem.open).to.be.true;
|
|
260
|
+
const closed = oneEvent(this.rootItem, "sp-closed");
|
|
261
|
+
await sendMouse({
|
|
262
|
+
steps: [
|
|
263
|
+
{
|
|
264
|
+
type: "move",
|
|
265
|
+
position: [
|
|
266
|
+
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
267
|
+
rootItemBoundingRect.top + rootItemBoundingRect.height * 2
|
|
268
|
+
]
|
|
269
|
+
}
|
|
270
|
+
]
|
|
271
|
+
});
|
|
272
|
+
await closed;
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
function doesNotOpenWhenDisabled() {
|
|
276
|
+
it("does not open when disabled", async function() {
|
|
277
|
+
this.rootItem.disabled = true;
|
|
278
|
+
await elementUpdated(this.rootItem);
|
|
279
|
+
const rootItemBoundingRect = this.rootItem.getBoundingClientRect();
|
|
280
|
+
expect(this.rootItem.open).to.be.false;
|
|
281
|
+
await sendMouse({
|
|
282
|
+
steps: [
|
|
283
|
+
{
|
|
284
|
+
type: "move",
|
|
285
|
+
position: [
|
|
286
|
+
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
287
|
+
rootItemBoundingRect.top + rootItemBoundingRect.height / 2
|
|
288
|
+
]
|
|
289
|
+
}
|
|
290
|
+
]
|
|
291
|
+
});
|
|
292
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
293
|
+
expect(this.rootItem.open).to.be.false;
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
function persistsWhenMovingBetweenItemAndSubmenu() {
|
|
297
|
+
it("stays open when mousing between menu item and submenu", async function() {
|
|
298
|
+
const rootItemBoundingRect = this.rootItem.getBoundingClientRect();
|
|
299
|
+
expect(this.rootItem.open).to.be.false;
|
|
300
|
+
const opened = oneEvent(this.rootItem, "sp-opened");
|
|
301
|
+
await sendMouse({
|
|
302
|
+
steps: [
|
|
303
|
+
{
|
|
304
|
+
type: "move",
|
|
305
|
+
position: [
|
|
306
|
+
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
307
|
+
rootItemBoundingRect.top + rootItemBoundingRect.height / 2
|
|
308
|
+
]
|
|
309
|
+
}
|
|
310
|
+
]
|
|
311
|
+
});
|
|
312
|
+
await opened;
|
|
313
|
+
await nextFrame();
|
|
314
|
+
await nextFrame();
|
|
315
|
+
const subItem = this.el.querySelector(
|
|
316
|
+
".submenu-item-2"
|
|
317
|
+
);
|
|
318
|
+
const clickSpy = spy();
|
|
319
|
+
subItem.addEventListener("click", () => clickSpy());
|
|
320
|
+
const subItemBoundingRect = subItem.getBoundingClientRect();
|
|
321
|
+
expect(this.rootItem.open).to.be.true;
|
|
322
|
+
await sendMouse({
|
|
323
|
+
steps: [
|
|
324
|
+
{
|
|
325
|
+
type: "move",
|
|
326
|
+
position: [
|
|
327
|
+
subItemBoundingRect.left + subItemBoundingRect.width / 2,
|
|
328
|
+
subItemBoundingRect.top + subItemBoundingRect.height / 2
|
|
329
|
+
]
|
|
330
|
+
}
|
|
331
|
+
]
|
|
332
|
+
});
|
|
333
|
+
expect(this.rootItem.open).to.be.true;
|
|
334
|
+
await aTimeout(150);
|
|
335
|
+
expect(this.rootItem.open).to.be.true;
|
|
336
|
+
const closed = oneEvent(this.rootItem, "sp-closed");
|
|
337
|
+
await sendMouse({
|
|
338
|
+
steps: [
|
|
339
|
+
{
|
|
340
|
+
type: "click",
|
|
341
|
+
position: [
|
|
342
|
+
subItemBoundingRect.left + subItemBoundingRect.width / 2,
|
|
343
|
+
subItemBoundingRect.top + subItemBoundingRect.height / 2
|
|
344
|
+
]
|
|
345
|
+
}
|
|
346
|
+
]
|
|
347
|
+
});
|
|
348
|
+
await closed;
|
|
349
|
+
expect(clickSpy.callCount).to.equal(1);
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
function continuesToOpenWhenMovingBetweenItemAndSubmenu() {
|
|
353
|
+
it("continues to open when mousing between menu item and submenu", async function() {
|
|
354
|
+
const rootItemBoundingRect = this.rootItem.getBoundingClientRect();
|
|
355
|
+
expect(this.rootItem.open).to.be.false;
|
|
356
|
+
const opened = oneEvent(this.rootItem, "sp-opened");
|
|
357
|
+
await sendMouse({
|
|
358
|
+
steps: [
|
|
359
|
+
{
|
|
360
|
+
type: "move",
|
|
361
|
+
position: [
|
|
362
|
+
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
363
|
+
rootItemBoundingRect.top + rootItemBoundingRect.height / 2
|
|
364
|
+
]
|
|
365
|
+
}
|
|
366
|
+
]
|
|
367
|
+
});
|
|
368
|
+
await nextFrame();
|
|
369
|
+
await nextFrame();
|
|
370
|
+
await nextFrame();
|
|
371
|
+
await nextFrame();
|
|
372
|
+
await nextFrame();
|
|
373
|
+
await nextFrame();
|
|
374
|
+
await nextFrame();
|
|
375
|
+
await nextFrame();
|
|
376
|
+
const subItem = this.el.querySelector(
|
|
377
|
+
".submenu-item-2"
|
|
378
|
+
);
|
|
379
|
+
const clickSpy = spy();
|
|
380
|
+
subItem.addEventListener("click", () => clickSpy());
|
|
381
|
+
const subItemBoundingRect = subItem.getBoundingClientRect();
|
|
382
|
+
await sendMouse({
|
|
383
|
+
steps: [
|
|
384
|
+
{
|
|
385
|
+
type: "move",
|
|
386
|
+
position: [
|
|
387
|
+
subItemBoundingRect.left + subItemBoundingRect.width / 2,
|
|
388
|
+
subItemBoundingRect.top + subItemBoundingRect.height / 2
|
|
389
|
+
]
|
|
390
|
+
}
|
|
391
|
+
]
|
|
392
|
+
});
|
|
393
|
+
await opened;
|
|
394
|
+
expect(this.rootItem.open).to.be.true;
|
|
395
|
+
await aTimeout(150);
|
|
396
|
+
expect(this.rootItem.open).to.be.true;
|
|
397
|
+
const closed = oneEvent(this.rootItem, "sp-closed");
|
|
398
|
+
await sendMouse({
|
|
399
|
+
steps: [
|
|
400
|
+
{
|
|
401
|
+
type: "click",
|
|
402
|
+
position: [
|
|
403
|
+
subItemBoundingRect.left + subItemBoundingRect.width / 2,
|
|
404
|
+
subItemBoundingRect.top + subItemBoundingRect.height / 2
|
|
405
|
+
]
|
|
406
|
+
}
|
|
407
|
+
]
|
|
408
|
+
});
|
|
409
|
+
await closed;
|
|
410
|
+
expect(clickSpy.callCount).to.equal(1);
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
const renderSubmenu = () => html`
|
|
414
|
+
<sp-menu-item class="submenu-item-1">One</sp-menu-item>
|
|
415
|
+
<sp-menu-item class="submenu-item-2">Two</sp-menu-item>
|
|
416
|
+
<sp-menu-item class="submenu-item-3">Three</sp-menu-item>
|
|
417
|
+
`;
|
|
418
|
+
describe("static DOM", () => {
|
|
419
|
+
beforeEach(async function() {
|
|
420
|
+
this.rootChanged = spy();
|
|
421
|
+
this.submenuChanged = spy();
|
|
422
|
+
this.el = await fixture(html`
|
|
26
423
|
<sp-menu
|
|
27
424
|
@change=${(event) => {
|
|
28
|
-
rootChanged(event.target.value);
|
|
425
|
+
this.rootChanged(event.target.value);
|
|
29
426
|
}}
|
|
30
427
|
>
|
|
428
|
+
<sp-menu-item>No submenu</sp-menu-item>
|
|
31
429
|
<sp-menu-item class="root">
|
|
32
430
|
Has submenu
|
|
33
431
|
<sp-menu
|
|
34
432
|
slot="submenu"
|
|
35
433
|
@change=${(event) => {
|
|
36
|
-
submenuChanged(event.target.value);
|
|
434
|
+
this.submenuChanged(event.target.value);
|
|
37
435
|
}}
|
|
38
436
|
>
|
|
39
|
-
|
|
40
|
-
One
|
|
41
|
-
</sp-menu-item>
|
|
42
|
-
<sp-menu-item class="submenu-item-2">
|
|
43
|
-
Two
|
|
44
|
-
</sp-menu-item>
|
|
45
|
-
<sp-menu-item class="submenu-item-3">
|
|
46
|
-
Three
|
|
47
|
-
</sp-menu-item>
|
|
437
|
+
${renderSubmenu()}
|
|
48
438
|
</sp-menu>
|
|
49
439
|
</sp-menu-item>
|
|
50
440
|
</sp-menu>
|
|
51
|
-
`
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const rootItem = el.querySelector(".root");
|
|
57
|
-
const rootItemBoundingRect = rootItem.getBoundingClientRect();
|
|
58
|
-
expect(rootItem.open).to.be.false;
|
|
59
|
-
const opened = oneEvent(rootItem, "sp-opened");
|
|
60
|
-
await sendMouse({
|
|
61
|
-
steps: [
|
|
62
|
-
{
|
|
63
|
-
type: "move",
|
|
64
|
-
position: [
|
|
65
|
-
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
66
|
-
rootItemBoundingRect.top + rootItemBoundingRect.height / 2
|
|
67
|
-
]
|
|
68
|
-
}
|
|
69
|
-
]
|
|
441
|
+
`);
|
|
442
|
+
await elementUpdated(this.el);
|
|
443
|
+
await nextFrame();
|
|
444
|
+
await nextFrame();
|
|
445
|
+
this.rootItem = this.el.querySelector(".root");
|
|
70
446
|
});
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
await sendMouse({
|
|
77
|
-
steps: [
|
|
78
|
-
{
|
|
79
|
-
type: "click",
|
|
80
|
-
position: [
|
|
81
|
-
item2BoundingRect.left + item2BoundingRect.width / 2,
|
|
82
|
-
item2BoundingRect.top + item2BoundingRect.height / 2
|
|
83
|
-
]
|
|
84
|
-
}
|
|
85
|
-
]
|
|
447
|
+
describe("selects", () => {
|
|
448
|
+
selectWithPointer();
|
|
449
|
+
selectsWithKeyboardData.map((testData) => {
|
|
450
|
+
selectsWithKeyboard(testData);
|
|
451
|
+
});
|
|
86
452
|
});
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
)
|
|
92
|
-
|
|
453
|
+
closesOnPointerLeave();
|
|
454
|
+
returnsFocusToRootWhenClosingSubmenu();
|
|
455
|
+
persistsThroughMouseLeaveAndReturn();
|
|
456
|
+
doesNotOpenWhenDisabled();
|
|
457
|
+
persistsWhenMovingBetweenItemAndSubmenu();
|
|
458
|
+
continuesToOpenWhenMovingBetweenItemAndSubmenu();
|
|
459
|
+
});
|
|
460
|
+
describe("directive", () => {
|
|
461
|
+
beforeEach(async function() {
|
|
462
|
+
this.rootChanged = spy();
|
|
463
|
+
this.submenuChanged = spy();
|
|
464
|
+
this.el = await fixture(html`
|
|
465
|
+
<sp-menu
|
|
466
|
+
@change=${(event) => {
|
|
467
|
+
this.rootChanged(event.target.value);
|
|
468
|
+
}}
|
|
469
|
+
>
|
|
470
|
+
<sp-menu-item>No submenu</sp-menu-item>
|
|
471
|
+
<sp-menu-item class="root">
|
|
472
|
+
Has submenu
|
|
473
|
+
<sp-menu
|
|
474
|
+
slot="submenu"
|
|
475
|
+
@change=${(event) => {
|
|
476
|
+
this.submenuChanged(event.target.value);
|
|
477
|
+
}}
|
|
478
|
+
${slottableRequest(renderSubmenu)}
|
|
479
|
+
></sp-menu>
|
|
480
|
+
</sp-menu-item>
|
|
481
|
+
</sp-menu>
|
|
482
|
+
`);
|
|
483
|
+
await elementUpdated(this.el);
|
|
484
|
+
await nextFrame();
|
|
485
|
+
await nextFrame();
|
|
486
|
+
this.rootItem = this.el.querySelector(".root");
|
|
487
|
+
});
|
|
488
|
+
describe("selects", () => {
|
|
489
|
+
selectWithPointer();
|
|
490
|
+
selectsWithKeyboardData.map((testData) => {
|
|
491
|
+
selectsWithKeyboard(testData);
|
|
492
|
+
});
|
|
493
|
+
});
|
|
494
|
+
closesOnPointerLeave();
|
|
495
|
+
returnsFocusToRootWhenClosingSubmenu();
|
|
496
|
+
persistsThroughMouseLeaveAndReturn();
|
|
497
|
+
doesNotOpenWhenDisabled();
|
|
498
|
+
persistsWhenMovingBetweenItemAndSubmenu();
|
|
499
|
+
continuesToOpenWhenMovingBetweenItemAndSubmenu();
|
|
93
500
|
});
|
|
94
501
|
it("closes deep tree on selection", async function() {
|
|
95
502
|
const rootChanged = spy();
|
|
@@ -192,703 +599,226 @@ describe("Submenu", () => {
|
|
|
192
599
|
expect(submenuChanged.calledWith("Two"), "submenu changed").to.be.true;
|
|
193
600
|
expect(subSubmenuChanged.calledWith("C"), "sub submenu changed").to.be.true;
|
|
194
601
|
});
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
<sp-menu
|
|
220
|
-
|
|
221
|
-
<sp-menu
|
|
222
|
-
|
|
223
|
-
slot="submenu"
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
602
|
+
it("closes all decendent submenus when closing a ancestor menu", async () => {
|
|
603
|
+
const el = await fixture(html`
|
|
604
|
+
<sp-action-menu label="Closing ancestors will close submenus">
|
|
605
|
+
<sp-icon-show-menu slot="icon"></sp-icon-show-menu>
|
|
606
|
+
<sp-menu-group role="none" id="group">
|
|
607
|
+
<span slot="header">New York</span>
|
|
608
|
+
<sp-menu-item>Bronx</sp-menu-item>
|
|
609
|
+
<sp-menu-item id="submenu-item-1">
|
|
610
|
+
Brooklyn
|
|
611
|
+
<sp-menu slot="submenu" id="submenu-1">
|
|
612
|
+
<sp-menu-item id="submenu-item-2">
|
|
613
|
+
Ft. Greene
|
|
614
|
+
<sp-menu slot="submenu" id="submenu-2">
|
|
615
|
+
<sp-menu-item>S. Oxford St</sp-menu-item>
|
|
616
|
+
<sp-menu-item>S. Portland Ave</sp-menu-item>
|
|
617
|
+
<sp-menu-item>S. Elliot Pl</sp-menu-item>
|
|
618
|
+
</sp-menu>
|
|
619
|
+
</sp-menu-item>
|
|
620
|
+
<sp-menu-item disabled>Park Slope</sp-menu-item>
|
|
621
|
+
<sp-menu-item>Williamsburg</sp-menu-item>
|
|
622
|
+
</sp-menu>
|
|
623
|
+
</sp-menu-item>
|
|
624
|
+
<sp-menu-item id="submenu-item-3">
|
|
625
|
+
Manhattan
|
|
626
|
+
<sp-menu slot="submenu" id="submenu-3">
|
|
627
|
+
<sp-menu-item disabled>SoHo</sp-menu-item>
|
|
628
|
+
<sp-menu-item>
|
|
629
|
+
Union Square
|
|
630
|
+
<sp-menu slot="submenu">
|
|
631
|
+
<sp-menu-item>14th St</sp-menu-item>
|
|
632
|
+
<sp-menu-item>Broadway</sp-menu-item>
|
|
633
|
+
<sp-menu-item>Park Ave</sp-menu-item>
|
|
634
|
+
</sp-menu>
|
|
635
|
+
</sp-menu-item>
|
|
636
|
+
<sp-menu-item>Upper East Side</sp-menu-item>
|
|
637
|
+
</sp-menu>
|
|
638
|
+
</sp-menu-item>
|
|
639
|
+
</sp-menu-group>
|
|
640
|
+
</sp-action-menu>
|
|
641
|
+
`);
|
|
642
|
+
const rootMenu1 = el.querySelector("#submenu-item-1");
|
|
643
|
+
const rootMenu2 = el.querySelector("#submenu-item-3");
|
|
644
|
+
const childMenu2 = el.querySelector("#submenu-item-2");
|
|
645
|
+
expect(el.open).to.be.false;
|
|
646
|
+
let opened = oneEvent(el, "sp-opened");
|
|
647
|
+
el.click();
|
|
648
|
+
await opened;
|
|
649
|
+
expect(el.open).to.be.true;
|
|
650
|
+
opened = oneEvent(rootMenu1, "sp-opened");
|
|
651
|
+
rootMenu1.dispatchEvent(
|
|
652
|
+
new PointerEvent("pointerenter", { bubbles: true })
|
|
653
|
+
);
|
|
654
|
+
await opened;
|
|
655
|
+
expect(rootMenu1.open).to.be.true;
|
|
656
|
+
opened = oneEvent(childMenu2, "sp-opened");
|
|
657
|
+
childMenu2.dispatchEvent(
|
|
658
|
+
new PointerEvent("pointerenter", { bubbles: true })
|
|
659
|
+
);
|
|
660
|
+
await opened;
|
|
661
|
+
expect(childMenu2.open).to.be.true;
|
|
662
|
+
const childMenu2Closed = oneEvent(childMenu2, "sp-closed");
|
|
663
|
+
const rootMenu1Closed = oneEvent(rootMenu1, "sp-closed");
|
|
664
|
+
const rootMenu2Opened = oneEvent(rootMenu2, "sp-opened");
|
|
665
|
+
rootMenu2.dispatchEvent(
|
|
666
|
+
new PointerEvent("pointerenter", { bubbles: true })
|
|
667
|
+
);
|
|
668
|
+
await childMenu2Closed;
|
|
669
|
+
await rootMenu1Closed;
|
|
670
|
+
await rootMenu2Opened;
|
|
671
|
+
});
|
|
672
|
+
describe("deep tree", () => {
|
|
673
|
+
beforeEach(async function() {
|
|
674
|
+
this.el = await fixture(html`
|
|
675
|
+
<sp-action-menu label="Deep submenu tree">
|
|
676
|
+
<sp-icon-show-menu slot="icon"></sp-icon-show-menu>
|
|
677
|
+
<sp-menu-group role="none">
|
|
678
|
+
<span slot="header">New York</span>
|
|
679
|
+
<sp-menu-item id="no-submenu">Bronx</sp-menu-item>
|
|
680
|
+
<sp-menu-item id="submenu-item-1">
|
|
681
|
+
Brooklyn
|
|
682
|
+
<sp-menu slot="submenu">
|
|
683
|
+
<sp-menu-item id="submenu-item-2">
|
|
684
|
+
Ft. Greene
|
|
685
|
+
<sp-menu slot="submenu">
|
|
686
|
+
<sp-menu-item>
|
|
687
|
+
S. Oxford St
|
|
688
|
+
</sp-menu-item>
|
|
689
|
+
<sp-menu-item>
|
|
690
|
+
S. Portland Ave
|
|
691
|
+
</sp-menu-item>
|
|
692
|
+
<sp-menu-item>
|
|
693
|
+
S. Elliot Pl
|
|
694
|
+
</sp-menu-item>
|
|
695
|
+
</sp-menu>
|
|
230
696
|
</sp-menu-item>
|
|
231
|
-
<sp-menu-item
|
|
232
|
-
|
|
697
|
+
<sp-menu-item disabled>Park Slope</sp-menu-item>
|
|
698
|
+
<sp-menu-item id="ancestor-item">
|
|
699
|
+
Williamsburg
|
|
233
700
|
</sp-menu-item>
|
|
234
|
-
|
|
235
|
-
|
|
701
|
+
</sp-menu>
|
|
702
|
+
</sp-menu-item>
|
|
703
|
+
<sp-menu-item id="submenu-item-3">
|
|
704
|
+
Manhattan
|
|
705
|
+
<sp-menu slot="submenu">
|
|
706
|
+
<sp-menu-item disabled>SoHo</sp-menu-item>
|
|
707
|
+
<sp-menu-item>
|
|
708
|
+
Union Square
|
|
709
|
+
<sp-menu slot="submenu">
|
|
710
|
+
<sp-menu-item>14th St</sp-menu-item>
|
|
711
|
+
<sp-menu-item>Broadway</sp-menu-item>
|
|
712
|
+
<sp-menu-item>Park Ave</sp-menu-item>
|
|
713
|
+
</sp-menu>
|
|
236
714
|
</sp-menu-item>
|
|
715
|
+
<sp-menu-item>Upper East Side</sp-menu-item>
|
|
237
716
|
</sp-menu>
|
|
238
717
|
</sp-menu-item>
|
|
239
|
-
</sp-menu>
|
|
240
|
-
|
|
241
|
-
|
|
718
|
+
</sp-menu-group>
|
|
719
|
+
</sp-action-menu>
|
|
720
|
+
`);
|
|
721
|
+
await nextFrame();
|
|
722
|
+
await nextFrame();
|
|
723
|
+
});
|
|
724
|
+
it("closes back to the first overlay without a `root` when clicking away", async function() {
|
|
725
|
+
const rootMenu1 = this.el.querySelector("#submenu-item-1");
|
|
726
|
+
const childMenu2 = this.el.querySelector("#submenu-item-2");
|
|
727
|
+
expect(this.el.open).to.be.false;
|
|
728
|
+
let opened = oneEvent(this.el, "sp-opened");
|
|
729
|
+
this.el.click();
|
|
730
|
+
await opened;
|
|
731
|
+
expect(this.el.open).to.be.true;
|
|
732
|
+
opened = oneEvent(rootMenu1, "sp-opened");
|
|
733
|
+
rootMenu1.dispatchEvent(
|
|
734
|
+
new PointerEvent("pointerenter", { bubbles: true })
|
|
242
735
|
);
|
|
243
|
-
await elementUpdated(el);
|
|
244
|
-
const rootItem = el.querySelector(".root");
|
|
245
|
-
const submenu = el.querySelector('[slot="submenu"]');
|
|
246
|
-
const submenuItem = el.querySelector(".submenu-item-2");
|
|
247
|
-
expect(rootItem.open).to.be.false;
|
|
248
|
-
el.focus();
|
|
249
|
-
await elementUpdated(el);
|
|
250
|
-
let opened = oneEvent(rootItem, "sp-opened");
|
|
251
|
-
await sendKeys({
|
|
252
|
-
press: testData.openKey
|
|
253
|
-
});
|
|
254
736
|
await opened;
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
737
|
+
opened = oneEvent(childMenu2, "sp-opened");
|
|
738
|
+
childMenu2.dispatchEvent(
|
|
739
|
+
new PointerEvent("pointerenter", { bubbles: true })
|
|
740
|
+
);
|
|
741
|
+
await opened;
|
|
742
|
+
const closed = Promise.all([
|
|
743
|
+
oneEvent(childMenu2, "sp-closed"),
|
|
744
|
+
oneEvent(rootMenu1, "sp-closed"),
|
|
745
|
+
oneEvent(this.el, "sp-closed")
|
|
746
|
+
]);
|
|
747
|
+
await sendMouse({
|
|
748
|
+
steps: [
|
|
749
|
+
{
|
|
750
|
+
type: "click",
|
|
751
|
+
position: [600, 5]
|
|
752
|
+
}
|
|
753
|
+
]
|
|
263
754
|
});
|
|
264
755
|
await closed;
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
)
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
756
|
+
});
|
|
757
|
+
it("closes decendent menus when Menu Item in ancestor without a submenu is pointerentered", async function() {
|
|
758
|
+
const rootMenu = this.el.querySelector(
|
|
759
|
+
"#submenu-item-1"
|
|
760
|
+
);
|
|
761
|
+
const noSubmenu = this.el.querySelector("#no-submenu");
|
|
762
|
+
expect(this.el.open).to.be.false;
|
|
763
|
+
let opened = oneEvent(this.el, "sp-opened");
|
|
764
|
+
this.el.click();
|
|
274
765
|
await opened;
|
|
275
|
-
expect(
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
await
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
await
|
|
286
|
-
press: "Enter"
|
|
287
|
-
});
|
|
288
|
-
await closed;
|
|
289
|
-
expect(submenuChanged.calledWith("Two"), "submenu changed").to.be.true;
|
|
290
|
-
expect(rootChanged.called, "root has changed").to.be.true;
|
|
291
|
-
expect(
|
|
292
|
-
rootChanged.calledWith("Has submenu"),
|
|
293
|
-
"root specifically changed"
|
|
294
|
-
).to.be.true;
|
|
295
|
-
});
|
|
296
|
-
});
|
|
297
|
-
it("closes on `pointerleave`", async () => {
|
|
298
|
-
const el = await fixture(
|
|
299
|
-
html`
|
|
300
|
-
<sp-menu>
|
|
301
|
-
<sp-menu-item class="root">
|
|
302
|
-
Has submenu
|
|
303
|
-
<sp-menu slot="submenu">
|
|
304
|
-
<sp-menu-item class="submenu-item-1">
|
|
305
|
-
One
|
|
306
|
-
</sp-menu-item>
|
|
307
|
-
<sp-menu-item class="submenu-item-2">
|
|
308
|
-
Two
|
|
309
|
-
</sp-menu-item>
|
|
310
|
-
<sp-menu-item class="submenu-item-3">
|
|
311
|
-
Three
|
|
312
|
-
</sp-menu-item>
|
|
313
|
-
</sp-menu>
|
|
314
|
-
</sp-menu-item>
|
|
315
|
-
</sp-menu>
|
|
316
|
-
`
|
|
317
|
-
);
|
|
318
|
-
await elementUpdated(el);
|
|
319
|
-
const rootItem = el.querySelector(".root");
|
|
320
|
-
const rootItemBoundingRect = rootItem.getBoundingClientRect();
|
|
321
|
-
expect(rootItem.open).to.be.false;
|
|
322
|
-
const opened = oneEvent(rootItem, "sp-opened");
|
|
323
|
-
await sendMouse({
|
|
324
|
-
steps: [
|
|
325
|
-
{
|
|
326
|
-
type: "move",
|
|
327
|
-
position: [
|
|
328
|
-
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
329
|
-
rootItemBoundingRect.top + rootItemBoundingRect.height / 2
|
|
330
|
-
]
|
|
331
|
-
}
|
|
332
|
-
]
|
|
333
|
-
});
|
|
334
|
-
await opened;
|
|
335
|
-
expect(rootItem.open).to.be.true;
|
|
336
|
-
const closed = oneEvent(rootItem, "sp-closed");
|
|
337
|
-
await sendMouse({
|
|
338
|
-
steps: [
|
|
339
|
-
{
|
|
340
|
-
type: "move",
|
|
341
|
-
position: [
|
|
342
|
-
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
343
|
-
rootItemBoundingRect.top + rootItemBoundingRect.height * 2
|
|
344
|
-
]
|
|
345
|
-
}
|
|
346
|
-
]
|
|
347
|
-
});
|
|
348
|
-
await closed;
|
|
349
|
-
expect(rootItem.open).to.be.false;
|
|
350
|
-
});
|
|
351
|
-
it("stays open when mousing off menu item and back again", async () => {
|
|
352
|
-
const el = await fixture(
|
|
353
|
-
html`
|
|
354
|
-
<sp-menu>
|
|
355
|
-
<sp-menu-item class="root">
|
|
356
|
-
Has submenu
|
|
357
|
-
<sp-menu slot="submenu">
|
|
358
|
-
<sp-menu-item class="submenu-item-1">
|
|
359
|
-
One
|
|
360
|
-
</sp-menu-item>
|
|
361
|
-
<sp-menu-item class="submenu-item-2">
|
|
362
|
-
Two
|
|
363
|
-
</sp-menu-item>
|
|
364
|
-
<sp-menu-item class="submenu-item-3">
|
|
365
|
-
Three
|
|
366
|
-
</sp-menu-item>
|
|
367
|
-
</sp-menu>
|
|
368
|
-
</sp-menu-item>
|
|
369
|
-
</sp-menu>
|
|
370
|
-
`
|
|
371
|
-
);
|
|
372
|
-
await elementUpdated(el);
|
|
373
|
-
const rootItem = el.querySelector(".root");
|
|
374
|
-
const rootItemBoundingRect = rootItem.getBoundingClientRect();
|
|
375
|
-
expect(rootItem.open).to.be.false;
|
|
376
|
-
const opened = oneEvent(rootItem, "sp-opened");
|
|
377
|
-
await sendMouse({
|
|
378
|
-
steps: [
|
|
379
|
-
{
|
|
380
|
-
type: "move",
|
|
381
|
-
position: [
|
|
382
|
-
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
383
|
-
rootItemBoundingRect.top + rootItemBoundingRect.height / 2
|
|
384
|
-
]
|
|
385
|
-
}
|
|
386
|
-
]
|
|
387
|
-
});
|
|
388
|
-
await sendMouse({
|
|
389
|
-
steps: [
|
|
390
|
-
{
|
|
391
|
-
type: "move",
|
|
392
|
-
position: [
|
|
393
|
-
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
394
|
-
rootItemBoundingRect.top + rootItemBoundingRect.height * 2
|
|
395
|
-
]
|
|
396
|
-
}
|
|
397
|
-
]
|
|
398
|
-
});
|
|
399
|
-
await sendMouse({
|
|
400
|
-
steps: [
|
|
401
|
-
{
|
|
402
|
-
type: "move",
|
|
403
|
-
position: [
|
|
404
|
-
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
405
|
-
rootItemBoundingRect.top + rootItemBoundingRect.height / 2
|
|
406
|
-
]
|
|
407
|
-
}
|
|
408
|
-
]
|
|
409
|
-
});
|
|
410
|
-
await opened;
|
|
411
|
-
expect(rootItem.open).to.be.true;
|
|
412
|
-
const closed = oneEvent(rootItem, "sp-closed");
|
|
413
|
-
await sendMouse({
|
|
414
|
-
steps: [
|
|
415
|
-
{
|
|
416
|
-
type: "move",
|
|
417
|
-
position: [
|
|
418
|
-
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
419
|
-
rootItemBoundingRect.top + rootItemBoundingRect.height * 2
|
|
420
|
-
]
|
|
421
|
-
}
|
|
422
|
-
]
|
|
423
|
-
});
|
|
424
|
-
await closed;
|
|
425
|
-
});
|
|
426
|
-
it("continues to open when mousing between menu item and submenu", async function() {
|
|
427
|
-
const clickSpy = spy();
|
|
428
|
-
const el = await fixture(
|
|
429
|
-
html`
|
|
430
|
-
<sp-menu>
|
|
431
|
-
<sp-menu-item class="root">
|
|
432
|
-
Has submenu
|
|
433
|
-
<sp-menu slot="submenu">
|
|
434
|
-
<sp-menu-item class="submenu-item-1">
|
|
435
|
-
One
|
|
436
|
-
</sp-menu-item>
|
|
437
|
-
<sp-menu-item
|
|
438
|
-
class="submenu-item-2"
|
|
439
|
-
@click=${() => clickSpy()}
|
|
440
|
-
>
|
|
441
|
-
Two
|
|
442
|
-
</sp-menu-item>
|
|
443
|
-
<sp-menu-item class="submenu-item-3">
|
|
444
|
-
Three
|
|
445
|
-
</sp-menu-item>
|
|
446
|
-
</sp-menu>
|
|
447
|
-
</sp-menu-item>
|
|
448
|
-
</sp-menu>
|
|
449
|
-
`
|
|
450
|
-
);
|
|
451
|
-
await elementUpdated(el);
|
|
452
|
-
const rootItem = el.querySelector(".root");
|
|
453
|
-
const subItem = el.querySelector(".submenu-item-2");
|
|
454
|
-
const rootItemBoundingRect = rootItem.getBoundingClientRect();
|
|
455
|
-
expect(rootItem.open).to.be.false;
|
|
456
|
-
const opened = oneEvent(rootItem, "sp-opened");
|
|
457
|
-
await sendMouse({
|
|
458
|
-
steps: [
|
|
459
|
-
{
|
|
460
|
-
type: "move",
|
|
461
|
-
position: [
|
|
462
|
-
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
463
|
-
rootItemBoundingRect.top + rootItemBoundingRect.height / 2
|
|
464
|
-
]
|
|
465
|
-
}
|
|
466
|
-
]
|
|
467
|
-
});
|
|
468
|
-
await nextFrame();
|
|
469
|
-
await nextFrame();
|
|
470
|
-
await nextFrame();
|
|
471
|
-
await nextFrame();
|
|
472
|
-
await nextFrame();
|
|
473
|
-
await nextFrame();
|
|
474
|
-
await nextFrame();
|
|
475
|
-
await nextFrame();
|
|
476
|
-
const subItemBoundingRect = subItem.getBoundingClientRect();
|
|
477
|
-
await sendMouse({
|
|
478
|
-
steps: [
|
|
479
|
-
{
|
|
480
|
-
type: "move",
|
|
481
|
-
position: [
|
|
482
|
-
subItemBoundingRect.left + subItemBoundingRect.width / 2,
|
|
483
|
-
subItemBoundingRect.top + subItemBoundingRect.height / 2
|
|
484
|
-
]
|
|
485
|
-
}
|
|
486
|
-
]
|
|
487
|
-
});
|
|
488
|
-
await opened;
|
|
489
|
-
expect(rootItem.open).to.be.true;
|
|
490
|
-
await aTimeout(150);
|
|
491
|
-
expect(rootItem.open).to.be.true;
|
|
492
|
-
const closed = oneEvent(rootItem, "sp-closed");
|
|
493
|
-
await sendMouse({
|
|
494
|
-
steps: [
|
|
495
|
-
{
|
|
496
|
-
type: "click",
|
|
497
|
-
position: [
|
|
498
|
-
subItemBoundingRect.left + subItemBoundingRect.width / 2,
|
|
499
|
-
subItemBoundingRect.top + subItemBoundingRect.height / 2
|
|
500
|
-
]
|
|
501
|
-
}
|
|
502
|
-
]
|
|
503
|
-
});
|
|
504
|
-
await closed;
|
|
505
|
-
expect(clickSpy.callCount).to.equal(1);
|
|
506
|
-
});
|
|
507
|
-
it("stays open when mousing between menu item and submenu", async () => {
|
|
508
|
-
const clickSpy = spy();
|
|
509
|
-
const el = await fixture(
|
|
510
|
-
html`
|
|
511
|
-
<sp-menu>
|
|
512
|
-
<sp-menu-item class="root">
|
|
513
|
-
Has submenu
|
|
514
|
-
<sp-menu slot="submenu">
|
|
515
|
-
<sp-menu-item class="submenu-item-1">
|
|
516
|
-
One
|
|
517
|
-
</sp-menu-item>
|
|
518
|
-
<sp-menu-item
|
|
519
|
-
class="submenu-item-2"
|
|
520
|
-
@click=${() => clickSpy()}
|
|
521
|
-
>
|
|
522
|
-
Two
|
|
523
|
-
</sp-menu-item>
|
|
524
|
-
<sp-menu-item class="submenu-item-3">
|
|
525
|
-
Three
|
|
526
|
-
</sp-menu-item>
|
|
527
|
-
</sp-menu>
|
|
528
|
-
</sp-menu-item>
|
|
529
|
-
</sp-menu>
|
|
530
|
-
`
|
|
531
|
-
);
|
|
532
|
-
await elementUpdated(el);
|
|
533
|
-
const rootItem = el.querySelector(".root");
|
|
534
|
-
const subItem = el.querySelector(".submenu-item-2");
|
|
535
|
-
const rootItemBoundingRect = rootItem.getBoundingClientRect();
|
|
536
|
-
expect(rootItem.open).to.be.false;
|
|
537
|
-
const opened = oneEvent(rootItem, "sp-opened");
|
|
538
|
-
await sendMouse({
|
|
539
|
-
steps: [
|
|
540
|
-
{
|
|
541
|
-
type: "move",
|
|
542
|
-
position: [
|
|
543
|
-
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
544
|
-
rootItemBoundingRect.top + rootItemBoundingRect.height / 2
|
|
545
|
-
]
|
|
546
|
-
}
|
|
547
|
-
]
|
|
548
|
-
});
|
|
549
|
-
await opened;
|
|
550
|
-
await nextFrame();
|
|
551
|
-
await nextFrame();
|
|
552
|
-
const subItemBoundingRect = subItem.getBoundingClientRect();
|
|
553
|
-
expect(rootItem.open).to.be.true;
|
|
554
|
-
await sendMouse({
|
|
555
|
-
steps: [
|
|
556
|
-
{
|
|
557
|
-
type: "move",
|
|
558
|
-
position: [
|
|
559
|
-
subItemBoundingRect.left + subItemBoundingRect.width / 2,
|
|
560
|
-
subItemBoundingRect.top + subItemBoundingRect.height / 2
|
|
561
|
-
]
|
|
562
|
-
}
|
|
563
|
-
]
|
|
564
|
-
});
|
|
565
|
-
expect(rootItem.open).to.be.true;
|
|
566
|
-
await aTimeout(150);
|
|
567
|
-
expect(rootItem.open).to.be.true;
|
|
568
|
-
const closed = oneEvent(rootItem, "sp-closed");
|
|
569
|
-
await sendMouse({
|
|
570
|
-
steps: [
|
|
571
|
-
{
|
|
572
|
-
type: "click",
|
|
573
|
-
position: [
|
|
574
|
-
subItemBoundingRect.left + subItemBoundingRect.width / 2,
|
|
575
|
-
subItemBoundingRect.top + subItemBoundingRect.height / 2
|
|
576
|
-
]
|
|
577
|
-
}
|
|
578
|
-
]
|
|
579
|
-
});
|
|
580
|
-
await closed;
|
|
581
|
-
expect(clickSpy.callCount).to.equal(1);
|
|
582
|
-
});
|
|
583
|
-
it("not opens if disabled", async () => {
|
|
584
|
-
const el = await fixture(
|
|
585
|
-
html`
|
|
586
|
-
<sp-menu>
|
|
587
|
-
<sp-menu-item disabled class="root">
|
|
588
|
-
Has submenu
|
|
589
|
-
<sp-menu slot="submenu">
|
|
590
|
-
<sp-menu-item class="submenu-item-1">
|
|
591
|
-
One
|
|
592
|
-
</sp-menu-item>
|
|
593
|
-
<sp-menu-item class="submenu-item-2">
|
|
594
|
-
Two
|
|
595
|
-
</sp-menu-item>
|
|
596
|
-
<sp-menu-item class="submenu-item-3">
|
|
597
|
-
Three
|
|
598
|
-
</sp-menu-item>
|
|
599
|
-
</sp-menu>
|
|
600
|
-
</sp-menu-item>
|
|
601
|
-
</sp-menu>
|
|
602
|
-
`
|
|
603
|
-
);
|
|
604
|
-
await elementUpdated(el);
|
|
605
|
-
const rootItem = el.querySelector(".root");
|
|
606
|
-
const rootItemBoundingRect = rootItem.getBoundingClientRect();
|
|
607
|
-
expect(rootItem.open).to.be.false;
|
|
608
|
-
await sendMouse({
|
|
609
|
-
steps: [
|
|
610
|
-
{
|
|
611
|
-
type: "move",
|
|
612
|
-
position: [
|
|
613
|
-
rootItemBoundingRect.left + rootItemBoundingRect.width / 2,
|
|
614
|
-
rootItemBoundingRect.top + rootItemBoundingRect.height / 2
|
|
615
|
-
]
|
|
616
|
-
}
|
|
617
|
-
]
|
|
618
|
-
});
|
|
619
|
-
await new Promise((r) => setTimeout(r, 200));
|
|
620
|
-
expect(rootItem.open).to.be.false;
|
|
621
|
-
});
|
|
622
|
-
it("closes all decendent submenus when closing a ancestor menu", async () => {
|
|
623
|
-
const el = await fixture(html`
|
|
624
|
-
<sp-action-menu>
|
|
625
|
-
<sp-icon-show-menu slot="icon"></sp-icon-show-menu>
|
|
626
|
-
<sp-menu-group role="none" id="group">
|
|
627
|
-
<span slot="header">New York</span>
|
|
628
|
-
<sp-menu-item>Bronx</sp-menu-item>
|
|
629
|
-
<sp-menu-item id="submenu-item-1">
|
|
630
|
-
Brooklyn
|
|
631
|
-
<sp-menu slot="submenu" id="submenu-1">
|
|
632
|
-
<sp-menu-item id="submenu-item-2">
|
|
633
|
-
Ft. Greene
|
|
634
|
-
<sp-menu slot="submenu" id="submenu-2">
|
|
635
|
-
<sp-menu-item>S. Oxford St</sp-menu-item>
|
|
636
|
-
<sp-menu-item>S. Portland Ave</sp-menu-item>
|
|
637
|
-
<sp-menu-item>S. Elliot Pl</sp-menu-item>
|
|
638
|
-
</sp-menu>
|
|
639
|
-
</sp-menu-item>
|
|
640
|
-
<sp-menu-item disabled>Park Slope</sp-menu-item>
|
|
641
|
-
<sp-menu-item>Williamsburg</sp-menu-item>
|
|
642
|
-
</sp-menu>
|
|
643
|
-
</sp-menu-item>
|
|
644
|
-
<sp-menu-item id="submenu-item-3">
|
|
645
|
-
Manhattan
|
|
646
|
-
<sp-menu slot="submenu" id="submenu-3">
|
|
647
|
-
<sp-menu-item disabled>SoHo</sp-menu-item>
|
|
648
|
-
<sp-menu-item>
|
|
649
|
-
Union Square
|
|
650
|
-
<sp-menu slot="submenu">
|
|
651
|
-
<sp-menu-item>14th St</sp-menu-item>
|
|
652
|
-
<sp-menu-item>Broadway</sp-menu-item>
|
|
653
|
-
<sp-menu-item>Park Ave</sp-menu-item>
|
|
654
|
-
</sp-menu>
|
|
655
|
-
</sp-menu-item>
|
|
656
|
-
<sp-menu-item>Upper East Side</sp-menu-item>
|
|
657
|
-
</sp-menu>
|
|
658
|
-
</sp-menu-item>
|
|
659
|
-
</sp-menu-group>
|
|
660
|
-
</sp-action-menu>
|
|
661
|
-
`);
|
|
662
|
-
const rootMenu1 = el.querySelector("#submenu-item-1");
|
|
663
|
-
const rootMenu2 = el.querySelector("#submenu-item-3");
|
|
664
|
-
const childMenu2 = el.querySelector("#submenu-item-2");
|
|
665
|
-
expect(el.open).to.be.false;
|
|
666
|
-
let opened = oneEvent(el, "sp-opened");
|
|
667
|
-
el.click();
|
|
668
|
-
await opened;
|
|
669
|
-
expect(el.open).to.be.true;
|
|
670
|
-
opened = oneEvent(rootMenu1, "sp-opened");
|
|
671
|
-
rootMenu1.dispatchEvent(
|
|
672
|
-
new PointerEvent("pointerenter", { bubbles: true })
|
|
673
|
-
);
|
|
674
|
-
await opened;
|
|
675
|
-
expect(rootMenu1.open).to.be.true;
|
|
676
|
-
opened = oneEvent(childMenu2, "sp-opened");
|
|
677
|
-
childMenu2.dispatchEvent(
|
|
678
|
-
new PointerEvent("pointerenter", { bubbles: true })
|
|
679
|
-
);
|
|
680
|
-
await opened;
|
|
681
|
-
expect(childMenu2.open).to.be.true;
|
|
682
|
-
const childMenu2Closed = oneEvent(childMenu2, "sp-closed");
|
|
683
|
-
const rootMenu1Closed = oneEvent(rootMenu1, "sp-closed");
|
|
684
|
-
const rootMenu2Opened = oneEvent(rootMenu2, "sp-opened");
|
|
685
|
-
rootMenu2.dispatchEvent(
|
|
686
|
-
new PointerEvent("pointerenter", { bubbles: true })
|
|
687
|
-
);
|
|
688
|
-
await childMenu2Closed;
|
|
689
|
-
await rootMenu1Closed;
|
|
690
|
-
await rootMenu2Opened;
|
|
691
|
-
});
|
|
692
|
-
it("closes back to the first overlay without a `root` when clicking away", async function() {
|
|
693
|
-
const el = await fixture(html`
|
|
694
|
-
<sp-action-menu>
|
|
695
|
-
<sp-icon-show-menu slot="icon"></sp-icon-show-menu>
|
|
696
|
-
<sp-menu-group role="none">
|
|
697
|
-
<span slot="header">New York</span>
|
|
698
|
-
<sp-menu-item>Bronx</sp-menu-item>
|
|
699
|
-
<sp-menu-item id="submenu-item-1">
|
|
700
|
-
Brooklyn
|
|
701
|
-
<sp-menu slot="submenu">
|
|
702
|
-
<sp-menu-item id="submenu-item-2">
|
|
703
|
-
Ft. Greene
|
|
704
|
-
<sp-menu slot="submenu">
|
|
705
|
-
<sp-menu-item>S. Oxford St</sp-menu-item>
|
|
706
|
-
<sp-menu-item>S. Portland Ave</sp-menu-item>
|
|
707
|
-
<sp-menu-item>S. Elliot Pl</sp-menu-item>
|
|
708
|
-
</sp-menu>
|
|
709
|
-
</sp-menu-item>
|
|
710
|
-
<sp-menu-item disabled>Park Slope</sp-menu-item>
|
|
711
|
-
<sp-menu-item>Williamsburg</sp-menu-item>
|
|
712
|
-
</sp-menu>
|
|
713
|
-
</sp-menu-item>
|
|
714
|
-
<sp-menu-item id="submenu-item-3">
|
|
715
|
-
Manhattan
|
|
716
|
-
<sp-menu slot="submenu">
|
|
717
|
-
<sp-menu-item disabled>SoHo</sp-menu-item>
|
|
718
|
-
<sp-menu-item>
|
|
719
|
-
Union Square
|
|
720
|
-
<sp-menu slot="submenu">
|
|
721
|
-
<sp-menu-item>14th St</sp-menu-item>
|
|
722
|
-
<sp-menu-item>Broadway</sp-menu-item>
|
|
723
|
-
<sp-menu-item>Park Ave</sp-menu-item>
|
|
724
|
-
</sp-menu>
|
|
725
|
-
</sp-menu-item>
|
|
726
|
-
<sp-menu-item>Upper East Side</sp-menu-item>
|
|
727
|
-
</sp-menu>
|
|
728
|
-
</sp-menu-item>
|
|
729
|
-
</sp-menu-group>
|
|
730
|
-
</sp-action-menu>
|
|
731
|
-
`);
|
|
732
|
-
const rootMenu1 = el.querySelector("#submenu-item-1");
|
|
733
|
-
const childMenu2 = el.querySelector("#submenu-item-2");
|
|
734
|
-
expect(el.open).to.be.false;
|
|
735
|
-
let opened = oneEvent(el, "sp-opened");
|
|
736
|
-
el.click();
|
|
737
|
-
await opened;
|
|
738
|
-
expect(el.open).to.be.true;
|
|
739
|
-
opened = oneEvent(rootMenu1, "sp-opened");
|
|
740
|
-
rootMenu1.dispatchEvent(
|
|
741
|
-
new PointerEvent("pointerenter", { bubbles: true })
|
|
742
|
-
);
|
|
743
|
-
await opened;
|
|
744
|
-
opened = oneEvent(childMenu2, "sp-opened");
|
|
745
|
-
childMenu2.dispatchEvent(
|
|
746
|
-
new PointerEvent("pointerenter", { bubbles: true })
|
|
747
|
-
);
|
|
748
|
-
await opened;
|
|
749
|
-
const closed = Promise.all([
|
|
750
|
-
oneEvent(childMenu2, "sp-closed"),
|
|
751
|
-
oneEvent(rootMenu1, "sp-closed"),
|
|
752
|
-
oneEvent(el, "sp-closed")
|
|
753
|
-
]);
|
|
754
|
-
await sendMouse({
|
|
755
|
-
steps: [
|
|
756
|
-
{
|
|
757
|
-
type: "click",
|
|
758
|
-
position: [600, 5]
|
|
759
|
-
}
|
|
760
|
-
]
|
|
766
|
+
expect(this.el.open).to.be.true;
|
|
767
|
+
opened = oneEvent(rootMenu, "sp-opened");
|
|
768
|
+
rootMenu.dispatchEvent(
|
|
769
|
+
new PointerEvent("pointerenter", { bubbles: true })
|
|
770
|
+
);
|
|
771
|
+
await opened;
|
|
772
|
+
const closed = oneEvent(rootMenu, "sp-closed");
|
|
773
|
+
noSubmenu.dispatchEvent(
|
|
774
|
+
new PointerEvent("pointerenter", { bubbles: true })
|
|
775
|
+
);
|
|
776
|
+
await closed;
|
|
761
777
|
});
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
await opened;
|
|
806
|
-
const closed = oneEvent(rootMenu, "sp-closed");
|
|
807
|
-
noSubmenu.dispatchEvent(
|
|
808
|
-
new PointerEvent("pointerenter", { bubbles: true })
|
|
809
|
-
);
|
|
810
|
-
await closed;
|
|
811
|
-
});
|
|
812
|
-
it("closes decendent menus when Menu Item in ancestor is clicked", async function() {
|
|
813
|
-
const el = await fixture(html`
|
|
814
|
-
<sp-action-menu>
|
|
815
|
-
<sp-icon-show-menu slot="icon"></sp-icon-show-menu>
|
|
816
|
-
<sp-menu-group role="none">
|
|
817
|
-
<span slot="header">New York</span>
|
|
818
|
-
<sp-menu-item>Bronx</sp-menu-item>
|
|
819
|
-
<sp-menu-item id="submenu-item-1">
|
|
820
|
-
Brooklyn
|
|
821
|
-
<sp-menu slot="submenu">
|
|
822
|
-
<sp-menu-item id="submenu-item-2">
|
|
823
|
-
Ft. Greene
|
|
824
|
-
<sp-menu slot="submenu">
|
|
825
|
-
<sp-menu-item>S. Oxford St</sp-menu-item>
|
|
826
|
-
<sp-menu-item>S. Portland Ave</sp-menu-item>
|
|
827
|
-
<sp-menu-item>S. Elliot Pl</sp-menu-item>
|
|
828
|
-
</sp-menu>
|
|
829
|
-
</sp-menu-item>
|
|
830
|
-
<sp-menu-item disabled>Park Slope</sp-menu-item>
|
|
831
|
-
<sp-menu-item id="ancestor-item">
|
|
832
|
-
Williamsburg
|
|
833
|
-
</sp-menu-item>
|
|
834
|
-
</sp-menu>
|
|
835
|
-
</sp-menu-item>
|
|
836
|
-
<sp-menu-item id="submenu-item-3">
|
|
837
|
-
Manhattan
|
|
838
|
-
<sp-menu slot="submenu">
|
|
839
|
-
<sp-menu-item disabled>SoHo</sp-menu-item>
|
|
840
|
-
<sp-menu-item>
|
|
841
|
-
Union Square
|
|
842
|
-
<sp-menu slot="submenu">
|
|
843
|
-
<sp-menu-item>14th St</sp-menu-item>
|
|
844
|
-
<sp-menu-item>Broadway</sp-menu-item>
|
|
845
|
-
<sp-menu-item>Park Ave</sp-menu-item>
|
|
846
|
-
</sp-menu>
|
|
847
|
-
</sp-menu-item>
|
|
848
|
-
<sp-menu-item>Upper East Side</sp-menu-item>
|
|
849
|
-
</sp-menu>
|
|
850
|
-
</sp-menu-item>
|
|
851
|
-
</sp-menu-group>
|
|
852
|
-
</sp-action-menu>
|
|
853
|
-
`);
|
|
854
|
-
await nextFrame();
|
|
855
|
-
await nextFrame();
|
|
856
|
-
const rootMenu1 = el.querySelector("#submenu-item-1");
|
|
857
|
-
const childMenu2 = el.querySelector("#submenu-item-2");
|
|
858
|
-
const ancestorItem = el.querySelector("#ancestor-item");
|
|
859
|
-
expect(el.open).to.be.false;
|
|
860
|
-
let opened = oneEvent(el, "sp-opened");
|
|
861
|
-
el.click();
|
|
862
|
-
await opened;
|
|
863
|
-
expect(el.open).to.be.true;
|
|
864
|
-
opened = oneEvent(rootMenu1, "sp-opened");
|
|
865
|
-
rootMenu1.dispatchEvent(
|
|
866
|
-
new PointerEvent("pointerenter", { bubbles: true })
|
|
867
|
-
);
|
|
868
|
-
await opened;
|
|
869
|
-
opened = oneEvent(childMenu2, "sp-opened");
|
|
870
|
-
childMenu2.dispatchEvent(
|
|
871
|
-
new PointerEvent("pointerenter", { bubbles: true })
|
|
872
|
-
);
|
|
873
|
-
await opened;
|
|
874
|
-
const closed = Promise.all([
|
|
875
|
-
oneEvent(childMenu2, "sp-closed"),
|
|
876
|
-
oneEvent(rootMenu1, "sp-closed"),
|
|
877
|
-
oneEvent(el, "sp-closed")
|
|
878
|
-
]);
|
|
879
|
-
const rect = ancestorItem.getBoundingClientRect();
|
|
880
|
-
await sendMouse({
|
|
881
|
-
steps: [
|
|
882
|
-
{
|
|
883
|
-
type: "click",
|
|
884
|
-
position: [
|
|
885
|
-
rect.left + rect.width / 2,
|
|
886
|
-
rect.top + rect.height / 2
|
|
887
|
-
]
|
|
888
|
-
}
|
|
889
|
-
]
|
|
778
|
+
it("closes decendent menus when Menu Item in ancestor is clicked", async function() {
|
|
779
|
+
const rootMenu1 = this.el.querySelector(
|
|
780
|
+
"#submenu-item-1"
|
|
781
|
+
);
|
|
782
|
+
const childMenu2 = this.el.querySelector(
|
|
783
|
+
"#submenu-item-2"
|
|
784
|
+
);
|
|
785
|
+
const ancestorItem = this.el.querySelector(
|
|
786
|
+
"#ancestor-item"
|
|
787
|
+
);
|
|
788
|
+
expect(this.el.open).to.be.false;
|
|
789
|
+
let opened = oneEvent(this.el, "sp-opened");
|
|
790
|
+
this.el.click();
|
|
791
|
+
await opened;
|
|
792
|
+
expect(this.el.open).to.be.true;
|
|
793
|
+
opened = oneEvent(rootMenu1, "sp-opened");
|
|
794
|
+
rootMenu1.dispatchEvent(
|
|
795
|
+
new PointerEvent("pointerenter", { bubbles: true })
|
|
796
|
+
);
|
|
797
|
+
await opened;
|
|
798
|
+
opened = oneEvent(childMenu2, "sp-opened");
|
|
799
|
+
childMenu2.dispatchEvent(
|
|
800
|
+
new PointerEvent("pointerenter", { bubbles: true })
|
|
801
|
+
);
|
|
802
|
+
await opened;
|
|
803
|
+
const closed = Promise.all([
|
|
804
|
+
oneEvent(childMenu2, "sp-closed"),
|
|
805
|
+
oneEvent(rootMenu1, "sp-closed"),
|
|
806
|
+
oneEvent(this.el, "sp-closed")
|
|
807
|
+
]);
|
|
808
|
+
const rect = ancestorItem.getBoundingClientRect();
|
|
809
|
+
await sendMouse({
|
|
810
|
+
steps: [
|
|
811
|
+
{
|
|
812
|
+
type: "click",
|
|
813
|
+
position: [
|
|
814
|
+
rect.left + rect.width / 2,
|
|
815
|
+
rect.top + rect.height / 2
|
|
816
|
+
]
|
|
817
|
+
}
|
|
818
|
+
]
|
|
819
|
+
});
|
|
820
|
+
await closed;
|
|
890
821
|
});
|
|
891
|
-
await closed;
|
|
892
822
|
});
|
|
893
823
|
it('cleans up submenus that close before they are "open"', async () => {
|
|
894
824
|
if ("showPopover" in document.createElement("div")) {
|
|
@@ -907,31 +837,11 @@ describe("Submenu", () => {
|
|
|
907
837
|
<sp-menu>
|
|
908
838
|
<sp-menu-item class="root-1">
|
|
909
839
|
Has submenu
|
|
910
|
-
<sp-menu slot="submenu">
|
|
911
|
-
<sp-menu-item class="submenu-item-1">
|
|
912
|
-
One
|
|
913
|
-
</sp-menu-item>
|
|
914
|
-
<sp-menu-item class="submenu-item-2">
|
|
915
|
-
Two
|
|
916
|
-
</sp-menu-item>
|
|
917
|
-
<sp-menu-item class="submenu-item-3">
|
|
918
|
-
Three
|
|
919
|
-
</sp-menu-item>
|
|
920
|
-
</sp-menu>
|
|
840
|
+
<sp-menu slot="submenu">${renderSubmenu()}</sp-menu>
|
|
921
841
|
</sp-menu-item>
|
|
922
842
|
<sp-menu-item class="root-2">
|
|
923
843
|
Has submenu
|
|
924
|
-
<sp-menu slot="submenu">
|
|
925
|
-
<sp-menu-item class="submenu-item-1">
|
|
926
|
-
One
|
|
927
|
-
</sp-menu-item>
|
|
928
|
-
<sp-menu-item class="submenu-item-2">
|
|
929
|
-
Two
|
|
930
|
-
</sp-menu-item>
|
|
931
|
-
<sp-menu-item class="submenu-item-3">
|
|
932
|
-
Three
|
|
933
|
-
</sp-menu-item>
|
|
934
|
-
</sp-menu>
|
|
844
|
+
<sp-menu slot="submenu">${renderSubmenu()}</sp-menu>
|
|
935
845
|
</sp-menu-item>
|
|
936
846
|
</sp-menu>
|
|
937
847
|
`
|