@spectrum-web-components/overlay 0.18.0 → 0.18.2
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/active-overlay.dev.js +1 -0
- package/active-overlay.dev.js.map +1 -1
- package/active-overlay.js +1 -1
- package/active-overlay.js.map +2 -2
- package/overlay-trigger.dev.js +1 -0
- package/overlay-trigger.dev.js.map +1 -1
- package/overlay-trigger.js +1 -1
- package/overlay-trigger.js.map +2 -2
- package/package.json +4 -4
- package/src/ActiveOverlay.dev.js +60 -24
- package/src/ActiveOverlay.dev.js.map +3 -3
- package/src/ActiveOverlay.js +3 -3
- package/src/ActiveOverlay.js.map +3 -3
- package/src/OverlayTrigger.dev.js +51 -18
- package/src/OverlayTrigger.dev.js.map +1 -1
- package/src/OverlayTrigger.js +2 -2
- package/src/OverlayTrigger.js.map +2 -2
- package/src/VirtualTrigger.dev.js +1 -0
- package/src/VirtualTrigger.dev.js.map +1 -1
- package/src/VirtualTrigger.js +1 -1
- package/src/VirtualTrigger.js.map +2 -2
- package/src/active-overlay.css.dev.js +1 -0
- package/src/active-overlay.css.dev.js.map +1 -1
- package/src/active-overlay.css.js +1 -1
- package/src/active-overlay.css.js.map +2 -2
- package/src/index.dev.js +1 -0
- package/src/index.dev.js.map +1 -1
- package/src/index.js +1 -1
- package/src/index.js.map +1 -1
- package/src/loader.dev.js +1 -0
- package/src/loader.dev.js.map +1 -1
- package/src/loader.js +1 -1
- package/src/loader.js.map +2 -2
- package/src/overlay-events.dev.js +1 -0
- package/src/overlay-events.dev.js.map +1 -1
- package/src/overlay-events.js +1 -1
- package/src/overlay-events.js.map +2 -2
- package/src/overlay-stack.d.ts +1 -1
- package/src/overlay-stack.dev.js +97 -46
- package/src/overlay-stack.dev.js.map +3 -3
- package/src/overlay-stack.js +2 -2
- package/src/overlay-stack.js.map +3 -3
- package/src/overlay-timer.dev.js +1 -0
- package/src/overlay-timer.dev.js.map +1 -1
- package/src/overlay-timer.js +1 -1
- package/src/overlay-timer.js.map +2 -2
- package/src/overlay-trigger.css.dev.js +1 -0
- package/src/overlay-trigger.css.dev.js.map +1 -1
- package/src/overlay-trigger.css.js +1 -1
- package/src/overlay-trigger.css.js.map +2 -2
- package/src/overlay-types.dev.js +1 -0
- package/src/overlay-types.js +1 -0
- package/src/overlay-utils.dev.js +4 -1
- package/src/overlay-utils.dev.js.map +1 -1
- package/src/overlay-utils.js +1 -1
- package/src/overlay-utils.js.map +2 -2
- package/src/overlay.dev.js +1 -0
- package/src/overlay.dev.js.map +1 -1
- package/src/overlay.js +1 -1
- package/src/overlay.js.map +2 -2
- package/stories/overlay-story-components.js +219 -11
- package/stories/overlay-story-components.js.map +2 -2
- package/stories/overlay.stories.js +354 -55
- package/stories/overlay.stories.js.map +1 -1
- package/sync/overlay-trigger.dev.js +1 -0
- package/sync/overlay-trigger.dev.js.map +1 -1
- package/sync/overlay-trigger.js +1 -1
- package/sync/overlay-trigger.js.map +2 -2
- package/test/benchmark/basic-test.js +10 -2
- package/test/benchmark/basic-test.js.map +1 -1
- package/test/overlay-lifecycle.test.js +149 -6
- package/test/overlay-lifecycle.test.js.map +1 -1
- package/test/overlay-timer.test.js +117 -1
- package/test/overlay-timer.test.js.map +2 -2
- package/test/overlay-trigger-click.test.js +66 -7
- package/test/overlay-trigger-click.test.js.map +1 -1
- package/test/overlay-trigger-extended.test.js +187 -4
- package/test/overlay-trigger-extended.test.js.map +1 -1
- package/test/overlay-trigger-hover-click.test.js +68 -3
- package/test/overlay-trigger-hover-click.test.js.map +1 -1
- package/test/overlay-trigger-hover.test.js +172 -7
- package/test/overlay-trigger-hover.test.js.map +2 -2
- package/test/overlay-trigger-longpress.test.js +233 -9
- package/test/overlay-trigger-longpress.test.js.map +2 -2
- package/test/overlay-trigger-sync.test.js +536 -4
- package/test/overlay-trigger-sync.test.js.map +2 -2
- package/test/overlay-trigger.test.js +536 -4
- package/test/overlay-trigger.test.js.map +2 -2
- package/test/overlay.test-vrt.js +4 -1
- package/test/overlay.test-vrt.js.map +1 -1
- package/test/overlay.test.js +565 -11
- package/test/overlay.test.js.map +1 -1
|
@@ -1,23 +1,100 @@
|
|
|
1
|
-
|
|
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/overlay/overlay-trigger.js";
|
|
13
|
+
import "@spectrum-web-components/popover/sp-popover.js";
|
|
14
|
+
import "@spectrum-web-components/button/sp-button.js";
|
|
15
|
+
import "@spectrum-web-components/tooltip/sp-tooltip.js";
|
|
16
|
+
import "@spectrum-web-components/dialog/sp-dialog-wrapper.js";
|
|
17
|
+
import "@spectrum-web-components/action-button/sp-action-button.js";
|
|
18
|
+
import "@spectrum-web-components/icons-workflow/icons/sp-icon-magnify.js";
|
|
19
|
+
import { spy } from "sinon";
|
|
20
|
+
import { sendKeys } from "@web/test-runner-commands";
|
|
21
|
+
import "@spectrum-web-components/theme/sp-theme.js";
|
|
22
|
+
import "@spectrum-web-components/theme/src/themes.js";
|
|
23
|
+
async function styledFixture(story) {
|
|
24
|
+
const test = await fixture(html`
|
|
25
|
+
<sp-theme theme="spectrum" scale="medium" color="light">
|
|
26
|
+
${story}
|
|
27
|
+
</sp-theme>
|
|
28
|
+
`);
|
|
29
|
+
return test.children[0];
|
|
30
|
+
}
|
|
31
|
+
describe("Overlay Trigger - Hover", () => {
|
|
32
|
+
afterEach(async () => {
|
|
33
|
+
const el = document.querySelector("overlay-trigger");
|
|
34
|
+
if (el.open) {
|
|
35
|
+
const closed = oneEvent(el, "sp-closed");
|
|
36
|
+
el.open = void 0;
|
|
37
|
+
await closed;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
it("displays `hover` declaratively", async () => {
|
|
41
|
+
const openedSpy = spy();
|
|
42
|
+
const closedSpy = spy();
|
|
43
|
+
const el = await fixture(
|
|
44
|
+
(() => html`
|
|
2
45
|
<overlay-trigger
|
|
3
46
|
placement="right-start"
|
|
4
47
|
open="hover"
|
|
5
|
-
@sp-opened=${()=>
|
|
6
|
-
@sp-closed=${()=>
|
|
48
|
+
@sp-opened=${() => openedSpy()}
|
|
49
|
+
@sp-closed=${() => closedSpy()}
|
|
7
50
|
>
|
|
8
51
|
<sp-action-button slot="trigger">
|
|
9
52
|
<sp-icon-magnify slot="icon"></sp-icon-magnify>
|
|
10
53
|
</sp-action-button>
|
|
11
54
|
<sp-popover slot="hover-content" tip></sp-popover>
|
|
12
55
|
</overlay-trigger>
|
|
13
|
-
`)()
|
|
56
|
+
`)()
|
|
57
|
+
);
|
|
58
|
+
await elementUpdated(el);
|
|
59
|
+
await waitUntil(
|
|
60
|
+
() => openedSpy.calledOnce,
|
|
61
|
+
"hover content projected to overlay",
|
|
62
|
+
{ timeout: 2e3 }
|
|
63
|
+
);
|
|
64
|
+
el.removeAttribute("open");
|
|
65
|
+
await elementUpdated(el);
|
|
66
|
+
await waitUntil(() => closedSpy.calledOnce, "hover content returned", {
|
|
67
|
+
timeout: 2e3
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
it("persists hover content", async () => {
|
|
71
|
+
const el = await fixture(
|
|
72
|
+
(() => html`
|
|
14
73
|
<overlay-trigger placement="right-start">
|
|
15
74
|
<sp-action-button slot="trigger">
|
|
16
75
|
<sp-icon-magnify slot="icon"></sp-icon-magnify>
|
|
17
76
|
</sp-action-button>
|
|
18
77
|
<sp-popover slot="hover-content" tip></sp-popover>
|
|
19
78
|
</overlay-trigger>
|
|
20
|
-
`)()
|
|
79
|
+
`)()
|
|
80
|
+
);
|
|
81
|
+
await elementUpdated(el);
|
|
82
|
+
expect(el.open).to.be.undefined;
|
|
83
|
+
const trigger = el.querySelector('[slot="trigger"]');
|
|
84
|
+
trigger.dispatchEvent(
|
|
85
|
+
new Event("mouseenter", {
|
|
86
|
+
bubbles: true
|
|
87
|
+
})
|
|
88
|
+
);
|
|
89
|
+
await elementUpdated(el);
|
|
90
|
+
expect(el.open).to.equal("hover");
|
|
91
|
+
trigger.click();
|
|
92
|
+
await elementUpdated(el);
|
|
93
|
+
expect(el.open).to.equal("hover");
|
|
94
|
+
});
|
|
95
|
+
it("closes persistent hover content on `longpress`", async () => {
|
|
96
|
+
const el = await fixture(
|
|
97
|
+
(() => html`
|
|
21
98
|
<overlay-trigger placement="right-start">
|
|
22
99
|
<sp-action-button slot="trigger">
|
|
23
100
|
<sp-icon-magnify slot="icon"></sp-icon-magnify>
|
|
@@ -25,12 +102,100 @@ import{aTimeout as g,elementUpdated as o,expect as r,fixture as i,html as a,oneE
|
|
|
25
102
|
<sp-popover slot="hover-content" tip></sp-popover>
|
|
26
103
|
<sp-popover slot="longpress-content" tip></sp-popover>
|
|
27
104
|
</overlay-trigger>
|
|
28
|
-
`)()
|
|
105
|
+
`)()
|
|
106
|
+
);
|
|
107
|
+
await elementUpdated(el);
|
|
108
|
+
expect(el.open).to.be.undefined;
|
|
109
|
+
const trigger = el.querySelector('[slot="trigger"]');
|
|
110
|
+
trigger.dispatchEvent(
|
|
111
|
+
new Event("mouseenter", {
|
|
112
|
+
bubbles: true
|
|
113
|
+
})
|
|
114
|
+
);
|
|
115
|
+
await elementUpdated(el);
|
|
116
|
+
expect(el.open).to.equal("hover");
|
|
117
|
+
trigger.dispatchEvent(
|
|
118
|
+
new Event("longpress", {
|
|
119
|
+
bubbles: true
|
|
120
|
+
})
|
|
121
|
+
);
|
|
122
|
+
await elementUpdated(el);
|
|
123
|
+
expect(el.open).to.equal("longpress");
|
|
124
|
+
});
|
|
125
|
+
it('closes `hover` overlay when [type="modal"]', async () => {
|
|
126
|
+
const el = await fixture(
|
|
127
|
+
(() => html`
|
|
29
128
|
<overlay-trigger placement="right-start" type="modal">
|
|
30
129
|
<sp-action-button slot="trigger">
|
|
31
130
|
<sp-icon-magnify slot="icon"></sp-icon-magnify>
|
|
32
131
|
</sp-action-button>
|
|
33
132
|
<sp-popover slot="hover-content" tip></sp-popover>
|
|
34
133
|
</overlay-trigger>
|
|
35
|
-
`)()
|
|
134
|
+
`)()
|
|
135
|
+
);
|
|
136
|
+
await elementUpdated(el);
|
|
137
|
+
expect(el.open).to.be.undefined;
|
|
138
|
+
const trigger = el.querySelector('[slot="trigger"]');
|
|
139
|
+
const opened = oneEvent(el, "sp-opened");
|
|
140
|
+
trigger.focus();
|
|
141
|
+
await opened;
|
|
142
|
+
await elementUpdated(el);
|
|
143
|
+
await aTimeout(500);
|
|
144
|
+
expect(el.open).to.equal("hover");
|
|
145
|
+
const closed = oneEvent(el, "sp-closed");
|
|
146
|
+
trigger.blur();
|
|
147
|
+
await closed;
|
|
148
|
+
await elementUpdated(el);
|
|
149
|
+
expect(el.open).to.be.null;
|
|
150
|
+
});
|
|
151
|
+
it('will not return focus to a "modal" parent', async () => {
|
|
152
|
+
const el = await styledFixture(html`
|
|
153
|
+
<overlay-trigger type="modal" placement="none">
|
|
154
|
+
<sp-button slot="trigger">Toggle Dialog</sp-button>
|
|
155
|
+
<sp-dialog-wrapper
|
|
156
|
+
slot="click-content"
|
|
157
|
+
headline="Dialog title"
|
|
158
|
+
size="s"
|
|
159
|
+
>
|
|
160
|
+
${[1, 2, 3, 4].map(
|
|
161
|
+
(index) => html`
|
|
162
|
+
<overlay-trigger>
|
|
163
|
+
<sp-button slot="trigger" id="button-${index}">
|
|
164
|
+
Button with Tooltip ${index}
|
|
165
|
+
</sp-button>
|
|
166
|
+
<sp-tooltip slot="hover-content">
|
|
167
|
+
Tooltip ${index}
|
|
168
|
+
</sp-tooltip>
|
|
169
|
+
</overlay-trigger>
|
|
170
|
+
`
|
|
171
|
+
)}
|
|
172
|
+
</sp-dialog-wrapper>
|
|
173
|
+
</overlay-trigger>
|
|
174
|
+
`);
|
|
175
|
+
await elementUpdated(el);
|
|
176
|
+
const button = el.querySelector("sp-button");
|
|
177
|
+
const dialog = el.querySelector("sp-dialog-wrapper");
|
|
178
|
+
await elementUpdated(button);
|
|
179
|
+
await elementUpdated(dialog);
|
|
180
|
+
let opened = oneEvent(button, "sp-opened");
|
|
181
|
+
button.dispatchEvent(new Event("click", { bubbles: true }));
|
|
182
|
+
await opened;
|
|
183
|
+
const button1 = dialog.querySelector("#button-1");
|
|
184
|
+
const button2 = dialog.querySelector("#button-2");
|
|
185
|
+
opened = oneEvent(button1, "sp-opened");
|
|
186
|
+
sendKeys({
|
|
187
|
+
press: "Tab"
|
|
188
|
+
});
|
|
189
|
+
await opened;
|
|
190
|
+
await nextFrame();
|
|
191
|
+
expect(button1 === document.activeElement).to.be.true;
|
|
192
|
+
opened = oneEvent(button2, "sp-opened");
|
|
193
|
+
sendKeys({
|
|
194
|
+
press: "Tab"
|
|
195
|
+
});
|
|
196
|
+
await opened;
|
|
197
|
+
await nextFrame();
|
|
198
|
+
expect(button2 === document.activeElement).to.be.true;
|
|
199
|
+
});
|
|
200
|
+
});
|
|
36
201
|
//# sourceMappingURL=overlay-trigger-hover.test.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["overlay-trigger-hover.test.ts"],
|
|
4
|
-
"sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport {\n aTimeout,\n elementUpdated,\n expect,\n fixture,\n html,\n oneEvent,\n waitUntil,\n} from '@open-wc/testing';\nimport '@spectrum-web-components/popover/sp-popover.js';\nimport '@spectrum-web-components/action-button/sp-action-button.js';\nimport '@spectrum-web-components/icons-workflow/icons/sp-icon-magnify.js';\nimport { OverlayTrigger } from '@spectrum-web-components/overlay';\nimport '@spectrum-web-components/
|
|
5
|
-
"mappings": "AAWA,
|
|
4
|
+
"sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\nimport {\n aTimeout,\n elementUpdated,\n expect,\n fixture,\n html,\n nextFrame,\n oneEvent,\n waitUntil,\n} from '@open-wc/testing';\nimport '@spectrum-web-components/overlay/overlay-trigger.js';\nimport '@spectrum-web-components/popover/sp-popover.js';\nimport '@spectrum-web-components/button/sp-button.js';\nimport '@spectrum-web-components/tooltip/sp-tooltip.js';\nimport '@spectrum-web-components/dialog/sp-dialog-wrapper.js';\nimport '@spectrum-web-components/action-button/sp-action-button.js';\nimport '@spectrum-web-components/icons-workflow/icons/sp-icon-magnify.js';\nimport { OverlayTrigger } from '@spectrum-web-components/overlay';\nimport { spy } from 'sinon';\nimport { ActionButton } from '@spectrum-web-components/action-button';\nimport { sendKeys } from '@web/test-runner-commands';\nimport { Button } from '@spectrum-web-components/button';\nimport '@spectrum-web-components/theme/sp-theme.js';\nimport '@spectrum-web-components/theme/src/themes.js';\nimport { TemplateResult } from '@spectrum-web-components/base';\nimport { Theme } from '@spectrum-web-components/theme';\n\nasync function styledFixture<T extends Element>(\n story: TemplateResult\n): Promise<T> {\n const test = await fixture<Theme>(html`\n <sp-theme theme=\"spectrum\" scale=\"medium\" color=\"light\">\n ${story}\n </sp-theme>\n `);\n return test.children[0] as T;\n}\n\ndescribe('Overlay Trigger - Hover', () => {\n afterEach(async () => {\n const el = document.querySelector('overlay-trigger') as OverlayTrigger;\n if (el.open) {\n const closed = oneEvent(el, 'sp-closed');\n el.open = undefined;\n await closed;\n }\n });\n it('displays `hover` declaratively', async () => {\n const openedSpy = spy();\n const closedSpy = spy();\n const el = await fixture<OverlayTrigger>(\n (() => html`\n <overlay-trigger\n placement=\"right-start\"\n open=\"hover\"\n @sp-opened=${() => openedSpy()}\n @sp-closed=${() => closedSpy()}\n >\n <sp-action-button slot=\"trigger\">\n <sp-icon-magnify slot=\"icon\"></sp-icon-magnify>\n </sp-action-button>\n <sp-popover slot=\"hover-content\" tip></sp-popover>\n </overlay-trigger>\n `)()\n );\n await elementUpdated(el);\n\n await waitUntil(\n () => openedSpy.calledOnce,\n 'hover content projected to overlay',\n { timeout: 2000 }\n );\n\n el.removeAttribute('open');\n await elementUpdated(el);\n\n await waitUntil(() => closedSpy.calledOnce, 'hover content returned', {\n timeout: 2000,\n });\n });\n it('persists hover content', async () => {\n const el = await fixture<OverlayTrigger>(\n (() => html`\n <overlay-trigger placement=\"right-start\">\n <sp-action-button slot=\"trigger\">\n <sp-icon-magnify slot=\"icon\"></sp-icon-magnify>\n </sp-action-button>\n <sp-popover slot=\"hover-content\" tip></sp-popover>\n </overlay-trigger>\n `)()\n );\n await elementUpdated(el);\n\n expect(el.open).to.be.undefined;\n\n const trigger = el.querySelector('[slot=\"trigger\"]') as ActionButton;\n trigger.dispatchEvent(\n new Event('mouseenter', {\n bubbles: true,\n })\n );\n\n await elementUpdated(el);\n\n expect(el.open).to.equal('hover');\n\n trigger.click();\n\n await elementUpdated(el);\n\n expect(el.open).to.equal('hover');\n });\n it('closes persistent hover content on `longpress`', async () => {\n const el = await fixture<OverlayTrigger>(\n (() => html`\n <overlay-trigger placement=\"right-start\">\n <sp-action-button slot=\"trigger\">\n <sp-icon-magnify slot=\"icon\"></sp-icon-magnify>\n </sp-action-button>\n <sp-popover slot=\"hover-content\" tip></sp-popover>\n <sp-popover slot=\"longpress-content\" tip></sp-popover>\n </overlay-trigger>\n `)()\n );\n await elementUpdated(el);\n\n expect(el.open).to.be.undefined;\n\n const trigger = el.querySelector('[slot=\"trigger\"]') as ActionButton;\n trigger.dispatchEvent(\n new Event('mouseenter', {\n bubbles: true,\n })\n );\n\n await elementUpdated(el);\n\n expect(el.open).to.equal('hover');\n\n trigger.dispatchEvent(\n new Event('longpress', {\n bubbles: true,\n })\n );\n\n await elementUpdated(el);\n\n expect(el.open).to.equal('longpress');\n });\n it('closes `hover` overlay when [type=\"modal\"]', async () => {\n const el = await fixture<OverlayTrigger>(\n (() => html`\n <overlay-trigger placement=\"right-start\" type=\"modal\">\n <sp-action-button slot=\"trigger\">\n <sp-icon-magnify slot=\"icon\"></sp-icon-magnify>\n </sp-action-button>\n <sp-popover slot=\"hover-content\" tip></sp-popover>\n </overlay-trigger>\n `)()\n );\n await elementUpdated(el);\n\n expect(el.open).to.be.undefined;\n\n const trigger = el.querySelector('[slot=\"trigger\"]') as ActionButton;\n const opened = oneEvent(el, 'sp-opened');\n trigger.focus();\n await opened;\n\n await elementUpdated(el);\n await aTimeout(500);\n\n expect(el.open).to.equal('hover');\n\n const closed = oneEvent(el, 'sp-closed');\n trigger.blur();\n await closed;\n\n await elementUpdated(el);\n\n expect(el.open).to.be.null;\n });\n it('will not return focus to a \"modal\" parent', async () => {\n const el = await styledFixture<OverlayTrigger>(html`\n <overlay-trigger type=\"modal\" placement=\"none\">\n <sp-button slot=\"trigger\">Toggle Dialog</sp-button>\n <sp-dialog-wrapper\n slot=\"click-content\"\n headline=\"Dialog title\"\n size=\"s\"\n >\n ${[1, 2, 3, 4].map(\n (index) => html`\n <overlay-trigger>\n <sp-button slot=\"trigger\" id=\"button-${index}\">\n Button with Tooltip ${index}\n </sp-button>\n <sp-tooltip slot=\"hover-content\">\n Tooltip ${index}\n </sp-tooltip>\n </overlay-trigger>\n `\n )}\n </sp-dialog-wrapper>\n </overlay-trigger>\n `);\n await elementUpdated(el);\n\n const button = el.querySelector('sp-button') as Button;\n const dialog = el.querySelector('sp-dialog-wrapper') as HTMLElement;\n await elementUpdated(button);\n await elementUpdated(dialog);\n\n let opened = oneEvent(button, 'sp-opened');\n button.dispatchEvent(new Event('click', { bubbles: true }));\n await opened;\n const button1 = dialog.querySelector('#button-1') as Button;\n const button2 = dialog.querySelector('#button-2') as Button;\n\n opened = oneEvent(button1, 'sp-opened');\n sendKeys({\n press: 'Tab',\n });\n await opened;\n\n await nextFrame();\n\n expect(button1 === document.activeElement).to.be.true;\n\n opened = oneEvent(button2, 'sp-opened');\n sendKeys({\n press: 'Tab',\n });\n await opened;\n\n await nextFrame();\n\n expect(button2 === document.activeElement).to.be.true;\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,4 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
import {
|
|
3
|
+
elementUpdated,
|
|
4
|
+
expect,
|
|
5
|
+
fixture,
|
|
6
|
+
html,
|
|
7
|
+
nextFrame,
|
|
8
|
+
oneEvent,
|
|
9
|
+
waitUntil
|
|
10
|
+
} from "@open-wc/testing";
|
|
11
|
+
import "@spectrum-web-components/action-button/sp-action-button.js";
|
|
12
|
+
import "@spectrum-web-components/action-group/sp-action-group.js";
|
|
13
|
+
import "@spectrum-web-components/icons-workflow/icons/sp-icon-magnify.js";
|
|
14
|
+
import "@spectrum-web-components/popover/sp-popover.js";
|
|
15
|
+
import {
|
|
16
|
+
LONGPRESS_INSTRUCTIONS
|
|
17
|
+
} from "@spectrum-web-components/overlay";
|
|
18
|
+
import "@spectrum-web-components/overlay/overlay-trigger.js";
|
|
19
|
+
import { sendKeys } from "@web/test-runner-commands";
|
|
20
|
+
import { spy } from "sinon";
|
|
21
|
+
import { sendMouse } from "../../../test/plugins/browser.js";
|
|
22
|
+
import { findDescribedNode } from "../../../test/testing-helpers-a11y.js";
|
|
23
|
+
describe("Overlay Trigger - Longpress", () => {
|
|
24
|
+
it("displays `longpress` content", async () => {
|
|
25
|
+
const el = await fixture(
|
|
26
|
+
(() => html`
|
|
2
27
|
<overlay-trigger placement="right-start">
|
|
3
28
|
<sp-action-button slot="trigger" hold-affordance>
|
|
4
29
|
<sp-icon-magnify slot="icon"></sp-icon-magnify>
|
|
@@ -21,19 +46,84 @@ import{elementUpdated as i,expect as o,fixture as g,html as u,nextFrame as y,one
|
|
|
21
46
|
</sp-action-group>
|
|
22
47
|
</sp-popover>
|
|
23
48
|
</overlay-trigger>
|
|
24
|
-
`)()
|
|
49
|
+
`)()
|
|
50
|
+
);
|
|
51
|
+
await elementUpdated(el);
|
|
52
|
+
const trigger = el.querySelector("sp-action-button");
|
|
53
|
+
const content = el.querySelector(
|
|
54
|
+
'[slot="longpress-content"]'
|
|
55
|
+
);
|
|
56
|
+
expect(trigger).to.not.be.null;
|
|
57
|
+
expect(content).to.not.be.null;
|
|
58
|
+
expect(content.open).to.be.false;
|
|
59
|
+
trigger.focus();
|
|
60
|
+
let open = oneEvent(el, "sp-opened");
|
|
61
|
+
await sendKeys({
|
|
62
|
+
press: "Space"
|
|
63
|
+
});
|
|
64
|
+
await open;
|
|
65
|
+
expect(content.open, "opens for `Space`").to.be.true;
|
|
66
|
+
let closed = oneEvent(el, "sp-closed");
|
|
67
|
+
document.body.click();
|
|
68
|
+
await closed;
|
|
69
|
+
expect(!content.open, "closes for `Space`").to.be.true;
|
|
70
|
+
trigger.focus();
|
|
71
|
+
open = oneEvent(el, "sp-opened");
|
|
72
|
+
sendKeys({
|
|
73
|
+
press: "Alt+ArrowDown"
|
|
74
|
+
});
|
|
75
|
+
await open;
|
|
76
|
+
expect(content.open, "opens for `Alt+ArrowDown`").to.be.true;
|
|
77
|
+
closed = oneEvent(el, "sp-closed");
|
|
78
|
+
await sendKeys({
|
|
79
|
+
press: "Escape"
|
|
80
|
+
});
|
|
81
|
+
await closed;
|
|
82
|
+
expect(!content.open, "closes for `Alt+ArrowDown`").to.be.true;
|
|
83
|
+
await elementUpdated(el);
|
|
84
|
+
open = oneEvent(el, "sp-opened");
|
|
85
|
+
trigger.dispatchEvent(new PointerEvent("pointerdown", { button: 0 }));
|
|
86
|
+
await open;
|
|
87
|
+
expect(content.open, "opens for `pointerdown`").to.be.true;
|
|
88
|
+
closed = oneEvent(el, "sp-closed");
|
|
89
|
+
await sendKeys({
|
|
90
|
+
press: "Escape"
|
|
91
|
+
});
|
|
92
|
+
await closed;
|
|
93
|
+
expect(!content.open, "closes for `pointerdown`").to.be.true;
|
|
94
|
+
});
|
|
95
|
+
it("displays `longpress` declaratively", async () => {
|
|
96
|
+
const openedSpy = spy();
|
|
97
|
+
const closedSpy = spy();
|
|
98
|
+
const el = await fixture(
|
|
99
|
+
(() => html`
|
|
25
100
|
<overlay-trigger
|
|
26
101
|
placement="right-start"
|
|
27
102
|
open="longpress"
|
|
28
|
-
@sp-opened=${()=>
|
|
29
|
-
@sp-closed=${()=>
|
|
103
|
+
@sp-opened=${() => openedSpy()}
|
|
104
|
+
@sp-closed=${() => closedSpy()}
|
|
30
105
|
>
|
|
31
106
|
<sp-action-button slot="trigger" hold-affordance>
|
|
32
107
|
<sp-icon-magnify slot="icon"></sp-icon-magnify>
|
|
33
108
|
</sp-action-button>
|
|
34
109
|
<sp-popover slot="longpress-content" tip></sp-popover>
|
|
35
110
|
</overlay-trigger>
|
|
36
|
-
`)()
|
|
111
|
+
`)()
|
|
112
|
+
);
|
|
113
|
+
await elementUpdated(el);
|
|
114
|
+
await waitUntil(
|
|
115
|
+
() => openedSpy.calledOnce,
|
|
116
|
+
"longpress content projected to overlay",
|
|
117
|
+
{ timeout: 2e3 }
|
|
118
|
+
);
|
|
119
|
+
const closed = oneEvent(el, "sp-closed");
|
|
120
|
+
el.removeAttribute("open");
|
|
121
|
+
await closed;
|
|
122
|
+
expect(closedSpy.calledOnce, "longpress content returned").to.be.true;
|
|
123
|
+
});
|
|
124
|
+
it("describes longpress interaction accessibly", async () => {
|
|
125
|
+
const el = await fixture(
|
|
126
|
+
html`
|
|
37
127
|
<overlay-trigger placement="right-start">
|
|
38
128
|
<sp-action-button slot="trigger" hold-affordance>
|
|
39
129
|
Trigger with hold affordance
|
|
@@ -56,7 +146,44 @@ import{elementUpdated as i,expect as o,fixture as g,html as u,nextFrame as y,one
|
|
|
56
146
|
</sp-action-group>
|
|
57
147
|
</sp-popover>
|
|
58
148
|
</overlay-trigger>
|
|
59
|
-
`
|
|
149
|
+
`
|
|
150
|
+
);
|
|
151
|
+
const trigger = el.querySelector('[slot="trigger"]');
|
|
152
|
+
await elementUpdated(el);
|
|
153
|
+
expect(trigger.hasAttribute("aria-describedby")).to.be.true;
|
|
154
|
+
expect(el.open).to.be.undefined;
|
|
155
|
+
expect(el.childNodes.length, "always").to.equal(6);
|
|
156
|
+
await findDescribedNode(
|
|
157
|
+
"Trigger with hold affordance",
|
|
158
|
+
LONGPRESS_INSTRUCTIONS.keyboard
|
|
159
|
+
);
|
|
160
|
+
const opened = oneEvent(el, "sp-opened");
|
|
161
|
+
trigger.dispatchEvent(
|
|
162
|
+
new Event("longpress", { bubbles: true, composed: true })
|
|
163
|
+
);
|
|
164
|
+
await opened;
|
|
165
|
+
expect(el.open).to.equal("longpress");
|
|
166
|
+
expect(el.childNodes.length, "always").to.equal(6);
|
|
167
|
+
await findDescribedNode(
|
|
168
|
+
"Trigger with hold affordance",
|
|
169
|
+
LONGPRESS_INSTRUCTIONS.keyboard
|
|
170
|
+
);
|
|
171
|
+
const closed = oneEvent(el, "sp-closed");
|
|
172
|
+
await sendKeys({
|
|
173
|
+
press: "Escape"
|
|
174
|
+
});
|
|
175
|
+
await closed;
|
|
176
|
+
expect(el.open).to.be.null;
|
|
177
|
+
expect(trigger.hasAttribute("aria-describedby")).to.be.true;
|
|
178
|
+
expect(el.childNodes.length, "always").to.equal(6);
|
|
179
|
+
await findDescribedNode(
|
|
180
|
+
"Trigger with hold affordance",
|
|
181
|
+
LONGPRESS_INSTRUCTIONS.keyboard
|
|
182
|
+
);
|
|
183
|
+
});
|
|
184
|
+
it("removes longpress `aria-describedby` description element when longpress content is removed", async () => {
|
|
185
|
+
const el = await fixture(
|
|
186
|
+
html`
|
|
60
187
|
<overlay-trigger placement="right-start">
|
|
61
188
|
<sp-action-button slot="trigger" hold-affordance>
|
|
62
189
|
Trigger with hold affordance
|
|
@@ -79,7 +206,34 @@ import{elementUpdated as i,expect as o,fixture as g,html as u,nextFrame as y,one
|
|
|
79
206
|
</sp-action-group>
|
|
80
207
|
</sp-popover>
|
|
81
208
|
</overlay-trigger>
|
|
82
|
-
`
|
|
209
|
+
`
|
|
210
|
+
);
|
|
211
|
+
const trigger = el.querySelector('[slot="trigger"]');
|
|
212
|
+
const content = el.querySelector(
|
|
213
|
+
'[slot="longpress-content"]'
|
|
214
|
+
);
|
|
215
|
+
await elementUpdated(el);
|
|
216
|
+
expect(el.hasLongpressContent).to.be.true;
|
|
217
|
+
expect(el.childNodes.length, "always").to.equal(6);
|
|
218
|
+
el.removeAttribute("hold-affordance");
|
|
219
|
+
el.removeChild(content);
|
|
220
|
+
await elementUpdated(el);
|
|
221
|
+
expect(trigger.hasAttribute("aria-describedby")).to.be.false;
|
|
222
|
+
expect(el.hasLongpressContent).to.be.false;
|
|
223
|
+
expect(el.childNodes.length, "always").to.equal(4);
|
|
224
|
+
el.setAttribute("hold-affordance", "true");
|
|
225
|
+
el.append(content);
|
|
226
|
+
await elementUpdated(el);
|
|
227
|
+
await findDescribedNode(
|
|
228
|
+
"Trigger with hold affordance",
|
|
229
|
+
LONGPRESS_INSTRUCTIONS.keyboard
|
|
230
|
+
);
|
|
231
|
+
expect(el.hasLongpressContent).to.be.true;
|
|
232
|
+
expect(el.childNodes.length, "always").to.equal(6);
|
|
233
|
+
});
|
|
234
|
+
it("recognises multiple overlay triggers in a11y tree", async () => {
|
|
235
|
+
const el = await fixture(
|
|
236
|
+
html`
|
|
83
237
|
<div id="container">
|
|
84
238
|
<overlay-trigger id="first-trigger" placement="right-start">
|
|
85
239
|
<sp-action-button slot="trigger" hold-affordance>
|
|
@@ -118,7 +272,31 @@ import{elementUpdated as i,expect as o,fixture as g,html as u,nextFrame as y,one
|
|
|
118
272
|
</sp-popover>
|
|
119
273
|
</overlay-trigger>
|
|
120
274
|
</div>
|
|
121
|
-
`
|
|
275
|
+
`
|
|
276
|
+
);
|
|
277
|
+
await elementUpdated(el);
|
|
278
|
+
const div = document.getElementById("container");
|
|
279
|
+
const firstTrigger = document.getElementById(
|
|
280
|
+
"first-trigger"
|
|
281
|
+
);
|
|
282
|
+
const secondTrigger = document.getElementById(
|
|
283
|
+
"second-trigger"
|
|
284
|
+
);
|
|
285
|
+
expect(firstTrigger.hasLongpressContent).to.be.true;
|
|
286
|
+
expect(secondTrigger.hasLongpressContent).to.be.true;
|
|
287
|
+
expect(div.childNodes.length, "always").to.equal(5);
|
|
288
|
+
await findDescribedNode(
|
|
289
|
+
"First button",
|
|
290
|
+
LONGPRESS_INSTRUCTIONS.keyboard
|
|
291
|
+
);
|
|
292
|
+
await findDescribedNode(
|
|
293
|
+
"Second button",
|
|
294
|
+
LONGPRESS_INSTRUCTIONS.keyboard
|
|
295
|
+
);
|
|
296
|
+
});
|
|
297
|
+
it("describes interactions differently to the user", async () => {
|
|
298
|
+
const test = await fixture(
|
|
299
|
+
html`
|
|
122
300
|
<div>
|
|
123
301
|
<input id="first" />
|
|
124
302
|
<overlay-trigger placement="right-start">
|
|
@@ -151,5 +329,51 @@ import{elementUpdated as i,expect as o,fixture as g,html as u,nextFrame as y,one
|
|
|
151
329
|
</overlay-trigger>
|
|
152
330
|
<input id="last" />
|
|
153
331
|
</div>
|
|
154
|
-
`
|
|
332
|
+
`
|
|
333
|
+
);
|
|
334
|
+
const el = test.querySelector("overlay-trigger");
|
|
335
|
+
const first = test.querySelector("#first");
|
|
336
|
+
const firstRect = first.getBoundingClientRect();
|
|
337
|
+
const trigger = el.querySelector("sp-action-button");
|
|
338
|
+
const content = el.querySelector(
|
|
339
|
+
'[slot="longpress-content"]'
|
|
340
|
+
);
|
|
341
|
+
await elementUpdated(el);
|
|
342
|
+
expect(trigger).to.not.be.null;
|
|
343
|
+
expect(content).to.not.be.null;
|
|
344
|
+
expect(trigger.hasAttribute("aria-describedby")).to.be.true;
|
|
345
|
+
expect(content.open).to.be.false;
|
|
346
|
+
first.focus();
|
|
347
|
+
await sendKeys({
|
|
348
|
+
press: "Tab"
|
|
349
|
+
});
|
|
350
|
+
expect(document.activeElement === trigger, "Trigger focused").to.be.true;
|
|
351
|
+
await findDescribedNode(
|
|
352
|
+
"Trigger with hold affordance",
|
|
353
|
+
LONGPRESS_INSTRUCTIONS.keyboard
|
|
354
|
+
);
|
|
355
|
+
await sendKeys({
|
|
356
|
+
press: "Tab"
|
|
357
|
+
});
|
|
358
|
+
await findDescribedNode(
|
|
359
|
+
"Trigger with hold affordance",
|
|
360
|
+
LONGPRESS_INSTRUCTIONS.keyboard
|
|
361
|
+
);
|
|
362
|
+
await sendMouse({
|
|
363
|
+
steps: [
|
|
364
|
+
{
|
|
365
|
+
type: "click",
|
|
366
|
+
position: [firstRect.x, firstRect.y]
|
|
367
|
+
}
|
|
368
|
+
]
|
|
369
|
+
});
|
|
370
|
+
trigger.focus();
|
|
371
|
+
await nextFrame();
|
|
372
|
+
await nextFrame();
|
|
373
|
+
await findDescribedNode(
|
|
374
|
+
"Trigger with hold affordance",
|
|
375
|
+
LONGPRESS_INSTRUCTIONS.keyboard
|
|
376
|
+
);
|
|
377
|
+
});
|
|
378
|
+
});
|
|
155
379
|
//# sourceMappingURL=overlay-trigger-longpress.test.js.map
|