@spectrum-web-components/action-group 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/package.json +7 -6
- package/stories/action-group-sizes.stories.js +140 -0
- package/stories/action-group-sizes.stories.js.map +7 -0
- package/stories/action-group-tooltip.stories.js +388 -0
- package/stories/action-group-tooltip.stories.js.map +7 -0
- package/stories/action-group.stories.js +327 -0
- package/stories/action-group.stories.js.map +7 -0
- package/test/action-group-memory.test.js +5 -0
- package/test/action-group-memory.test.js.map +7 -0
- package/test/action-group-sizes.test-vrt.js +5 -0
- package/test/action-group-sizes.test-vrt.js.map +7 -0
- package/test/action-group-tooltip.test-vrt.js +5 -0
- package/test/action-group-tooltip.test-vrt.js.map +7 -0
- package/test/action-group.test-vrt.js +5 -0
- package/test/action-group.test-vrt.js.map +7 -0
- package/test/action-group.test.js +1249 -0
- package/test/action-group.test.js.map +7 -0
- package/test/benchmark/basic-test.js +13 -0
- package/test/benchmark/basic-test.js.map +7 -0
|
@@ -0,0 +1,1249 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import {
|
|
3
|
+
aTimeout,
|
|
4
|
+
elementUpdated,
|
|
5
|
+
expect,
|
|
6
|
+
fixture,
|
|
7
|
+
html,
|
|
8
|
+
nextFrame,
|
|
9
|
+
oneEvent,
|
|
10
|
+
waitUntil
|
|
11
|
+
} from "@open-wc/testing";
|
|
12
|
+
import "@spectrum-web-components/action-button/sp-action-button.js";
|
|
13
|
+
import "@spectrum-web-components/action-menu/sp-action-menu.js";
|
|
14
|
+
import "@spectrum-web-components/menu/sp-menu.js";
|
|
15
|
+
import "@spectrum-web-components/menu/sp-menu-item.js";
|
|
16
|
+
import "@spectrum-web-components/picker/sp-picker.js";
|
|
17
|
+
import {
|
|
18
|
+
LitElement
|
|
19
|
+
} from "@spectrum-web-components/base";
|
|
20
|
+
import "@spectrum-web-components/overlay/overlay-trigger.js";
|
|
21
|
+
import "@spectrum-web-components/tooltip/sp-tooltip.js";
|
|
22
|
+
import {
|
|
23
|
+
arrowDownEvent,
|
|
24
|
+
arrowLeftEvent,
|
|
25
|
+
arrowRightEvent,
|
|
26
|
+
arrowUpEvent,
|
|
27
|
+
endEvent,
|
|
28
|
+
homeEvent,
|
|
29
|
+
testForLitDevWarnings
|
|
30
|
+
} from "../../../test/testing-helpers";
|
|
31
|
+
import { sendKeys } from "@web/test-runner-commands";
|
|
32
|
+
import "@spectrum-web-components/action-group/sp-action-group.js";
|
|
33
|
+
import { controlled } from "../stories/action-group-tooltip.stories.js";
|
|
34
|
+
import { spy } from "sinon";
|
|
35
|
+
import { sendMouse } from "../../../test/plugins/browser.js";
|
|
36
|
+
import { HasActionMenuAsChild } from "../stories/action-group.stories.js";
|
|
37
|
+
import "../stories/action-group.stories.js";
|
|
38
|
+
import { isWebKit } from "@spectrum-web-components/shared";
|
|
39
|
+
import sinon from "sinon";
|
|
40
|
+
class QuietActionGroup extends LitElement {
|
|
41
|
+
render() {
|
|
42
|
+
return html`
|
|
43
|
+
<sp-action-group quiet>
|
|
44
|
+
<slot name="first"></slot>
|
|
45
|
+
<slot name="second"></slot>
|
|
46
|
+
</sp-action-group>
|
|
47
|
+
`;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
customElements.define("quiet-action-group", QuietActionGroup);
|
|
51
|
+
class EmphasizedActionGroup extends LitElement {
|
|
52
|
+
render() {
|
|
53
|
+
return html`
|
|
54
|
+
<sp-action-group emphasized>
|
|
55
|
+
<slot name="first"></slot>
|
|
56
|
+
<slot name="second"></slot>
|
|
57
|
+
</sp-action-group>
|
|
58
|
+
`;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
customElements.define("emphasized-action-group", EmphasizedActionGroup);
|
|
62
|
+
async function singleSelectedActionGroup(selected) {
|
|
63
|
+
const el = await fixture(html`
|
|
64
|
+
<sp-action-group
|
|
65
|
+
label="Selects User-Chosen Buttons"
|
|
66
|
+
selects="single"
|
|
67
|
+
.selected=${selected}
|
|
68
|
+
>
|
|
69
|
+
<sp-action-button value="first" class="first">
|
|
70
|
+
First
|
|
71
|
+
</sp-action-button>
|
|
72
|
+
<sp-action-button value="second" class="second">
|
|
73
|
+
<div slot="icon" style="width: 10px; height: 10px;"></div>
|
|
74
|
+
Second
|
|
75
|
+
</sp-action-button>
|
|
76
|
+
</sp-action-group>
|
|
77
|
+
`);
|
|
78
|
+
return el;
|
|
79
|
+
}
|
|
80
|
+
async function multipleSelectedActionGroup(selected) {
|
|
81
|
+
const el = await fixture(html`
|
|
82
|
+
<sp-action-group
|
|
83
|
+
label="Selects User-Chosen Buttons"
|
|
84
|
+
selects="multiple"
|
|
85
|
+
.selected=${selected}
|
|
86
|
+
>
|
|
87
|
+
<sp-action-button value="first" class="first">
|
|
88
|
+
First
|
|
89
|
+
</sp-action-button>
|
|
90
|
+
<sp-action-button value="second" class="second">
|
|
91
|
+
Second
|
|
92
|
+
</sp-action-button>
|
|
93
|
+
</sp-action-group>
|
|
94
|
+
`);
|
|
95
|
+
return el;
|
|
96
|
+
}
|
|
97
|
+
describe("ActionGroup", () => {
|
|
98
|
+
it("does not throw an error if slotElement is null", async () => {
|
|
99
|
+
const el = await fixture(html`
|
|
100
|
+
<sp-action-group>
|
|
101
|
+
<sp-action-button value="first">First</sp-action-button>
|
|
102
|
+
<sp-action-button value="second">Second</sp-action-button>
|
|
103
|
+
</sp-action-group>
|
|
104
|
+
`);
|
|
105
|
+
const slotElementStub = sinon.stub(el, "slotElement").get(() => null);
|
|
106
|
+
await elementUpdated(el);
|
|
107
|
+
while (el.firstChild) {
|
|
108
|
+
el.removeChild(el.firstChild);
|
|
109
|
+
}
|
|
110
|
+
await elementUpdated(el);
|
|
111
|
+
expect(el.children.length).to.equal(0);
|
|
112
|
+
slotElementStub.restore();
|
|
113
|
+
});
|
|
114
|
+
it("loads empty action-group accessibly", async () => {
|
|
115
|
+
const el = await fixture(html`
|
|
116
|
+
<sp-action-group></sp-action-group>
|
|
117
|
+
`);
|
|
118
|
+
await elementUpdated(el);
|
|
119
|
+
await expect(el).to.be.accessible();
|
|
120
|
+
});
|
|
121
|
+
it("loads action-group with action-menu accessibly", async () => {
|
|
122
|
+
const el = await fixture(
|
|
123
|
+
HasActionMenuAsChild({ label: "Action Group" })
|
|
124
|
+
);
|
|
125
|
+
await elementUpdated(el);
|
|
126
|
+
await nextFrame();
|
|
127
|
+
await nextFrame();
|
|
128
|
+
await nextFrame();
|
|
129
|
+
await nextFrame();
|
|
130
|
+
await expect(el).to.be.accessible();
|
|
131
|
+
});
|
|
132
|
+
it("action-group with action-menu manages tabIndex correctly while using keyboard", async () => {
|
|
133
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
134
|
+
const el = await fixture(
|
|
135
|
+
HasActionMenuAsChild({ label: "Action Group" })
|
|
136
|
+
);
|
|
137
|
+
await elementUpdated(el);
|
|
138
|
+
await nextFrame();
|
|
139
|
+
await nextFrame();
|
|
140
|
+
await nextFrame();
|
|
141
|
+
await nextFrame();
|
|
142
|
+
await sendKeys({ press: "Tab" });
|
|
143
|
+
await elementUpdated(el);
|
|
144
|
+
expect((_a = document.activeElement) == null ? void 0 : _a.id).to.equal("first");
|
|
145
|
+
expect((_b = el.children[0]) == null ? void 0 : _b.tabIndex).to.equal(0);
|
|
146
|
+
expect((_c = el.children[1]) == null ? void 0 : _c.tabIndex).to.equal(-1);
|
|
147
|
+
expect((_d = el.children[2]) == null ? void 0 : _d.tabIndex).to.equal(-1);
|
|
148
|
+
expect((_e = el.children[3]) == null ? void 0 : _e.tabIndex).to.equal(-1);
|
|
149
|
+
await sendKeys({ press: "ArrowRight" });
|
|
150
|
+
await sendKeys({ press: "ArrowRight" });
|
|
151
|
+
await sendKeys({ press: "ArrowRight" });
|
|
152
|
+
await elementUpdated(el);
|
|
153
|
+
expect((_f = el.children[3]) == null ? void 0 : _f.focused).to.be.true;
|
|
154
|
+
await sendKeys({ press: "Enter" });
|
|
155
|
+
const opened = oneEvent(el.children[3], "sp-opened");
|
|
156
|
+
await elementUpdated(el.children[3]);
|
|
157
|
+
await opened;
|
|
158
|
+
const firstMenuItem = el.querySelector("#first-menu-item");
|
|
159
|
+
expect(firstMenuItem == null ? void 0 : firstMenuItem.focused).to.be.true;
|
|
160
|
+
await sendKeys({ press: "ArrowDown" });
|
|
161
|
+
await sendKeys({ press: "ArrowDown" });
|
|
162
|
+
await sendKeys({ press: "ArrowDown" });
|
|
163
|
+
await sendKeys({ press: "Enter" });
|
|
164
|
+
await elementUpdated(el.children[3]);
|
|
165
|
+
await nextFrame();
|
|
166
|
+
await nextFrame();
|
|
167
|
+
await nextFrame();
|
|
168
|
+
await nextFrame();
|
|
169
|
+
const secondSubMenuItem = el.querySelector(
|
|
170
|
+
"#second-sub-menu-item"
|
|
171
|
+
);
|
|
172
|
+
expect(secondSubMenuItem == null ? void 0 : secondSubMenuItem.focused).to.be.true;
|
|
173
|
+
await sendKeys({ press: "Enter" });
|
|
174
|
+
const closed = oneEvent(el.children[3], "sp-closed");
|
|
175
|
+
await elementUpdated(el.children[3]);
|
|
176
|
+
await closed;
|
|
177
|
+
expect((_g = el.children[3]) == null ? void 0 : _g.focused).to.be.true;
|
|
178
|
+
});
|
|
179
|
+
it("action-group with action-menu manages tabIndex correctly while using mouse", async () => {
|
|
180
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
181
|
+
const el = await fixture(
|
|
182
|
+
HasActionMenuAsChild({ label: "Action Group" })
|
|
183
|
+
);
|
|
184
|
+
await elementUpdated(el);
|
|
185
|
+
await aTimeout(500);
|
|
186
|
+
const firstButton = el.querySelector("#first");
|
|
187
|
+
const rect = firstButton.getBoundingClientRect();
|
|
188
|
+
sendMouse({
|
|
189
|
+
steps: [
|
|
190
|
+
{
|
|
191
|
+
position: [
|
|
192
|
+
rect.left + rect.width / 2,
|
|
193
|
+
rect.top + rect.height / 2
|
|
194
|
+
],
|
|
195
|
+
type: "click"
|
|
196
|
+
}
|
|
197
|
+
]
|
|
198
|
+
});
|
|
199
|
+
await elementUpdated(el);
|
|
200
|
+
await aTimeout(500);
|
|
201
|
+
expect((_a = el.children[0]) == null ? void 0 : _a.tabIndex).to.equal(0);
|
|
202
|
+
expect((_b = el.children[1]) == null ? void 0 : _b.tabIndex).to.equal(-1);
|
|
203
|
+
expect((_c = el.children[2]) == null ? void 0 : _c.tabIndex).to.equal(-1);
|
|
204
|
+
expect((_d = el.children[3]) == null ? void 0 : _d.tabIndex).to.equal(-1);
|
|
205
|
+
sendMouse({
|
|
206
|
+
steps: [
|
|
207
|
+
{
|
|
208
|
+
position: [0, 0],
|
|
209
|
+
type: "click"
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
});
|
|
213
|
+
await elementUpdated(el);
|
|
214
|
+
await aTimeout(500);
|
|
215
|
+
expect((_e = el.children[0]) == null ? void 0 : _e.tabIndex).to.equal(0);
|
|
216
|
+
expect((_f = el.children[1]) == null ? void 0 : _f.tabIndex).to.equal(-1);
|
|
217
|
+
expect((_g = el.children[2]) == null ? void 0 : _g.tabIndex).to.equal(-1);
|
|
218
|
+
expect((_h = el.children[3]) == null ? void 0 : _h.tabIndex).to.equal(-1);
|
|
219
|
+
const actionMenu = el.querySelector("#action-menu");
|
|
220
|
+
const actionMenuRect = actionMenu.getBoundingClientRect();
|
|
221
|
+
sendMouse({
|
|
222
|
+
steps: [
|
|
223
|
+
{
|
|
224
|
+
position: [
|
|
225
|
+
actionMenuRect.left + actionMenuRect.width / 2,
|
|
226
|
+
actionMenuRect.top + actionMenuRect.height / 2
|
|
227
|
+
],
|
|
228
|
+
type: "click"
|
|
229
|
+
}
|
|
230
|
+
]
|
|
231
|
+
});
|
|
232
|
+
await elementUpdated(el);
|
|
233
|
+
const opened = oneEvent(el.children[3], "sp-opened");
|
|
234
|
+
await opened;
|
|
235
|
+
await sendKeys({ press: "ArrowDown" });
|
|
236
|
+
await sendKeys({ press: "Enter" });
|
|
237
|
+
const closed = oneEvent(el.children[3], "sp-closed");
|
|
238
|
+
await closed;
|
|
239
|
+
if (!isWebKit()) {
|
|
240
|
+
sendMouse({
|
|
241
|
+
steps: [
|
|
242
|
+
{
|
|
243
|
+
position: [0, 0],
|
|
244
|
+
type: "click"
|
|
245
|
+
}
|
|
246
|
+
]
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
await aTimeout(500);
|
|
250
|
+
expect((_i = el.children[0]) == null ? void 0 : _i.tabIndex).to.equal(0);
|
|
251
|
+
expect((_j = el.children[1]) == null ? void 0 : _j.tabIndex).to.equal(-1);
|
|
252
|
+
expect((_k = el.children[2]) == null ? void 0 : _k.tabIndex).to.equal(-1);
|
|
253
|
+
expect((_l = el.children[3]) == null ? void 0 : _l.tabIndex).to.equal(-1);
|
|
254
|
+
});
|
|
255
|
+
testForLitDevWarnings(
|
|
256
|
+
async () => await fixture(html`
|
|
257
|
+
<sp-action-group aria-label="Default Group">
|
|
258
|
+
<sp-action-button>First</sp-action-button>
|
|
259
|
+
<sp-action-button>Second</sp-action-button>
|
|
260
|
+
<sp-action-button>Third</sp-action-button>
|
|
261
|
+
</sp-action-group>
|
|
262
|
+
`)
|
|
263
|
+
);
|
|
264
|
+
it("loads default action-group accessibly", async () => {
|
|
265
|
+
const el = await fixture(html`
|
|
266
|
+
<sp-action-group aria-label="Default Group">
|
|
267
|
+
<sp-action-button>First</sp-action-button>
|
|
268
|
+
<sp-action-button>Second</sp-action-button>
|
|
269
|
+
<sp-action-button>Third</sp-action-button>
|
|
270
|
+
</sp-action-group>
|
|
271
|
+
`);
|
|
272
|
+
await elementUpdated(el);
|
|
273
|
+
await expect(el).to.be.accessible();
|
|
274
|
+
expect(el.getAttribute("aria-label")).to.equal("Default Group");
|
|
275
|
+
expect(el.getAttribute("role")).to.equal("toolbar");
|
|
276
|
+
expect(el.children[0].getAttribute("role")).to.equal("button");
|
|
277
|
+
});
|
|
278
|
+
it("applies `static-color` attribute to its children", async () => {
|
|
279
|
+
const el = await fixture(html`
|
|
280
|
+
<sp-action-group static-color="white">
|
|
281
|
+
<sp-action-button id="first">First</sp-action-button>
|
|
282
|
+
<sp-action-button id="second">Second</sp-action-button>
|
|
283
|
+
</sp-action-group>
|
|
284
|
+
`);
|
|
285
|
+
const firstButton = el.querySelector("#first");
|
|
286
|
+
const secondButton = el.querySelector("#second");
|
|
287
|
+
await elementUpdated(el);
|
|
288
|
+
expect(firstButton.staticColor).to.equal("white");
|
|
289
|
+
expect(secondButton.staticColor).to.equal("white");
|
|
290
|
+
el.staticColor = void 0;
|
|
291
|
+
await elementUpdated(el);
|
|
292
|
+
expect(firstButton.staticColor).to.be.undefined;
|
|
293
|
+
expect(secondButton.staticColor).to.be.undefined;
|
|
294
|
+
});
|
|
295
|
+
it('manages "label"', async () => {
|
|
296
|
+
const testLabel = "Testable action group";
|
|
297
|
+
const el = await fixture(html`
|
|
298
|
+
<sp-action-group label=${testLabel}>
|
|
299
|
+
<sp-action-button id="first">First</sp-action-button>
|
|
300
|
+
<sp-action-button id="second">Second</sp-action-button>
|
|
301
|
+
</sp-action-group>
|
|
302
|
+
`);
|
|
303
|
+
expect(el.getAttribute("aria-label")).to.equal(testLabel);
|
|
304
|
+
el.label = "";
|
|
305
|
+
await elementUpdated(el);
|
|
306
|
+
expect(el.hasAttribute("aria-label")).to.be.false;
|
|
307
|
+
});
|
|
308
|
+
it("applies `quiet` attribute to its children", async () => {
|
|
309
|
+
const el = await fixture(html`
|
|
310
|
+
<sp-action-group quiet>
|
|
311
|
+
<sp-action-button id="first">First</sp-action-button>
|
|
312
|
+
<sp-action-button id="second">Second</sp-action-button>
|
|
313
|
+
</sp-action-group>
|
|
314
|
+
`);
|
|
315
|
+
const firstButton = el.querySelector("#first");
|
|
316
|
+
const secondButton = el.querySelector("#second");
|
|
317
|
+
await elementUpdated(el);
|
|
318
|
+
expect(firstButton.hasAttribute("quiet")).to.be.true;
|
|
319
|
+
expect(firstButton.quiet).to.be.true;
|
|
320
|
+
expect(secondButton.hasAttribute("quiet")).to.be.true;
|
|
321
|
+
expect(secondButton.quiet).to.be.true;
|
|
322
|
+
});
|
|
323
|
+
it("applies `quiet` attribute to its slotted children", async () => {
|
|
324
|
+
const el = await fixture(html`
|
|
325
|
+
<quiet-action-group>
|
|
326
|
+
<sp-action-button slot="first" id="first">
|
|
327
|
+
First
|
|
328
|
+
</sp-action-button>
|
|
329
|
+
<sp-action-button slot="second" id="second">
|
|
330
|
+
Second
|
|
331
|
+
</sp-action-button>
|
|
332
|
+
</quiet-action-group>
|
|
333
|
+
`);
|
|
334
|
+
const firstButton = el.querySelector("#first");
|
|
335
|
+
const secondButton = el.querySelector("#second");
|
|
336
|
+
await elementUpdated(el);
|
|
337
|
+
expect(firstButton.hasAttribute("quiet")).to.be.true;
|
|
338
|
+
expect(firstButton.quiet).to.be.true;
|
|
339
|
+
expect(secondButton.hasAttribute("quiet")).to.be.true;
|
|
340
|
+
expect(secondButton.quiet).to.be.true;
|
|
341
|
+
});
|
|
342
|
+
it("applies `emphasized` attribute to its slotted children", async () => {
|
|
343
|
+
const el = await fixture(html`
|
|
344
|
+
<emphasized-action-group>
|
|
345
|
+
<sp-action-button slot="first" id="first">
|
|
346
|
+
First
|
|
347
|
+
</sp-action-button>
|
|
348
|
+
<sp-action-button slot="second" id="second">
|
|
349
|
+
Second
|
|
350
|
+
</sp-action-button>
|
|
351
|
+
</emphasized-action-group>
|
|
352
|
+
`);
|
|
353
|
+
const firstButton = el.querySelector("#first");
|
|
354
|
+
const secondButton = el.querySelector("#second");
|
|
355
|
+
await elementUpdated(el);
|
|
356
|
+
expect(firstButton.hasAttribute("emphasized")).to.be.true;
|
|
357
|
+
expect(firstButton.emphasized).to.be.true;
|
|
358
|
+
expect(secondButton.hasAttribute("emphasized")).to.be.true;
|
|
359
|
+
expect(secondButton.emphasized).to.be.true;
|
|
360
|
+
});
|
|
361
|
+
it("applies `quiet` attribute to slotted children with overlays", async () => {
|
|
362
|
+
const el = await fixture(html`
|
|
363
|
+
<quiet-action-group>
|
|
364
|
+
<overlay-trigger slot="first">
|
|
365
|
+
<sp-action-button slot="trigger" id="first">
|
|
366
|
+
First
|
|
367
|
+
</sp-action-button>
|
|
368
|
+
</overlay-trigger>
|
|
369
|
+
<overlay-trigger slot="second">
|
|
370
|
+
<sp-action-button slot="trigger" id="second">
|
|
371
|
+
Second
|
|
372
|
+
</sp-action-button>
|
|
373
|
+
</overlay-trigger>
|
|
374
|
+
</quiet-action-group>
|
|
375
|
+
`);
|
|
376
|
+
const firstButton = el.querySelector("#first");
|
|
377
|
+
const secondButton = el.querySelector("#second");
|
|
378
|
+
await elementUpdated(el);
|
|
379
|
+
expect(firstButton.hasAttribute("quiet")).to.be.true;
|
|
380
|
+
expect(firstButton.quiet).to.be.true;
|
|
381
|
+
expect(secondButton.hasAttribute("quiet")).to.be.true;
|
|
382
|
+
expect(secondButton.quiet).to.be.true;
|
|
383
|
+
});
|
|
384
|
+
it("applies `emphasized` attribute to slotted children with overlays", async () => {
|
|
385
|
+
const el = await fixture(html`
|
|
386
|
+
<emphasized-action-group>
|
|
387
|
+
<overlay-trigger slot="first">
|
|
388
|
+
<sp-action-button slot="trigger" id="first">
|
|
389
|
+
First
|
|
390
|
+
</sp-action-button>
|
|
391
|
+
</overlay-trigger>
|
|
392
|
+
<overlay-trigger slot="second">
|
|
393
|
+
<sp-action-button slot="trigger" id="second">
|
|
394
|
+
Second
|
|
395
|
+
</sp-action-button>
|
|
396
|
+
</overlay-trigger>
|
|
397
|
+
</emphasized-action-group>
|
|
398
|
+
`);
|
|
399
|
+
const firstButton = el.querySelector("#first");
|
|
400
|
+
const secondButton = el.querySelector("#second");
|
|
401
|
+
await elementUpdated(el);
|
|
402
|
+
expect(firstButton.hasAttribute("emphasized")).to.be.true;
|
|
403
|
+
expect(firstButton.emphasized).to.be.true;
|
|
404
|
+
expect(secondButton.hasAttribute("emphasized")).to.be.true;
|
|
405
|
+
expect(secondButton.emphasized).to.be.true;
|
|
406
|
+
});
|
|
407
|
+
it('loads [selects="single"] action-group accessibly', async () => {
|
|
408
|
+
const el = await fixture(html`
|
|
409
|
+
<sp-action-group label="Selects Single Group" selects="single">
|
|
410
|
+
<sp-action-button>First</sp-action-button>
|
|
411
|
+
<sp-action-button>Second</sp-action-button>
|
|
412
|
+
<sp-action-button>Third</sp-action-button>
|
|
413
|
+
</sp-action-group>
|
|
414
|
+
`);
|
|
415
|
+
await elementUpdated(el);
|
|
416
|
+
await expect(el).to.be.accessible();
|
|
417
|
+
expect(el.getAttribute("aria-label")).to.equal("Selects Single Group");
|
|
418
|
+
expect(el.getAttribute("role")).to.equal("radiogroup");
|
|
419
|
+
expect(el.children[0].getAttribute("role")).to.equal("radio");
|
|
420
|
+
});
|
|
421
|
+
it('loads [selects="single"] action-group w/ selection accessibly', async () => {
|
|
422
|
+
const el = await fixture(html`
|
|
423
|
+
<sp-action-group label="Selects Single Group" selects="single">
|
|
424
|
+
<sp-action-button>First</sp-action-button>
|
|
425
|
+
<sp-action-button>Second</sp-action-button>
|
|
426
|
+
<sp-action-button selected>Third</sp-action-button>
|
|
427
|
+
</sp-action-group>
|
|
428
|
+
`);
|
|
429
|
+
await elementUpdated(el);
|
|
430
|
+
await expect(el).to.be.accessible();
|
|
431
|
+
});
|
|
432
|
+
it('loads [selects="multiple"] action-group accessibly', async () => {
|
|
433
|
+
const el = await fixture(html`
|
|
434
|
+
<sp-action-group label="Selects Multiple Group" selects="multiple">
|
|
435
|
+
<sp-action-button>First</sp-action-button>
|
|
436
|
+
<sp-action-button>Second</sp-action-button>
|
|
437
|
+
<sp-action-button>Third</sp-action-button>
|
|
438
|
+
</sp-action-group>
|
|
439
|
+
`);
|
|
440
|
+
await elementUpdated(el);
|
|
441
|
+
await expect(el).to.be.accessible();
|
|
442
|
+
expect(el.getAttribute("aria-label")).to.equal(
|
|
443
|
+
"Selects Multiple Group"
|
|
444
|
+
);
|
|
445
|
+
expect(el.getAttribute("role")).to.equal("toolbar");
|
|
446
|
+
expect(el.children[0].getAttribute("role")).to.equal("checkbox");
|
|
447
|
+
});
|
|
448
|
+
it('loads [selects="multiple"] action-group w/ selection accessibly', async () => {
|
|
449
|
+
const el = await fixture(html`
|
|
450
|
+
<sp-action-group label="Selects Multiple Group" selects="multiple">
|
|
451
|
+
<sp-action-button>First</sp-action-button>
|
|
452
|
+
<sp-action-button selected>Second</sp-action-button>
|
|
453
|
+
<sp-action-button selected>Third</sp-action-button>
|
|
454
|
+
</sp-action-group>
|
|
455
|
+
`);
|
|
456
|
+
await elementUpdated(el);
|
|
457
|
+
await expect(el).to.be.accessible();
|
|
458
|
+
});
|
|
459
|
+
it('sets tab stop when [selects="single"] and the initial button is [disabled]', async () => {
|
|
460
|
+
const el = await fixture(html`
|
|
461
|
+
<sp-action-group label="Selects Single Group" selects="single">
|
|
462
|
+
<sp-action-button disabled>First</sp-action-button>
|
|
463
|
+
<sp-action-button class="second">Second</sp-action-button>
|
|
464
|
+
<sp-action-button>Third</sp-action-button>
|
|
465
|
+
</sp-action-group>
|
|
466
|
+
`);
|
|
467
|
+
const secondButton = el.querySelector(".second");
|
|
468
|
+
await elementUpdated(el);
|
|
469
|
+
expect(secondButton.hasAttribute("tabindex"));
|
|
470
|
+
expect(secondButton.getAttribute("tabindex")).to.equal("0");
|
|
471
|
+
});
|
|
472
|
+
it('surfaces [selects="single"] selection', async () => {
|
|
473
|
+
const el = await fixture(html`
|
|
474
|
+
<sp-action-group label="Selects Single Group" selects="single">
|
|
475
|
+
<sp-action-button>First</sp-action-button>
|
|
476
|
+
<sp-action-button>Second</sp-action-button>
|
|
477
|
+
<sp-action-button selected>Third</sp-action-button>
|
|
478
|
+
</sp-action-group>
|
|
479
|
+
`);
|
|
480
|
+
await elementUpdated(el);
|
|
481
|
+
expect(el.selected, '"Third" selected').to.deep.equal(["Third"]);
|
|
482
|
+
});
|
|
483
|
+
it('manages [selects="single"] selection through multiple slots', async () => {
|
|
484
|
+
const test = await fixture(html`
|
|
485
|
+
<div>
|
|
486
|
+
<sp-action-button>First</sp-action-button>
|
|
487
|
+
<sp-action-button>Second</sp-action-button>
|
|
488
|
+
<sp-action-button selected>Third</sp-action-button>
|
|
489
|
+
</div>
|
|
490
|
+
`);
|
|
491
|
+
const firstItem = test.querySelector(
|
|
492
|
+
"sp-action-button"
|
|
493
|
+
);
|
|
494
|
+
const thirdItem = test.querySelector(
|
|
495
|
+
"sp-action-button[selected]"
|
|
496
|
+
);
|
|
497
|
+
const shadowRoot = test.attachShadow({ mode: "open" });
|
|
498
|
+
shadowRoot.innerHTML = `
|
|
499
|
+
<sp-action-group label="Selects Single Group" selects="single">
|
|
500
|
+
<slot></slot>
|
|
501
|
+
</sp-action-group>
|
|
502
|
+
`;
|
|
503
|
+
const el = shadowRoot.querySelector("sp-action-group");
|
|
504
|
+
await elementUpdated(el);
|
|
505
|
+
expect(el.selected, '"Third" selected').to.deep.equal(["Third"]);
|
|
506
|
+
expect(firstItem.selected).to.be.false;
|
|
507
|
+
expect(thirdItem.selected).to.be.true;
|
|
508
|
+
firstItem.click();
|
|
509
|
+
await elementUpdated(el);
|
|
510
|
+
expect(el.selected, '"First" selected').to.deep.equal(["First"]);
|
|
511
|
+
expect(firstItem.selected).to.be.true;
|
|
512
|
+
expect(thirdItem.selected).to.be.false;
|
|
513
|
+
});
|
|
514
|
+
it('surfaces [selects="multiple"] selection', async () => {
|
|
515
|
+
const el = await fixture(html`
|
|
516
|
+
<sp-action-group label="Selects Multiple Group" selects="multiple">
|
|
517
|
+
<sp-action-button>First</sp-action-button>
|
|
518
|
+
<sp-action-button selected>Second</sp-action-button>
|
|
519
|
+
<sp-action-button selected>Third</sp-action-button>
|
|
520
|
+
</sp-action-group>
|
|
521
|
+
`);
|
|
522
|
+
await elementUpdated(el);
|
|
523
|
+
expect(el.selected, '"Second" and "Third" selected').to.deep.equal([
|
|
524
|
+
"Second",
|
|
525
|
+
"Third"
|
|
526
|
+
]);
|
|
527
|
+
});
|
|
528
|
+
it("does not select without [selects]", async () => {
|
|
529
|
+
const el = await fixture(html`
|
|
530
|
+
<sp-action-group label="No Selects Group">
|
|
531
|
+
<sp-action-button>First</sp-action-button>
|
|
532
|
+
<sp-action-button selected>Second</sp-action-button>
|
|
533
|
+
<sp-action-button class="third">Third</sp-action-button>
|
|
534
|
+
</sp-action-group>
|
|
535
|
+
`);
|
|
536
|
+
const thirdElement = el.querySelector(".third");
|
|
537
|
+
await elementUpdated(el);
|
|
538
|
+
expect(el.selected.length).to.equal(1);
|
|
539
|
+
thirdElement.click();
|
|
540
|
+
await elementUpdated(el);
|
|
541
|
+
expect(el.selected.length).to.equal(1);
|
|
542
|
+
});
|
|
543
|
+
it('selects via `click` while [selects="single"]', async () => {
|
|
544
|
+
const el = await fixture(html`
|
|
545
|
+
<sp-action-group label="Selects Single Group" selects="single">
|
|
546
|
+
<sp-action-button value="first">First</sp-action-button>
|
|
547
|
+
<sp-action-button value="second" selected>
|
|
548
|
+
Second
|
|
549
|
+
</sp-action-button>
|
|
550
|
+
<sp-action-button value="third" class="third">
|
|
551
|
+
Third
|
|
552
|
+
</sp-action-button>
|
|
553
|
+
</sp-action-group>
|
|
554
|
+
`);
|
|
555
|
+
const thirdElement = el.querySelector(".third");
|
|
556
|
+
await elementUpdated(el);
|
|
557
|
+
expect(el.selected.length).to.equal(1);
|
|
558
|
+
expect(el.selected.includes("second"));
|
|
559
|
+
thirdElement.click();
|
|
560
|
+
await elementUpdated(el);
|
|
561
|
+
expect(thirdElement.selected, "third child selected").to.be.true;
|
|
562
|
+
await waitUntil(
|
|
563
|
+
() => el.selected.length === 1 && el.selected.includes("third"),
|
|
564
|
+
"Updates value of `selected`"
|
|
565
|
+
);
|
|
566
|
+
});
|
|
567
|
+
it('selects via `click` while [selects="multiple"] selection', async () => {
|
|
568
|
+
const el = await fixture(html`
|
|
569
|
+
<sp-action-group label="Selects Multiple Group" selects="multiple">
|
|
570
|
+
<sp-action-button selected class="first">
|
|
571
|
+
First
|
|
572
|
+
</sp-action-button>
|
|
573
|
+
<sp-action-button class="second">Second</sp-action-button>
|
|
574
|
+
<sp-action-button class="third">Third</sp-action-button>
|
|
575
|
+
</sp-action-group>
|
|
576
|
+
`);
|
|
577
|
+
const firstElement = el.querySelector(".first");
|
|
578
|
+
const secondElement = el.querySelector(".second");
|
|
579
|
+
const thirdElement = el.querySelector(".third");
|
|
580
|
+
await elementUpdated(el);
|
|
581
|
+
expect(el.selected.length).to.equal(1);
|
|
582
|
+
expect(el.selected.includes("First"));
|
|
583
|
+
firstElement.click();
|
|
584
|
+
secondElement.click();
|
|
585
|
+
thirdElement.click();
|
|
586
|
+
await elementUpdated(el);
|
|
587
|
+
expect(secondElement.selected, "second child selected").to.be.true;
|
|
588
|
+
expect(thirdElement.selected, "third child selected").to.be.true;
|
|
589
|
+
await waitUntil(
|
|
590
|
+
() => el.selected.length === 2 && el.selected.includes("Second") && el.selected.includes("Third"),
|
|
591
|
+
"Updates value of `selected`"
|
|
592
|
+
);
|
|
593
|
+
});
|
|
594
|
+
it("consumes descendant `change` events when `[selects]`", async () => {
|
|
595
|
+
const changeSpy = spy();
|
|
596
|
+
const el = await fixture(html`
|
|
597
|
+
<sp-action-group
|
|
598
|
+
@change=${() => changeSpy()}
|
|
599
|
+
label="Selects Single Group"
|
|
600
|
+
selects="single"
|
|
601
|
+
>
|
|
602
|
+
<sp-action-button toggles value="first">First</sp-action-button>
|
|
603
|
+
<sp-action-button toggles value="second" selected>
|
|
604
|
+
Second
|
|
605
|
+
</sp-action-button>
|
|
606
|
+
<sp-action-button toggles value="third" class="third">
|
|
607
|
+
Third
|
|
608
|
+
</sp-action-button>
|
|
609
|
+
</sp-action-group>
|
|
610
|
+
`);
|
|
611
|
+
const thirdElement = el.querySelector(".third");
|
|
612
|
+
await elementUpdated(el);
|
|
613
|
+
expect(el.selected.length).to.equal(1);
|
|
614
|
+
expect(el.selected.includes("second"));
|
|
615
|
+
expect(changeSpy.callCount).to.equal(0);
|
|
616
|
+
thirdElement.click();
|
|
617
|
+
await elementUpdated(el);
|
|
618
|
+
expect(thirdElement.selected, "third child selected").to.be.true;
|
|
619
|
+
expect(changeSpy.callCount).to.equal(1);
|
|
620
|
+
await waitUntil(
|
|
621
|
+
() => el.selected.length === 1 && el.selected.includes("third"),
|
|
622
|
+
"Updates value of `selected`"
|
|
623
|
+
);
|
|
624
|
+
});
|
|
625
|
+
it("does not respond to clicks on itself", async () => {
|
|
626
|
+
const el = await fixture(html`
|
|
627
|
+
<sp-action-group label="Selects Single Group" selects="single">
|
|
628
|
+
<sp-action-button>First</sp-action-button>
|
|
629
|
+
<sp-action-button>Second</sp-action-button>
|
|
630
|
+
<sp-action-button class="third">Third</sp-action-button>
|
|
631
|
+
</sp-action-group>
|
|
632
|
+
`);
|
|
633
|
+
await elementUpdated(el);
|
|
634
|
+
expect(el.selected.length).to.equal(0);
|
|
635
|
+
el.click();
|
|
636
|
+
await elementUpdated(el);
|
|
637
|
+
expect(el.selected.length).to.equal(0);
|
|
638
|
+
});
|
|
639
|
+
it("selection can be prevented", async () => {
|
|
640
|
+
const el = await fixture(html`
|
|
641
|
+
<sp-action-group
|
|
642
|
+
label="Selects Single Group"
|
|
643
|
+
selects="single"
|
|
644
|
+
@change=${(event) => {
|
|
645
|
+
event.preventDefault();
|
|
646
|
+
}}
|
|
647
|
+
>
|
|
648
|
+
<sp-action-button>First</sp-action-button>
|
|
649
|
+
<sp-action-button>Second</sp-action-button>
|
|
650
|
+
<sp-action-button class="third">Third</sp-action-button>
|
|
651
|
+
</sp-action-group>
|
|
652
|
+
`);
|
|
653
|
+
const thirdElement = el.querySelector(".third");
|
|
654
|
+
await elementUpdated(el);
|
|
655
|
+
expect(el.selected.length).to.equal(0);
|
|
656
|
+
thirdElement.click();
|
|
657
|
+
await elementUpdated(el);
|
|
658
|
+
expect(thirdElement.selected, "third child not selected").to.be.false;
|
|
659
|
+
expect(el.selected.length).to.equal(0);
|
|
660
|
+
});
|
|
661
|
+
it('selects user-passed value while [selects="single"]', async () => {
|
|
662
|
+
const el = await singleSelectedActionGroup(["first"]);
|
|
663
|
+
await elementUpdated(el);
|
|
664
|
+
expect(el.selected.length).to.equal(1);
|
|
665
|
+
const firstButton = el.querySelector(".first");
|
|
666
|
+
const secondButton = el.querySelector(".second");
|
|
667
|
+
expect(firstButton.selected, "first button selected").to.be.true;
|
|
668
|
+
expect(secondButton.selected, "second button not selected").to.be.false;
|
|
669
|
+
secondButton.click();
|
|
670
|
+
await elementUpdated(el);
|
|
671
|
+
expect(el.selected.length).to.equal(1);
|
|
672
|
+
expect(firstButton.selected, "first button not selected").to.be.false;
|
|
673
|
+
expect(secondButton.selected, "second button selected").to.be.true;
|
|
674
|
+
});
|
|
675
|
+
it('selects can be updated while [selects="single"]', async () => {
|
|
676
|
+
const el = await singleSelectedActionGroup(["first"]);
|
|
677
|
+
await elementUpdated(el);
|
|
678
|
+
expect(el.selected.length).to.equal(1);
|
|
679
|
+
const firstButton = el.querySelector(".first");
|
|
680
|
+
const secondButton = el.querySelector(".second");
|
|
681
|
+
expect(firstButton.selected, "first button selected").to.be.true;
|
|
682
|
+
expect(secondButton.selected, "second button not selected").to.be.false;
|
|
683
|
+
el.selected = ["second"];
|
|
684
|
+
await elementUpdated(el);
|
|
685
|
+
expect(el.selected.length).to.equal(1);
|
|
686
|
+
expect(firstButton.selected, "first button not selected").to.be.false;
|
|
687
|
+
expect(secondButton.selected, "second button selected").to.be.true;
|
|
688
|
+
});
|
|
689
|
+
it("does not allow interaction with child content to interrupt the selection mechanism", async () => {
|
|
690
|
+
const el = await singleSelectedActionGroup([]);
|
|
691
|
+
await elementUpdated(el);
|
|
692
|
+
expect(el.selected.length).to.equal(0);
|
|
693
|
+
const firstButton = el.querySelector(".first");
|
|
694
|
+
const secondButton = el.querySelector(".second");
|
|
695
|
+
const icon = secondButton.querySelector("[slot=icon]");
|
|
696
|
+
expect(firstButton.selected, "first button selected").to.be.false;
|
|
697
|
+
expect(secondButton.selected, "second button not selected").to.be.false;
|
|
698
|
+
secondButton.click();
|
|
699
|
+
await elementUpdated(el);
|
|
700
|
+
expect(el.selected.length).to.equal(1);
|
|
701
|
+
expect(el.selected).to.deep.equal(["second"]);
|
|
702
|
+
expect(firstButton.selected, "first button not selected").to.be.false;
|
|
703
|
+
expect(secondButton.selected, "second button selected").to.be.true;
|
|
704
|
+
firstButton.click();
|
|
705
|
+
await elementUpdated(el);
|
|
706
|
+
expect(el.selected.length).to.equal(1);
|
|
707
|
+
expect(el.selected).to.deep.equal(["first"]);
|
|
708
|
+
expect(firstButton.selected, "first button selected").to.be.true;
|
|
709
|
+
expect(secondButton.selected, "second button not selected").to.be.false;
|
|
710
|
+
const rect = icon.getBoundingClientRect();
|
|
711
|
+
await sendMouse({
|
|
712
|
+
steps: [
|
|
713
|
+
{
|
|
714
|
+
type: "click",
|
|
715
|
+
position: [
|
|
716
|
+
rect.left + rect.width / 2,
|
|
717
|
+
rect.top + rect.height / 2
|
|
718
|
+
]
|
|
719
|
+
}
|
|
720
|
+
]
|
|
721
|
+
});
|
|
722
|
+
icon.click();
|
|
723
|
+
await elementUpdated(el);
|
|
724
|
+
expect(el.selected.length).to.equal(1);
|
|
725
|
+
expect(el.selected).to.deep.equal(["second"]);
|
|
726
|
+
expect(firstButton.selected, "first button not selected").to.be.false;
|
|
727
|
+
expect(secondButton.selected, "second button selected").to.be.true;
|
|
728
|
+
});
|
|
729
|
+
it('selects user-passed value while [selects="multiple"]', async () => {
|
|
730
|
+
const el = await fixture(html`
|
|
731
|
+
<sp-action-group
|
|
732
|
+
label="Selects Multiple Group"
|
|
733
|
+
selects="multiple"
|
|
734
|
+
.selected=${["first", "second"]}
|
|
735
|
+
>
|
|
736
|
+
<sp-action-button class="first" value="first">
|
|
737
|
+
First
|
|
738
|
+
</sp-action-button>
|
|
739
|
+
<sp-action-button class="second" value="second">
|
|
740
|
+
Second
|
|
741
|
+
</sp-action-button>
|
|
742
|
+
<sp-action-button class="third " value="third">
|
|
743
|
+
Third
|
|
744
|
+
</sp-action-button>
|
|
745
|
+
</sp-action-group>
|
|
746
|
+
`);
|
|
747
|
+
await elementUpdated(el);
|
|
748
|
+
await Promise.all(el.buttons.map((button) => elementUpdated(button)));
|
|
749
|
+
const firstButton = el.querySelector(".first");
|
|
750
|
+
const secondButton = el.querySelector(".second");
|
|
751
|
+
const thirdButton = el.querySelector(".third");
|
|
752
|
+
expect(el.selected.length).to.equal(2);
|
|
753
|
+
expect(firstButton.selected, "first button selected").to.be.true;
|
|
754
|
+
expect(secondButton.selected, "second button selected").to.be.true;
|
|
755
|
+
expect(thirdButton.selected, "third button not selected").to.be.false;
|
|
756
|
+
thirdButton.click();
|
|
757
|
+
await elementUpdated(el);
|
|
758
|
+
expect(el.selected.length).to.equal(3);
|
|
759
|
+
expect(firstButton.selected, "first button selected").to.be.true;
|
|
760
|
+
expect(secondButton.selected, "second button selected").to.be.true;
|
|
761
|
+
expect(thirdButton.selected, "third button selected").to.be.true;
|
|
762
|
+
firstButton.click();
|
|
763
|
+
await elementUpdated(el);
|
|
764
|
+
expect(el.selected.length).to.equal(2);
|
|
765
|
+
expect(firstButton.selected, "first button not selected").to.be.false;
|
|
766
|
+
expect(secondButton.selected, "second button selected").to.be.true;
|
|
767
|
+
expect(thirdButton.selected, "third button selected").to.be.true;
|
|
768
|
+
});
|
|
769
|
+
it('selects can be updated while [selects="multiple"]', async () => {
|
|
770
|
+
const el = await fixture(html`
|
|
771
|
+
<sp-action-group
|
|
772
|
+
label="Selects Multiple Group"
|
|
773
|
+
selects="multiple"
|
|
774
|
+
.selected=${["first", "second"]}
|
|
775
|
+
>
|
|
776
|
+
<sp-action-button class="first" value="first">
|
|
777
|
+
First
|
|
778
|
+
</sp-action-button>
|
|
779
|
+
<sp-action-button class="second" value="second">
|
|
780
|
+
Second
|
|
781
|
+
</sp-action-button>
|
|
782
|
+
<sp-action-button class="third " value="third">
|
|
783
|
+
Third
|
|
784
|
+
</sp-action-button>
|
|
785
|
+
</sp-action-group>
|
|
786
|
+
`);
|
|
787
|
+
await elementUpdated(el);
|
|
788
|
+
await Promise.all(el.buttons.map((button) => elementUpdated(button)));
|
|
789
|
+
const firstButton = el.querySelector(".first");
|
|
790
|
+
const secondButton = el.querySelector(".second");
|
|
791
|
+
const thirdButton = el.querySelector(".third");
|
|
792
|
+
expect(el.selected.length).to.equal(2);
|
|
793
|
+
expect(firstButton.selected, "first button selected").to.be.true;
|
|
794
|
+
expect(secondButton.selected, "second button selected").to.be.true;
|
|
795
|
+
expect(thirdButton.selected, "third button not selected").to.be.false;
|
|
796
|
+
el.selected = ["first", "second", "third"];
|
|
797
|
+
await elementUpdated(el);
|
|
798
|
+
expect(el.selected.length).to.equal(3);
|
|
799
|
+
expect(firstButton.selected, "first button selected").to.be.true;
|
|
800
|
+
expect(secondButton.selected, "second button selected").to.be.true;
|
|
801
|
+
expect(thirdButton.selected, "third button selected").to.be.true;
|
|
802
|
+
el.selected = ["second", "third"];
|
|
803
|
+
await elementUpdated(el);
|
|
804
|
+
expect(el.selected.length, JSON.stringify(el.selected)).to.equal(2);
|
|
805
|
+
expect(firstButton.selected, "first button not selected").to.be.false;
|
|
806
|
+
expect(secondButton.selected, "second button selected").to.be.true;
|
|
807
|
+
expect(thirdButton.selected, "third button selected").to.be.true;
|
|
808
|
+
});
|
|
809
|
+
it('selects multiple user-passed values while [selects="single"], but then proceeds with radio-button style functionality', async () => {
|
|
810
|
+
const el = await singleSelectedActionGroup(["first", "second"]);
|
|
811
|
+
await elementUpdated(el);
|
|
812
|
+
expect(el.selected.length).to.equal(2);
|
|
813
|
+
const firstButton = el.querySelector(".first");
|
|
814
|
+
const secondButton = el.querySelector(".second");
|
|
815
|
+
expect(firstButton.selected, "first button selected").to.be.true;
|
|
816
|
+
expect(secondButton.selected, "second button selected").to.be.true;
|
|
817
|
+
secondButton.click();
|
|
818
|
+
await elementUpdated(el);
|
|
819
|
+
expect(el.selected.length).to.equal(1);
|
|
820
|
+
expect(firstButton.selected, "first button selected").to.be.false;
|
|
821
|
+
expect(secondButton.selected, "second button selected").to.be.true;
|
|
822
|
+
});
|
|
823
|
+
it("Clicking button event should bubble up from inner label to outer button element", async () => {
|
|
824
|
+
const el = await fixture(html`
|
|
825
|
+
<sp-action-group
|
|
826
|
+
label="Selects Multiple Group"
|
|
827
|
+
selects="multiple"
|
|
828
|
+
.selected=${["first", "second"]}
|
|
829
|
+
>
|
|
830
|
+
<sp-action-button class="first" value="first">
|
|
831
|
+
First
|
|
832
|
+
</sp-action-button>
|
|
833
|
+
<sp-action-button class="second" value="second">
|
|
834
|
+
Second
|
|
835
|
+
</sp-action-button>
|
|
836
|
+
</sp-action-group>
|
|
837
|
+
`);
|
|
838
|
+
await elementUpdated(el);
|
|
839
|
+
expect(el.selected.length).to.equal(2);
|
|
840
|
+
const firstButtonEl = el.querySelector(".first");
|
|
841
|
+
const firstSpanEl = firstButtonEl.shadowRoot.querySelector(
|
|
842
|
+
"#label"
|
|
843
|
+
);
|
|
844
|
+
const secondButtonEl = el.querySelector(".second");
|
|
845
|
+
expect(firstButtonEl.selected, "first button selected").to.be.true;
|
|
846
|
+
expect(secondButtonEl.selected, "second button selected").to.be.true;
|
|
847
|
+
firstSpanEl.click();
|
|
848
|
+
await elementUpdated(el);
|
|
849
|
+
expect(firstButtonEl.selected, "first button selected").to.be.false;
|
|
850
|
+
expect(secondButtonEl.selected, "second button selected").to.be.true;
|
|
851
|
+
firstButtonEl.click();
|
|
852
|
+
await elementUpdated(el);
|
|
853
|
+
expect(firstButtonEl.selected, "first button selected").to.be.true;
|
|
854
|
+
expect(secondButtonEl.selected, "second button selected").to.be.true;
|
|
855
|
+
});
|
|
856
|
+
it('only selects user-passed buttons if present in action-group while [selects="multiple"]', async () => {
|
|
857
|
+
const el = await multipleSelectedActionGroup(["second", "fourth"]);
|
|
858
|
+
await elementUpdated(el);
|
|
859
|
+
expect(el.selected.length).to.equal(1);
|
|
860
|
+
const secondButton = el.querySelector(".second");
|
|
861
|
+
expect(secondButton.selected, "second button selected").to.be.true;
|
|
862
|
+
const firstButton = el.querySelector(".first");
|
|
863
|
+
expect(firstButton.selected, "first button selected").to.be.false;
|
|
864
|
+
});
|
|
865
|
+
it("selects user-passed values with no .selects value, but does not allow interaction afterwards", async () => {
|
|
866
|
+
const el = await fixture(html`
|
|
867
|
+
<sp-action-group
|
|
868
|
+
label="Selects User-Chosen Buttons"
|
|
869
|
+
.selected=${["first"]}
|
|
870
|
+
>
|
|
871
|
+
<sp-action-button value="first" class="first">
|
|
872
|
+
First
|
|
873
|
+
</sp-action-button>
|
|
874
|
+
<sp-action-button value="second" class="second">
|
|
875
|
+
Second
|
|
876
|
+
</sp-action-button>
|
|
877
|
+
</sp-action-group>
|
|
878
|
+
`);
|
|
879
|
+
await elementUpdated(el);
|
|
880
|
+
expect(el.selected.length).to.equal(1);
|
|
881
|
+
const firstButton = el.querySelector(".first");
|
|
882
|
+
const secondButton = el.querySelector(".second");
|
|
883
|
+
expect(firstButton.selected, "first button selected").to.be.true;
|
|
884
|
+
expect(secondButton.selected, "second button selected").to.be.false;
|
|
885
|
+
secondButton.click();
|
|
886
|
+
await elementUpdated(el);
|
|
887
|
+
expect(el.selected.length).to.equal(1);
|
|
888
|
+
expect(firstButton.selected, "first button selected").to.be.true;
|
|
889
|
+
expect(secondButton.selected, "second button selected").to.be.false;
|
|
890
|
+
});
|
|
891
|
+
it("selects multiple buttons if .selected is passed in, but does not allow further interaction afterwards", async () => {
|
|
892
|
+
const el = await fixture(html`
|
|
893
|
+
<sp-action-group
|
|
894
|
+
label="Selects User-Chosen Buttons"
|
|
895
|
+
.selected=${["first", "second"]}
|
|
896
|
+
>
|
|
897
|
+
<sp-action-button class="first" value="first">
|
|
898
|
+
First
|
|
899
|
+
</sp-action-button>
|
|
900
|
+
<sp-action-button class="second" value="second">
|
|
901
|
+
Second
|
|
902
|
+
</sp-action-button>
|
|
903
|
+
</sp-action-group>
|
|
904
|
+
`);
|
|
905
|
+
await elementUpdated(el);
|
|
906
|
+
expect(el.getAttribute("role")).to.equal("toolbar");
|
|
907
|
+
expect(el.selected.length).to.equal(2);
|
|
908
|
+
const firstButton = el.querySelector(".first");
|
|
909
|
+
expect(firstButton.selected, "first button selected").to.be.true;
|
|
910
|
+
expect(firstButton.hasAttribute("aria-checked")).to.be.false;
|
|
911
|
+
expect(
|
|
912
|
+
firstButton.getAttribute("aria-pressed"),
|
|
913
|
+
"first button aria-pressed"
|
|
914
|
+
).to.eq("true");
|
|
915
|
+
expect(firstButton.getAttribute("role"), "first button role").to.eq(
|
|
916
|
+
"button"
|
|
917
|
+
);
|
|
918
|
+
const secondButton = el.querySelector(".second");
|
|
919
|
+
expect(secondButton.selected, "second button selected").to.be.true;
|
|
920
|
+
expect(secondButton.hasAttribute("aria-checked")).to.be.false;
|
|
921
|
+
expect(
|
|
922
|
+
secondButton.getAttribute("aria-pressed"),
|
|
923
|
+
"second button aria-pressed"
|
|
924
|
+
).to.eq("true");
|
|
925
|
+
expect(secondButton.getAttribute("role"), "first button role").to.eq(
|
|
926
|
+
"button"
|
|
927
|
+
);
|
|
928
|
+
firstButton.click();
|
|
929
|
+
await elementUpdated(el);
|
|
930
|
+
expect(el.selected.length).to.equal(2);
|
|
931
|
+
expect(firstButton.selected, "first button selected").to.be.true;
|
|
932
|
+
expect(firstButton.hasAttribute("aria-checked")).to.be.false;
|
|
933
|
+
expect(
|
|
934
|
+
firstButton.getAttribute("aria-pressed"),
|
|
935
|
+
"first button aria-pressed"
|
|
936
|
+
).to.eq("true");
|
|
937
|
+
expect(firstButton.getAttribute("role"), "first button role").to.eq(
|
|
938
|
+
"button"
|
|
939
|
+
);
|
|
940
|
+
expect(secondButton.selected, "second button selected").to.be.true;
|
|
941
|
+
expect(secondButton.hasAttribute("aria-checked")).to.be.false;
|
|
942
|
+
expect(
|
|
943
|
+
secondButton.getAttribute("aria-pressed"),
|
|
944
|
+
"second button aria-pressed"
|
|
945
|
+
).to.eq("true");
|
|
946
|
+
expect(secondButton.getAttribute("role"), "first button role").to.eq(
|
|
947
|
+
"button"
|
|
948
|
+
);
|
|
949
|
+
});
|
|
950
|
+
it('will not change .selected state if event is prevented while [selects="multiple"]', async () => {
|
|
951
|
+
const el = await fixture(html`
|
|
952
|
+
<sp-action-group
|
|
953
|
+
label="Selects Multiple Group"
|
|
954
|
+
selects="multiple"
|
|
955
|
+
.selected=${["first", "second"]}
|
|
956
|
+
@change=${(event) => {
|
|
957
|
+
event.preventDefault();
|
|
958
|
+
}}
|
|
959
|
+
>
|
|
960
|
+
<sp-action-button class="first" value="first">
|
|
961
|
+
First
|
|
962
|
+
</sp-action-button>
|
|
963
|
+
<sp-action-button class="second" value="second">
|
|
964
|
+
Second
|
|
965
|
+
</sp-action-button>
|
|
966
|
+
<sp-action-button class="third " value="third">
|
|
967
|
+
Third
|
|
968
|
+
</sp-action-button>
|
|
969
|
+
</sp-action-group>
|
|
970
|
+
`);
|
|
971
|
+
const firstElement = el.querySelector(".first");
|
|
972
|
+
const secondElement = el.querySelector(".second");
|
|
973
|
+
const thirdElement = el.querySelector(".third");
|
|
974
|
+
await elementUpdated(el);
|
|
975
|
+
expect(el.selected.length).to.equal(2);
|
|
976
|
+
expect(firstElement.selected, "first child selected").to.be.true;
|
|
977
|
+
expect(secondElement.selected, "second child selected").to.be.true;
|
|
978
|
+
thirdElement.click();
|
|
979
|
+
await elementUpdated(el);
|
|
980
|
+
expect(thirdElement.selected, "third child not selected").to.be.false;
|
|
981
|
+
expect(el.selected.length).to.equal(2);
|
|
982
|
+
secondElement.click();
|
|
983
|
+
await elementUpdated(el);
|
|
984
|
+
expect(secondElement.selected, "second element still selected").to.be.true;
|
|
985
|
+
});
|
|
986
|
+
it('will not change .selected state if event is prevented while [selects="single"]', async () => {
|
|
987
|
+
const el = await fixture(html`
|
|
988
|
+
<sp-action-group
|
|
989
|
+
label="Selects Single Group"
|
|
990
|
+
selects="single"
|
|
991
|
+
.selected=${["first"]}
|
|
992
|
+
@change=${(event) => {
|
|
993
|
+
event.preventDefault();
|
|
994
|
+
}}
|
|
995
|
+
>
|
|
996
|
+
<sp-action-button class="first" value="first">
|
|
997
|
+
First
|
|
998
|
+
</sp-action-button>
|
|
999
|
+
<sp-action-button class="second" value="second">
|
|
1000
|
+
Second
|
|
1001
|
+
</sp-action-button>
|
|
1002
|
+
</sp-action-group>
|
|
1003
|
+
`);
|
|
1004
|
+
const firstElement = el.querySelector(".first");
|
|
1005
|
+
const secondElement = el.querySelector(".second");
|
|
1006
|
+
await elementUpdated(el);
|
|
1007
|
+
expect(el.selected.length).to.equal(1);
|
|
1008
|
+
expect(firstElement.selected, "first child selected").to.be.true;
|
|
1009
|
+
secondElement.click();
|
|
1010
|
+
await elementUpdated(el);
|
|
1011
|
+
expect(secondElement.selected, "second child not selected").to.be.false;
|
|
1012
|
+
expect(el.selected.length).to.equal(1);
|
|
1013
|
+
firstElement.click();
|
|
1014
|
+
await elementUpdated(el);
|
|
1015
|
+
expect(firstElement.selected, "first element still selected").to.be.true;
|
|
1016
|
+
});
|
|
1017
|
+
it("will not change .selected state if event is prevented while selects is undefined", async () => {
|
|
1018
|
+
const el = await fixture(html`
|
|
1019
|
+
<sp-action-group
|
|
1020
|
+
label="Selects Single Group"
|
|
1021
|
+
.selected=${["first"]}
|
|
1022
|
+
@change=${(event) => {
|
|
1023
|
+
event.preventDefault();
|
|
1024
|
+
}}
|
|
1025
|
+
>
|
|
1026
|
+
<sp-action-button class="first" value="first">
|
|
1027
|
+
First
|
|
1028
|
+
</sp-action-button>
|
|
1029
|
+
<sp-action-button class="second" value="second">
|
|
1030
|
+
Second
|
|
1031
|
+
</sp-action-button>
|
|
1032
|
+
</sp-action-group>
|
|
1033
|
+
`);
|
|
1034
|
+
const firstElement = el.querySelector(".first");
|
|
1035
|
+
const secondElement = el.querySelector(".second");
|
|
1036
|
+
await elementUpdated(el);
|
|
1037
|
+
expect(el.selected.length).to.equal(1);
|
|
1038
|
+
expect(firstElement.selected, "first child selected").to.be.true;
|
|
1039
|
+
secondElement.click();
|
|
1040
|
+
await elementUpdated(el);
|
|
1041
|
+
expect(el.selected.length).to.equal(1);
|
|
1042
|
+
expect(firstElement.selected, "first child selected").to.be.true;
|
|
1043
|
+
expect(secondElement.selected, "second child not selected").to.be.false;
|
|
1044
|
+
});
|
|
1045
|
+
it("manages a `size` attribute", async () => {
|
|
1046
|
+
const el = await fixture(html`
|
|
1047
|
+
<sp-action-group size="xl">
|
|
1048
|
+
<sp-action-button>Button</sp-action-button>
|
|
1049
|
+
</sp-action-group>
|
|
1050
|
+
`);
|
|
1051
|
+
const button = el.querySelector("sp-action-button");
|
|
1052
|
+
await elementUpdated(el);
|
|
1053
|
+
expect(el.size).to.equal("xl");
|
|
1054
|
+
expect(button.size).to.equal("xl");
|
|
1055
|
+
expect(el.getAttribute("size")).to.equal("xl");
|
|
1056
|
+
expect(button.getAttribute("size")).to.equal("xl");
|
|
1057
|
+
el.removeAttribute("size");
|
|
1058
|
+
await elementUpdated(el);
|
|
1059
|
+
expect(el.size).to.equal("m");
|
|
1060
|
+
expect(el.hasAttribute("size")).to.be.false;
|
|
1061
|
+
expect(button.size).to.equal("m");
|
|
1062
|
+
expect(button.getAttribute("size")).to.equal("m");
|
|
1063
|
+
});
|
|
1064
|
+
it("does not apply a default `size` attribute", async () => {
|
|
1065
|
+
const el = await fixture(html`
|
|
1066
|
+
<sp-action-group>
|
|
1067
|
+
<sp-action-button>Button</sp-action-button>
|
|
1068
|
+
</sp-action-group>
|
|
1069
|
+
`);
|
|
1070
|
+
const button = el.querySelector("sp-action-button");
|
|
1071
|
+
await elementUpdated(el);
|
|
1072
|
+
expect(el.size).to.equal("m");
|
|
1073
|
+
expect(button.size).to.equal("m");
|
|
1074
|
+
expect(el.hasAttribute("size")).to.be.false;
|
|
1075
|
+
expect(button.hasAttribute("size")).to.be.false;
|
|
1076
|
+
});
|
|
1077
|
+
it("will accept selected as a JSON string", async () => {
|
|
1078
|
+
const el = await fixture(html`
|
|
1079
|
+
<sp-action-group
|
|
1080
|
+
label="Selects Single Group"
|
|
1081
|
+
selects="single"
|
|
1082
|
+
selected='["first"]'
|
|
1083
|
+
>
|
|
1084
|
+
<sp-action-button class="first" value="first">
|
|
1085
|
+
First
|
|
1086
|
+
</sp-action-button>
|
|
1087
|
+
<sp-action-button class="second" value="second">
|
|
1088
|
+
Second
|
|
1089
|
+
</sp-action-button>
|
|
1090
|
+
</sp-action-group>
|
|
1091
|
+
`);
|
|
1092
|
+
await elementUpdated(el);
|
|
1093
|
+
const firstElement = el.querySelector(".first");
|
|
1094
|
+
const secondElement = el.querySelector(".second");
|
|
1095
|
+
expect(el.selected.length).to.equal(1);
|
|
1096
|
+
expect(firstElement.selected, "first child selected").to.be.true;
|
|
1097
|
+
expect(secondElement.selected, "second child selected").to.be.false;
|
|
1098
|
+
});
|
|
1099
|
+
it("accepts role attribute override", async () => {
|
|
1100
|
+
const el = await fixture(html`
|
|
1101
|
+
<sp-action-group role="group">
|
|
1102
|
+
<sp-action-button>Button</sp-action-button>
|
|
1103
|
+
</sp-action-group>
|
|
1104
|
+
`);
|
|
1105
|
+
await elementUpdated(el);
|
|
1106
|
+
expect(el.getAttribute("role")).to.equal("group");
|
|
1107
|
+
el.setAttribute("selects", "single");
|
|
1108
|
+
await elementUpdated(el);
|
|
1109
|
+
expect(el.getAttribute("role")).to.equal("radiogroup");
|
|
1110
|
+
el.setAttribute("selects", "multiple");
|
|
1111
|
+
await elementUpdated(el);
|
|
1112
|
+
expect(el.getAttribute("role")).to.equal("toolbar");
|
|
1113
|
+
el.removeAttribute("role");
|
|
1114
|
+
el.removeAttribute("selects");
|
|
1115
|
+
await elementUpdated(el);
|
|
1116
|
+
expect(el.getAttribute("role")).to.equal("toolbar");
|
|
1117
|
+
});
|
|
1118
|
+
const acceptKeyboardInput = async (el) => {
|
|
1119
|
+
const thirdElement = el.querySelector(".third");
|
|
1120
|
+
await elementUpdated(el);
|
|
1121
|
+
expect(el.selected.length).to.equal(1);
|
|
1122
|
+
expect(el.selected[0]).to.equal("Second");
|
|
1123
|
+
thirdElement.focus();
|
|
1124
|
+
thirdElement.click();
|
|
1125
|
+
await elementUpdated(el);
|
|
1126
|
+
expect(thirdElement.selected, "third child selected").to.be.true;
|
|
1127
|
+
expect(el.selected.length).to.equal(1);
|
|
1128
|
+
expect(el.selected[0]).to.equal("Third");
|
|
1129
|
+
el.dispatchEvent(arrowRightEvent());
|
|
1130
|
+
await sendKeys({ press: "Enter" });
|
|
1131
|
+
await elementUpdated(el);
|
|
1132
|
+
expect(el.selected.length).to.equal(1);
|
|
1133
|
+
expect(el.selected[0]).to.equal("First");
|
|
1134
|
+
el.dispatchEvent(arrowLeftEvent());
|
|
1135
|
+
el.dispatchEvent(arrowUpEvent());
|
|
1136
|
+
await sendKeys({ press: "Enter" });
|
|
1137
|
+
expect(el.selected.length).to.equal(1);
|
|
1138
|
+
expect(el.selected[0]).to.equal("Second");
|
|
1139
|
+
el.dispatchEvent(endEvent());
|
|
1140
|
+
await sendKeys({ press: "Enter" });
|
|
1141
|
+
expect(el.selected.length).to.equal(1);
|
|
1142
|
+
expect(el.selected[0]).to.equal("Third");
|
|
1143
|
+
await sendKeys({ press: "Enter" });
|
|
1144
|
+
el.dispatchEvent(homeEvent());
|
|
1145
|
+
await sendKeys({ press: "Enter" });
|
|
1146
|
+
expect(el.selected.length).to.equal(1);
|
|
1147
|
+
expect(el.selected[0]).to.equal("First");
|
|
1148
|
+
el.dispatchEvent(arrowDownEvent());
|
|
1149
|
+
await sendKeys({ press: "Enter" });
|
|
1150
|
+
expect(el.selected.length).to.equal(1);
|
|
1151
|
+
expect(el.selected[0]).to.equal("Second");
|
|
1152
|
+
};
|
|
1153
|
+
it("accepts keybord input", async () => {
|
|
1154
|
+
const el = await fixture(html`
|
|
1155
|
+
<sp-action-group label="Selects Single Group" selects="single">
|
|
1156
|
+
<sp-action-button>First</sp-action-button>
|
|
1157
|
+
<sp-action-button selected>Second</sp-action-button>
|
|
1158
|
+
<sp-action-button class="third">Third</sp-action-button>
|
|
1159
|
+
</sp-action-group>
|
|
1160
|
+
`);
|
|
1161
|
+
await acceptKeyboardInput(el);
|
|
1162
|
+
});
|
|
1163
|
+
it("accepts keybord input with tooltip", async () => {
|
|
1164
|
+
const el = await fixture(html`
|
|
1165
|
+
<sp-action-group label="Selects Single Group" selects="single">
|
|
1166
|
+
<overlay-trigger>
|
|
1167
|
+
<sp-action-button slot="trigger">First</sp-action-button>
|
|
1168
|
+
<sp-tooltip slot="hover-content">
|
|
1169
|
+
Definitely the first one.
|
|
1170
|
+
</sp-tooltip>
|
|
1171
|
+
</overlay-trigger>
|
|
1172
|
+
<overlay-trigger>
|
|
1173
|
+
<sp-action-button slot="trigger" selected>
|
|
1174
|
+
Second
|
|
1175
|
+
</sp-action-button>
|
|
1176
|
+
<sp-tooltip slot="hover-content">
|
|
1177
|
+
Not the first, not the last.
|
|
1178
|
+
</sp-tooltip>
|
|
1179
|
+
</overlay-trigger>
|
|
1180
|
+
<overlay-trigger>
|
|
1181
|
+
<sp-action-button slot="trigger" class="third">
|
|
1182
|
+
Third
|
|
1183
|
+
</sp-action-button>
|
|
1184
|
+
<sp-tooltip slot="hover-content">Select me.</sp-tooltip>
|
|
1185
|
+
</overlay-trigger>
|
|
1186
|
+
</sp-action-group>
|
|
1187
|
+
`);
|
|
1188
|
+
await acceptKeyboardInput(el);
|
|
1189
|
+
});
|
|
1190
|
+
it('accepts keybord input when [dir="ltr"]', async () => {
|
|
1191
|
+
const el = await fixture(html`
|
|
1192
|
+
<sp-action-group
|
|
1193
|
+
label="Selects Single Group"
|
|
1194
|
+
selects="single"
|
|
1195
|
+
dir="ltr"
|
|
1196
|
+
>
|
|
1197
|
+
<sp-action-button>First</sp-action-button>
|
|
1198
|
+
<sp-action-button disabled>Second</sp-action-button>
|
|
1199
|
+
<sp-action-button class="third">Third</sp-action-button>
|
|
1200
|
+
</sp-action-group>
|
|
1201
|
+
`);
|
|
1202
|
+
const thirdElement = el.querySelector(".third");
|
|
1203
|
+
await elementUpdated(el);
|
|
1204
|
+
expect(el.selected.length).to.equal(0);
|
|
1205
|
+
thirdElement.focus();
|
|
1206
|
+
thirdElement.click();
|
|
1207
|
+
await elementUpdated(el);
|
|
1208
|
+
expect(thirdElement.selected, "third child selected").to.be.true;
|
|
1209
|
+
expect(el.selected.length).to.equal(1);
|
|
1210
|
+
expect(el.selected[0]).to.equal("Third");
|
|
1211
|
+
el.dispatchEvent(arrowRightEvent());
|
|
1212
|
+
await sendKeys({ press: "Enter" });
|
|
1213
|
+
await elementUpdated(el);
|
|
1214
|
+
expect(el.selected.length).to.equal(1);
|
|
1215
|
+
expect(el.selected[0]).to.equal("First");
|
|
1216
|
+
el.dispatchEvent(arrowUpEvent());
|
|
1217
|
+
await sendKeys({ press: "Enter" });
|
|
1218
|
+
expect(el.selected.length).to.equal(1);
|
|
1219
|
+
expect(el.selected[0]).to.equal("Third");
|
|
1220
|
+
});
|
|
1221
|
+
it("processes `selects` correctly when mutations occur (because Overlays/Tooltips)", async () => {
|
|
1222
|
+
const test = await fixture(controlled());
|
|
1223
|
+
const actionButtons = [
|
|
1224
|
+
...test.shadowRoot.querySelectorAll("sp-action-button")
|
|
1225
|
+
];
|
|
1226
|
+
expect(actionButtons[0].selected).to.be.true;
|
|
1227
|
+
expect(actionButtons[1].selected).to.be.false;
|
|
1228
|
+
expect(actionButtons[2].selected).to.be.false;
|
|
1229
|
+
const changeSpy = spy();
|
|
1230
|
+
test.addEventListener("change", () => changeSpy());
|
|
1231
|
+
const rect = actionButtons[1].getBoundingClientRect();
|
|
1232
|
+
sendMouse({
|
|
1233
|
+
steps: [
|
|
1234
|
+
{
|
|
1235
|
+
position: [
|
|
1236
|
+
rect.left + rect.width / 2,
|
|
1237
|
+
rect.top + rect.height / 2
|
|
1238
|
+
],
|
|
1239
|
+
type: "click"
|
|
1240
|
+
}
|
|
1241
|
+
]
|
|
1242
|
+
});
|
|
1243
|
+
await aTimeout(500);
|
|
1244
|
+
expect(actionButtons[0].selected).to.be.false;
|
|
1245
|
+
expect(actionButtons[1].selected).to.be.true;
|
|
1246
|
+
expect(actionButtons[2].selected).to.be.false;
|
|
1247
|
+
});
|
|
1248
|
+
});
|
|
1249
|
+
//# sourceMappingURL=action-group.test.js.map
|