@spectrum-web-components/overlay 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/custom-elements.json +189 -73
- package/package.json +8 -7
- package/src/Overlay.d.ts +348 -18
- package/src/Overlay.dev.js +271 -12
- package/src/Overlay.dev.js.map +2 -2
- package/src/Overlay.js +4 -4
- package/src/Overlay.js.map +3 -3
- package/src/PlacementController.d.ts +118 -1
- package/src/PlacementController.dev.js +75 -0
- package/src/PlacementController.dev.js.map +2 -2
- package/src/PlacementController.js.map +2 -2
- package/src/overlay.css.dev.js +1 -1
- package/src/overlay.css.dev.js.map +1 -1
- package/src/overlay.css.js +1 -1
- package/src/overlay.css.js.map +1 -1
- package/stories/index.js +48 -0
- package/stories/index.js.map +7 -0
- package/stories/overlay-directive.stories.js +324 -0
- package/stories/overlay-directive.stories.js.map +7 -0
- package/stories/overlay-element.stories.js +675 -0
- package/stories/overlay-element.stories.js.map +7 -0
- package/stories/overlay-story-components.js +338 -0
- package/stories/overlay-story-components.js.map +7 -0
- package/stories/overlay.stories.js +1397 -0
- package/stories/overlay.stories.js.map +7 -0
- package/test/benchmark/basic-test.js +40 -0
- package/test/benchmark/basic-test.js.map +7 -0
- package/test/benchmark/directive-test.js +43 -0
- package/test/benchmark/directive-test.js.map +7 -0
- package/test/benchmark/element-test.js +40 -0
- package/test/benchmark/element-test.js.map +7 -0
- package/test/benchmark/lazy-test.js +47 -0
- package/test/benchmark/lazy-test.js.map +7 -0
- package/test/index.js +605 -0
- package/test/index.js.map +7 -0
- package/test/overlay-directive.test-vrt.js +5 -0
- package/test/overlay-directive.test-vrt.js.map +7 -0
- package/test/overlay-directive.test.js +162 -0
- package/test/overlay-directive.test.js.map +7 -0
- package/test/overlay-element.test-vrt.js +5 -0
- package/test/overlay-element.test-vrt.js.map +7 -0
- package/test/overlay-element.test.js +934 -0
- package/test/overlay-element.test.js.map +7 -0
- package/test/overlay-lifecycle.test.js +139 -0
- package/test/overlay-lifecycle.test.js.map +7 -0
- package/test/overlay-memory.test.js +10 -0
- package/test/overlay-memory.test.js.map +7 -0
- package/test/overlay-timer.test.js +118 -0
- package/test/overlay-timer.test.js.map +7 -0
- package/test/overlay-trigger-click.test.js +164 -0
- package/test/overlay-trigger-click.test.js.map +7 -0
- package/test/overlay-trigger-directive.test.js +75 -0
- package/test/overlay-trigger-directive.test.js.map +7 -0
- package/test/overlay-trigger-extended.test.js +235 -0
- package/test/overlay-trigger-extended.test.js.map +7 -0
- package/test/overlay-trigger-hover-click.test.js +225 -0
- package/test/overlay-trigger-hover-click.test.js.map +7 -0
- package/test/overlay-trigger-hover.test.js +308 -0
- package/test/overlay-trigger-hover.test.js.map +7 -0
- package/test/overlay-trigger-longpress.test.js +549 -0
- package/test/overlay-trigger-longpress.test.js.map +7 -0
- package/test/overlay-trigger-sync.test.js +5 -0
- package/test/overlay-trigger-sync.test.js.map +7 -0
- package/test/overlay-trigger.test.js +5 -0
- package/test/overlay-trigger.test.js.map +7 -0
- package/test/overlay-update.test.js +28 -0
- package/test/overlay-update.test.js.map +7 -0
- package/test/overlay-v1.test.js +569 -0
- package/test/overlay-v1.test.js.map +7 -0
- package/test/overlay.test-vrt.js +5 -0
- package/test/overlay.test-vrt.js.map +7 -0
- package/test/overlay.test.js +776 -0
- package/test/overlay.test.js.map +7 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import {
|
|
3
|
+
aTimeout,
|
|
4
|
+
elementUpdated,
|
|
5
|
+
expect,
|
|
6
|
+
fixture,
|
|
7
|
+
html,
|
|
8
|
+
oneEvent
|
|
9
|
+
} from "@open-wc/testing";
|
|
10
|
+
import "@spectrum-web-components/popover/sp-popover.js";
|
|
11
|
+
import "@spectrum-web-components/action-button/sp-action-button.js";
|
|
12
|
+
import "@spectrum-web-components/button/sp-button.js";
|
|
13
|
+
import "@spectrum-web-components/icons-workflow/icons/sp-icon-magnify.js";
|
|
14
|
+
import "@spectrum-web-components/popover/sp-popover.js";
|
|
15
|
+
import "@spectrum-web-components/tooltip/sp-tooltip.js";
|
|
16
|
+
import "@spectrum-web-components/overlay/overlay-trigger.js";
|
|
17
|
+
import { sendMouse } from "../../../test/plugins/browser.js";
|
|
18
|
+
import { clickAndHoverTargets, deep } from "../stories/overlay.stories.js";
|
|
19
|
+
import { ignoreResizeObserverLoopError } from "../../../test/testing-helpers.js";
|
|
20
|
+
import { sendKeys } from "@web/test-runner-commands";
|
|
21
|
+
ignoreResizeObserverLoopError(before, after);
|
|
22
|
+
describe("Overlay Trigger - Hover and Click", () => {
|
|
23
|
+
it("toggles open and closed on click", async () => {
|
|
24
|
+
const el = await fixture(html`
|
|
25
|
+
<overlay-trigger>
|
|
26
|
+
<sp-button slot="trigger">Click and hover</sp-button>
|
|
27
|
+
<sp-popover slot="click-content" dialog tip>
|
|
28
|
+
Popover content
|
|
29
|
+
</sp-popover>
|
|
30
|
+
<sp-tooltip slot="hover-content" delayed>
|
|
31
|
+
Tooltip content
|
|
32
|
+
</sp-tooltip>
|
|
33
|
+
</overlay-trigger>
|
|
34
|
+
`);
|
|
35
|
+
const trigger = el.querySelector(
|
|
36
|
+
"[slot=trigger]"
|
|
37
|
+
);
|
|
38
|
+
let interaction;
|
|
39
|
+
for (let i = 0; i < 3; i++) {
|
|
40
|
+
const openedEvent = oneEvent(el, "sp-opened");
|
|
41
|
+
trigger.click();
|
|
42
|
+
interaction = (await openedEvent).detail.interaction;
|
|
43
|
+
expect(interaction).equals("auto");
|
|
44
|
+
const closedEvent = oneEvent(el, "sp-closed");
|
|
45
|
+
trigger.click();
|
|
46
|
+
interaction = (await closedEvent).detail.interaction;
|
|
47
|
+
expect(interaction).equals("auto");
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
it("toggles on click after hover", async () => {
|
|
51
|
+
const el = await fixture(html`
|
|
52
|
+
<overlay-trigger>
|
|
53
|
+
<sp-button slot="trigger">Click and hover</sp-button>
|
|
54
|
+
<sp-popover slot="click-content" dialog tip>
|
|
55
|
+
Popover content
|
|
56
|
+
</sp-popover>
|
|
57
|
+
<sp-tooltip slot="hover-content" delayed>
|
|
58
|
+
Tooltip content
|
|
59
|
+
</sp-tooltip>
|
|
60
|
+
</overlay-trigger>
|
|
61
|
+
`);
|
|
62
|
+
const trigger = el.querySelector(
|
|
63
|
+
"[slot=trigger]"
|
|
64
|
+
);
|
|
65
|
+
const clickContent = el.querySelector(
|
|
66
|
+
'[slot="click-content"]'
|
|
67
|
+
);
|
|
68
|
+
const bounds = el.getBoundingClientRect();
|
|
69
|
+
let interaction;
|
|
70
|
+
const hoveredEvent = oneEvent(el, "sp-opened");
|
|
71
|
+
sendMouse({
|
|
72
|
+
steps: [
|
|
73
|
+
{
|
|
74
|
+
type: "move",
|
|
75
|
+
position: [bounds.left - 1, bounds.top - 1]
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
type: "move",
|
|
79
|
+
position: [bounds.left, bounds.top]
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
type: "move",
|
|
83
|
+
position: [bounds.left + 1, bounds.top + 1]
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
});
|
|
87
|
+
interaction = (await hoveredEvent).detail.interaction;
|
|
88
|
+
expect(interaction).equals("hint");
|
|
89
|
+
for (let i = 0; i < 3; i++) {
|
|
90
|
+
const openedEvent = oneEvent(clickContent, "sp-opened");
|
|
91
|
+
trigger.click();
|
|
92
|
+
interaction = (await openedEvent).detail.interaction;
|
|
93
|
+
expect(interaction).equals("auto");
|
|
94
|
+
const closedEvent = oneEvent(clickContent, "sp-closed");
|
|
95
|
+
trigger.click();
|
|
96
|
+
interaction = (await closedEvent).detail.interaction;
|
|
97
|
+
expect(interaction).equals("auto");
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
it("persists a hover overlay when clicking its trigger and closes the next highest overlay on the stack", async () => {
|
|
101
|
+
const root = document.createElement("div");
|
|
102
|
+
root.style.width = "100vw";
|
|
103
|
+
root.style.height = "100vh";
|
|
104
|
+
root.style.display = "grid";
|
|
105
|
+
root.style.placeContent = "center";
|
|
106
|
+
const test = await fixture(clickAndHoverTargets(), {
|
|
107
|
+
parentNode: root
|
|
108
|
+
});
|
|
109
|
+
const overlayTrigger1 = test.querySelector(
|
|
110
|
+
'overlay-trigger[placement="right"]'
|
|
111
|
+
);
|
|
112
|
+
const overlayTrigger2 = test.querySelector(
|
|
113
|
+
'overlay-trigger[placement="left"]'
|
|
114
|
+
);
|
|
115
|
+
await elementUpdated(overlayTrigger1);
|
|
116
|
+
await elementUpdated(overlayTrigger2);
|
|
117
|
+
const trigger1 = overlayTrigger1.querySelector(
|
|
118
|
+
".friendly-target"
|
|
119
|
+
);
|
|
120
|
+
const trigger2 = overlayTrigger2.querySelector(
|
|
121
|
+
".friendly-target"
|
|
122
|
+
);
|
|
123
|
+
const rect1 = trigger1.getBoundingClientRect();
|
|
124
|
+
const rect2 = trigger2.getBoundingClientRect();
|
|
125
|
+
let opened = oneEvent(trigger1, "sp-opened");
|
|
126
|
+
sendMouse({
|
|
127
|
+
steps: [
|
|
128
|
+
{
|
|
129
|
+
type: "click",
|
|
130
|
+
position: [
|
|
131
|
+
rect1.left + rect1.width / 2,
|
|
132
|
+
rect1.top + rect1.height / 2
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
});
|
|
137
|
+
await opened;
|
|
138
|
+
expect(overlayTrigger1.open).to.equal("click");
|
|
139
|
+
expect(overlayTrigger2.open).to.undefined;
|
|
140
|
+
opened = oneEvent(trigger2, "sp-opened");
|
|
141
|
+
sendMouse({
|
|
142
|
+
steps: [
|
|
143
|
+
{
|
|
144
|
+
type: "move",
|
|
145
|
+
position: [
|
|
146
|
+
rect2.left + rect2.width / 2,
|
|
147
|
+
rect2.top + rect2.height / 2
|
|
148
|
+
]
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
});
|
|
152
|
+
await opened;
|
|
153
|
+
expect(overlayTrigger1.open).to.equal("click");
|
|
154
|
+
expect(overlayTrigger2.open).to.equal("hover");
|
|
155
|
+
const closed = oneEvent(trigger1, "sp-closed");
|
|
156
|
+
sendMouse({
|
|
157
|
+
steps: [
|
|
158
|
+
{
|
|
159
|
+
type: "click",
|
|
160
|
+
position: [
|
|
161
|
+
rect2.left + rect2.width / 2,
|
|
162
|
+
rect2.top + rect2.height / 2
|
|
163
|
+
]
|
|
164
|
+
}
|
|
165
|
+
]
|
|
166
|
+
});
|
|
167
|
+
await closed;
|
|
168
|
+
expect(overlayTrigger1.open).to.be.undefined;
|
|
169
|
+
expect(overlayTrigger2.open).to.equal("hover");
|
|
170
|
+
});
|
|
171
|
+
it('does not close ancestor "click" overlays on `click`', async () => {
|
|
172
|
+
const test = await fixture(html`
|
|
173
|
+
<div>${deep()}</div>
|
|
174
|
+
`);
|
|
175
|
+
const el = test.querySelector("overlay-trigger");
|
|
176
|
+
const trigger = test.querySelector("sp-button");
|
|
177
|
+
const button = el.querySelector("sp-action-button");
|
|
178
|
+
const button2 = el.querySelector(
|
|
179
|
+
"sp-action-button:nth-of-type(2)"
|
|
180
|
+
);
|
|
181
|
+
const tooltip = button.querySelector("sp-tooltip");
|
|
182
|
+
expect(el.open).to.be.undefined;
|
|
183
|
+
expect(tooltip.open).to.be.false;
|
|
184
|
+
const opened = oneEvent(el, "sp-opened");
|
|
185
|
+
trigger.focus();
|
|
186
|
+
await sendKeys({
|
|
187
|
+
press: "Tab"
|
|
188
|
+
});
|
|
189
|
+
await sendKeys({
|
|
190
|
+
press: "Shift+Tab"
|
|
191
|
+
});
|
|
192
|
+
await sendKeys({
|
|
193
|
+
press: "Space"
|
|
194
|
+
});
|
|
195
|
+
await opened;
|
|
196
|
+
expect(el.open).to.equal("click");
|
|
197
|
+
expect(tooltip.open).to.be.true;
|
|
198
|
+
button.click();
|
|
199
|
+
await aTimeout(200);
|
|
200
|
+
expect(el.open).to.equal("click");
|
|
201
|
+
expect(tooltip.open).to.be.true;
|
|
202
|
+
let closed = oneEvent(button, "sp-closed");
|
|
203
|
+
expect(document.activeElement === button, `button focused`).to.be.true;
|
|
204
|
+
await sendKeys({
|
|
205
|
+
press: "Tab"
|
|
206
|
+
});
|
|
207
|
+
expect(document.activeElement === button2, `button focused`).to.be.true;
|
|
208
|
+
await closed;
|
|
209
|
+
expect(el.open).to.equal("click");
|
|
210
|
+
expect(tooltip.open).to.be.false;
|
|
211
|
+
closed = oneEvent(el, "sp-closed");
|
|
212
|
+
sendMouse({
|
|
213
|
+
steps: [
|
|
214
|
+
{
|
|
215
|
+
type: "click",
|
|
216
|
+
position: [1, 1]
|
|
217
|
+
}
|
|
218
|
+
]
|
|
219
|
+
});
|
|
220
|
+
await closed;
|
|
221
|
+
expect(el.open, '"click" overlay no longer open').to.be.undefined;
|
|
222
|
+
expect(tooltip.open).to.be.false;
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
//# sourceMappingURL=overlay-trigger-hover-click.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["overlay-trigger-hover-click.test.ts"],
|
|
4
|
+
"sourcesContent": ["/*\nCopyright 2021 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} 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/button/sp-button.js';\nimport '@spectrum-web-components/icons-workflow/icons/sp-icon-magnify.js';\nimport '@spectrum-web-components/popover/sp-popover.js';\nimport '@spectrum-web-components/tooltip/sp-tooltip.js';\nimport { OverlayTrigger } from '@spectrum-web-components/overlay/src/OverlayTrigger';\nimport { TriggerInteractions } from '@spectrum-web-components/overlay/src/overlay-types';\nimport '@spectrum-web-components/overlay/overlay-trigger.js';\nimport { ActionButton } from '@spectrum-web-components/action-button';\nimport { sendMouse } from '../../../test/plugins/browser.js';\nimport { clickAndHoverTargets, deep } from '../stories/overlay.stories.js';\nimport { ignoreResizeObserverLoopError } from '../../../test/testing-helpers.js';\nimport { Tooltip } from '@spectrum-web-components/tooltip/src/Tooltip.js';\nimport { sendKeys } from '@web/test-runner-commands';\nimport { Button } from '@spectrum-web-components/button';\n\nignoreResizeObserverLoopError(before, after);\n\ndescribe('Overlay Trigger - Hover and Click', () => {\n it('toggles open and closed on click', async () => {\n const el = await fixture<OverlayTrigger>(html`\n <overlay-trigger>\n <sp-button slot=\"trigger\">Click and hover</sp-button>\n <sp-popover slot=\"click-content\" dialog tip>\n Popover content\n </sp-popover>\n <sp-tooltip slot=\"hover-content\" delayed>\n Tooltip content\n </sp-tooltip>\n </overlay-trigger>\n `);\n const trigger = el.querySelector(\n '[slot=trigger]'\n ) as unknown as ActionButton;\n let interaction: TriggerInteractions;\n\n // repeatedly click to toggle the popover\n for (let i = 0; i < 3; i++) {\n const openedEvent = oneEvent(el, 'sp-opened');\n trigger.click();\n interaction = (await openedEvent).detail.interaction;\n\n expect(interaction).equals('auto');\n\n const closedEvent = oneEvent(el, 'sp-closed');\n trigger.click();\n interaction = (await closedEvent).detail.interaction;\n\n expect(interaction).equals('auto');\n }\n });\n it('toggles on click after hover', async () => {\n const el = await fixture<OverlayTrigger>(html`\n <overlay-trigger>\n <sp-button slot=\"trigger\">Click and hover</sp-button>\n <sp-popover slot=\"click-content\" dialog tip>\n Popover content\n </sp-popover>\n <sp-tooltip slot=\"hover-content\" delayed>\n Tooltip content\n </sp-tooltip>\n </overlay-trigger>\n `);\n const trigger = el.querySelector(\n '[slot=trigger]'\n ) as unknown as ActionButton;\n const clickContent = el.querySelector(\n '[slot=\"click-content\"]'\n ) as HTMLElement;\n const bounds = el.getBoundingClientRect();\n let interaction: TriggerInteractions;\n\n // hover over the button to trigger the tooltip\n const hoveredEvent = oneEvent(el, 'sp-opened');\n sendMouse({\n steps: [\n {\n type: 'move',\n position: [bounds.left - 1, bounds.top - 1],\n },\n {\n type: 'move',\n position: [bounds.left, bounds.top],\n },\n {\n type: 'move',\n position: [bounds.left + 1, bounds.top + 1],\n },\n ],\n });\n interaction = (await hoveredEvent).detail.interaction;\n\n expect(interaction).equals('hint');\n\n // repeatedly click to toggle the popover\n for (let i = 0; i < 3; i++) {\n const openedEvent = oneEvent(clickContent, 'sp-opened');\n trigger.click();\n interaction = (await openedEvent).detail.interaction;\n\n expect(interaction).equals('auto');\n\n const closedEvent = oneEvent(clickContent, 'sp-closed');\n trigger.click();\n interaction = (await closedEvent).detail.interaction;\n\n expect(interaction).equals('auto');\n }\n });\n it('persists a hover overlay when clicking its trigger and closes the next highest overlay on the stack', async () => {\n const root = document.createElement('div');\n root.style.width = '100vw';\n root.style.height = '100vh';\n root.style.display = 'grid';\n root.style.placeContent = 'center';\n const test = await fixture(clickAndHoverTargets(), {\n parentNode: root,\n });\n\n const overlayTrigger1 = test.querySelector(\n 'overlay-trigger[placement=\"right\"]'\n ) as OverlayTrigger;\n const overlayTrigger2 = test.querySelector(\n 'overlay-trigger[placement=\"left\"]'\n ) as OverlayTrigger;\n\n await elementUpdated(overlayTrigger1);\n await elementUpdated(overlayTrigger2);\n\n const trigger1 = overlayTrigger1.querySelector(\n '.friendly-target'\n ) as HTMLButtonElement;\n const trigger2 = overlayTrigger2.querySelector(\n '.friendly-target'\n ) as HTMLButtonElement;\n const rect1 = trigger1.getBoundingClientRect();\n const rect2 = trigger2.getBoundingClientRect();\n let opened = oneEvent(trigger1, 'sp-opened');\n sendMouse({\n steps: [\n {\n type: 'click',\n position: [\n rect1.left + rect1.width / 2,\n rect1.top + rect1.height / 2,\n ],\n },\n ],\n });\n await opened;\n\n expect(overlayTrigger1.open).to.equal('click');\n expect(overlayTrigger2.open).to.undefined;\n\n opened = oneEvent(trigger2, 'sp-opened');\n sendMouse({\n steps: [\n {\n type: 'move',\n position: [\n rect2.left + rect2.width / 2,\n rect2.top + rect2.height / 2,\n ],\n },\n ],\n });\n await opened;\n\n expect(overlayTrigger1.open).to.equal('click');\n expect(overlayTrigger2.open).to.equal('hover');\n\n const closed = oneEvent(trigger1, 'sp-closed');\n sendMouse({\n steps: [\n {\n type: 'click',\n position: [\n rect2.left + rect2.width / 2,\n rect2.top + rect2.height / 2,\n ],\n },\n ],\n });\n await closed;\n\n expect(overlayTrigger1.open).to.be.undefined;\n expect(overlayTrigger2.open).to.equal('hover');\n });\n it('does not close ancestor \"click\" overlays on `click`', async () => {\n const test = await fixture<HTMLDivElement>(html`\n <div>${deep()}</div>\n `);\n const el = test.querySelector('overlay-trigger') as OverlayTrigger;\n const trigger = test.querySelector('sp-button') as Button;\n const button = el.querySelector('sp-action-button') as ActionButton;\n const button2 = el.querySelector(\n 'sp-action-button:nth-of-type(2)'\n ) as ActionButton;\n const tooltip = button.querySelector('sp-tooltip') as Tooltip;\n\n expect(el.open).to.be.undefined;\n expect(tooltip.open).to.be.false;\n\n const opened = oneEvent(el, 'sp-opened');\n trigger.focus();\n // For `:focus-visible` heuristic.\n await sendKeys({\n press: 'Tab',\n });\n await sendKeys({\n press: 'Shift+Tab',\n });\n await sendKeys({\n press: 'Space',\n });\n await opened;\n\n expect(el.open).to.equal('click');\n expect(tooltip.open).to.be.true;\n\n button.click();\n\n await aTimeout(200);\n\n expect(el.open).to.equal('click');\n expect(tooltip.open).to.be.true;\n\n let closed = oneEvent(button, 'sp-closed');\n expect(document.activeElement === button, `button focused`).to.be.true;\n await sendKeys({\n press: 'Tab',\n });\n expect(document.activeElement === button2, `button focused`).to.be.true;\n await closed;\n\n expect(el.open).to.equal('click');\n expect(tooltip.open).to.be.false;\n\n closed = oneEvent(el, 'sp-closed');\n sendMouse({\n steps: [\n {\n type: 'click',\n position: [1, 1],\n },\n ],\n });\n await closed;\n\n expect(el.open, '\"click\" overlay no longer open').to.be.undefined;\n expect(tooltip.open).to.be.false;\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
import {
|
|
3
|
+
elementUpdated,
|
|
4
|
+
expect,
|
|
5
|
+
html,
|
|
6
|
+
nextFrame,
|
|
7
|
+
oneEvent,
|
|
8
|
+
waitUntil
|
|
9
|
+
} from "@open-wc/testing";
|
|
10
|
+
import "@spectrum-web-components/overlay/overlay-trigger.js";
|
|
11
|
+
import "@spectrum-web-components/popover/sp-popover.js";
|
|
12
|
+
import "@spectrum-web-components/button/sp-button.js";
|
|
13
|
+
import "@spectrum-web-components/tooltip/sp-tooltip.js";
|
|
14
|
+
import "@spectrum-web-components/dialog/sp-dialog-wrapper.js";
|
|
15
|
+
import "@spectrum-web-components/action-button/sp-action-button.js";
|
|
16
|
+
import "@spectrum-web-components/icons-workflow/icons/sp-icon-magnify.js";
|
|
17
|
+
import { spy } from "sinon";
|
|
18
|
+
import { sendKeys } from "@web/test-runner-commands";
|
|
19
|
+
import "@spectrum-web-components/theme/sp-theme.js";
|
|
20
|
+
import "@spectrum-web-components/theme/src/themes.js";
|
|
21
|
+
import {
|
|
22
|
+
fixture,
|
|
23
|
+
ignoreResizeObserverLoopError
|
|
24
|
+
} from "../../../test/testing-helpers.js";
|
|
25
|
+
ignoreResizeObserverLoopError(before, after);
|
|
26
|
+
async function styledFixture(story) {
|
|
27
|
+
const test = await fixture(html`
|
|
28
|
+
<sp-theme system="spectrum" scale="medium" color="light">
|
|
29
|
+
${story}
|
|
30
|
+
</sp-theme>
|
|
31
|
+
`);
|
|
32
|
+
return test.children[0];
|
|
33
|
+
}
|
|
34
|
+
describe("Overlay Trigger - Hover", () => {
|
|
35
|
+
it("displays `hover` declaratively", async () => {
|
|
36
|
+
const openedSpy = spy();
|
|
37
|
+
const closedSpy = spy();
|
|
38
|
+
const el = await fixture(
|
|
39
|
+
(() => html`
|
|
40
|
+
<overlay-trigger
|
|
41
|
+
placement="right-start"
|
|
42
|
+
open="hover"
|
|
43
|
+
@sp-opened=${() => openedSpy()}
|
|
44
|
+
@sp-closed=${() => closedSpy()}
|
|
45
|
+
>
|
|
46
|
+
<sp-action-button slot="trigger">
|
|
47
|
+
<sp-icon-magnify slot="icon"></sp-icon-magnify>
|
|
48
|
+
</sp-action-button>
|
|
49
|
+
<sp-popover slot="hover-content" tip></sp-popover>
|
|
50
|
+
</overlay-trigger>
|
|
51
|
+
`)()
|
|
52
|
+
);
|
|
53
|
+
await elementUpdated(el);
|
|
54
|
+
await waitUntil(
|
|
55
|
+
() => openedSpy.calledOnce,
|
|
56
|
+
"hover content projected to overlay",
|
|
57
|
+
{ timeout: 2e3 }
|
|
58
|
+
);
|
|
59
|
+
el.removeAttribute("open");
|
|
60
|
+
await elementUpdated(el);
|
|
61
|
+
await waitUntil(() => closedSpy.calledOnce, "hover content returned", {
|
|
62
|
+
timeout: 2e3
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
describe('"tooltip" mouse interactions', () => {
|
|
66
|
+
let el;
|
|
67
|
+
let button;
|
|
68
|
+
let tooltip;
|
|
69
|
+
beforeEach(async () => {
|
|
70
|
+
el = await fixture(
|
|
71
|
+
(() => html`
|
|
72
|
+
<overlay-trigger placement="right-start">
|
|
73
|
+
<sp-action-button slot="trigger">
|
|
74
|
+
<sp-icon-magnify slot="icon"></sp-icon-magnify>
|
|
75
|
+
</sp-action-button>
|
|
76
|
+
<sp-tooltip slot="hover-content" tip>
|
|
77
|
+
Magnify
|
|
78
|
+
</sp-tooltip>
|
|
79
|
+
</overlay-trigger>
|
|
80
|
+
`)()
|
|
81
|
+
);
|
|
82
|
+
await elementUpdated(el);
|
|
83
|
+
button = el.querySelector("sp-action-button");
|
|
84
|
+
tooltip = el.querySelector("sp-tooltip");
|
|
85
|
+
});
|
|
86
|
+
it('allows pointer to enter the "tooltip" without closing the "tooltip"', async () => {
|
|
87
|
+
const opened = oneEvent(button, "sp-opened");
|
|
88
|
+
button.dispatchEvent(
|
|
89
|
+
new MouseEvent("pointerenter", {
|
|
90
|
+
bubbles: true,
|
|
91
|
+
composed: true
|
|
92
|
+
})
|
|
93
|
+
);
|
|
94
|
+
await nextFrame();
|
|
95
|
+
await nextFrame();
|
|
96
|
+
await nextFrame();
|
|
97
|
+
await nextFrame();
|
|
98
|
+
expect(tooltip.open).to.be.true;
|
|
99
|
+
button.dispatchEvent(
|
|
100
|
+
new MouseEvent("pointerleave", {
|
|
101
|
+
bubbles: true,
|
|
102
|
+
composed: true
|
|
103
|
+
})
|
|
104
|
+
);
|
|
105
|
+
await nextFrame();
|
|
106
|
+
button.dispatchEvent(
|
|
107
|
+
new MouseEvent("pointerenter", {
|
|
108
|
+
bubbles: true,
|
|
109
|
+
composed: true
|
|
110
|
+
})
|
|
111
|
+
);
|
|
112
|
+
await nextFrame();
|
|
113
|
+
tooltip.dispatchEvent(
|
|
114
|
+
new MouseEvent("pointerleave", {
|
|
115
|
+
bubbles: true,
|
|
116
|
+
composed: true
|
|
117
|
+
})
|
|
118
|
+
);
|
|
119
|
+
await nextFrame();
|
|
120
|
+
button.dispatchEvent(
|
|
121
|
+
new MouseEvent("pointerenter", {
|
|
122
|
+
bubbles: true,
|
|
123
|
+
composed: true
|
|
124
|
+
})
|
|
125
|
+
);
|
|
126
|
+
await opened;
|
|
127
|
+
expect(el.open).to.equal("hover");
|
|
128
|
+
const closed = oneEvent(button, "sp-closed");
|
|
129
|
+
button.dispatchEvent(
|
|
130
|
+
new MouseEvent("pointerleave", {
|
|
131
|
+
relatedTarget: null,
|
|
132
|
+
bubbles: true,
|
|
133
|
+
composed: true
|
|
134
|
+
})
|
|
135
|
+
);
|
|
136
|
+
await closed;
|
|
137
|
+
expect(el.open).to.be.undefined;
|
|
138
|
+
});
|
|
139
|
+
it('closes the "tooltip" when leaving the "tooltip"', async () => {
|
|
140
|
+
const opened = oneEvent(button, "sp-opened");
|
|
141
|
+
button.dispatchEvent(
|
|
142
|
+
new MouseEvent("pointerenter", {
|
|
143
|
+
bubbles: true,
|
|
144
|
+
composed: true
|
|
145
|
+
})
|
|
146
|
+
);
|
|
147
|
+
await nextFrame();
|
|
148
|
+
button.dispatchEvent(
|
|
149
|
+
new MouseEvent("pointerleave", {
|
|
150
|
+
relatedTarget: tooltip,
|
|
151
|
+
bubbles: true,
|
|
152
|
+
composed: true
|
|
153
|
+
})
|
|
154
|
+
);
|
|
155
|
+
await opened;
|
|
156
|
+
expect(el.open).to.equal("hover");
|
|
157
|
+
const closed = oneEvent(button, "sp-closed");
|
|
158
|
+
tooltip.dispatchEvent(
|
|
159
|
+
new MouseEvent("pointerleave", {
|
|
160
|
+
relatedTarget: null,
|
|
161
|
+
bubbles: true,
|
|
162
|
+
composed: true
|
|
163
|
+
})
|
|
164
|
+
);
|
|
165
|
+
await closed;
|
|
166
|
+
expect(el.open).to.be.undefined;
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
it("persists hover content", async () => {
|
|
170
|
+
const el = await fixture(
|
|
171
|
+
(() => html`
|
|
172
|
+
<overlay-trigger placement="right-start">
|
|
173
|
+
<sp-action-button slot="trigger">
|
|
174
|
+
<sp-icon-magnify slot="icon"></sp-icon-magnify>
|
|
175
|
+
</sp-action-button>
|
|
176
|
+
<sp-popover slot="hover-content" tip></sp-popover>
|
|
177
|
+
</overlay-trigger>
|
|
178
|
+
`)()
|
|
179
|
+
);
|
|
180
|
+
await elementUpdated(el);
|
|
181
|
+
expect(el.open).to.be.undefined;
|
|
182
|
+
const trigger = el.querySelector('[slot="trigger"]');
|
|
183
|
+
const opened = oneEvent(trigger, "sp-opened");
|
|
184
|
+
trigger.dispatchEvent(
|
|
185
|
+
new Event("pointerenter", {
|
|
186
|
+
bubbles: true,
|
|
187
|
+
composed: true
|
|
188
|
+
})
|
|
189
|
+
);
|
|
190
|
+
await opened;
|
|
191
|
+
expect(el.open).to.equal("hover");
|
|
192
|
+
trigger.click();
|
|
193
|
+
await elementUpdated(el);
|
|
194
|
+
expect(el.open).to.equal("hover");
|
|
195
|
+
});
|
|
196
|
+
it("closes persistent hover content on `longpress`", async () => {
|
|
197
|
+
const el = await fixture(
|
|
198
|
+
(() => html`
|
|
199
|
+
<overlay-trigger placement="right-start">
|
|
200
|
+
<sp-action-button slot="trigger">
|
|
201
|
+
<sp-icon-magnify slot="icon"></sp-icon-magnify>
|
|
202
|
+
</sp-action-button>
|
|
203
|
+
<sp-popover slot="hover-content" tip></sp-popover>
|
|
204
|
+
<sp-popover slot="longpress-content" tip></sp-popover>
|
|
205
|
+
</overlay-trigger>
|
|
206
|
+
`)()
|
|
207
|
+
);
|
|
208
|
+
await elementUpdated(el);
|
|
209
|
+
expect(el.open).to.be.undefined;
|
|
210
|
+
const trigger = el.querySelector('[slot="trigger"]');
|
|
211
|
+
let opened = oneEvent(trigger, "sp-opened");
|
|
212
|
+
trigger.dispatchEvent(
|
|
213
|
+
new Event("pointerenter", {
|
|
214
|
+
bubbles: true
|
|
215
|
+
})
|
|
216
|
+
);
|
|
217
|
+
await opened;
|
|
218
|
+
expect(el.open).to.equal("hover");
|
|
219
|
+
opened = oneEvent(trigger, "sp-opened");
|
|
220
|
+
trigger.dispatchEvent(
|
|
221
|
+
new Event("longpress", {
|
|
222
|
+
bubbles: true
|
|
223
|
+
})
|
|
224
|
+
);
|
|
225
|
+
await opened;
|
|
226
|
+
expect(el.open).to.equal("longpress");
|
|
227
|
+
});
|
|
228
|
+
it('closes `hover` overlay when [type="modal"]', async () => {
|
|
229
|
+
const el = await fixture(
|
|
230
|
+
(() => html`
|
|
231
|
+
<overlay-trigger placement="right-start" type="modal">
|
|
232
|
+
<sp-action-button slot="trigger">
|
|
233
|
+
<sp-icon-magnify slot="icon"></sp-icon-magnify>
|
|
234
|
+
</sp-action-button>
|
|
235
|
+
<sp-popover slot="hover-content" tip></sp-popover>
|
|
236
|
+
</overlay-trigger>
|
|
237
|
+
`)()
|
|
238
|
+
);
|
|
239
|
+
await elementUpdated(el);
|
|
240
|
+
const input = document.createElement("input");
|
|
241
|
+
el.insertAdjacentElement("beforebegin", input);
|
|
242
|
+
expect(el.open).to.be.undefined;
|
|
243
|
+
const trigger = el.querySelector('[slot="trigger"]');
|
|
244
|
+
const opened = oneEvent(el, "sp-opened");
|
|
245
|
+
input.focus();
|
|
246
|
+
await sendKeys({
|
|
247
|
+
press: "Tab"
|
|
248
|
+
});
|
|
249
|
+
await opened;
|
|
250
|
+
expect(el.open).to.equal("hover");
|
|
251
|
+
const closed = oneEvent(el, "sp-closed");
|
|
252
|
+
trigger.blur();
|
|
253
|
+
await closed;
|
|
254
|
+
expect(el.open).to.be.undefined;
|
|
255
|
+
});
|
|
256
|
+
it('will not return focus to a "modal" parent', async () => {
|
|
257
|
+
const el = await styledFixture(html`
|
|
258
|
+
<overlay-trigger type="modal">
|
|
259
|
+
<sp-button slot="trigger">Toggle Dialog</sp-button>
|
|
260
|
+
<sp-dialog-wrapper
|
|
261
|
+
slot="click-content"
|
|
262
|
+
headline="Dialog title"
|
|
263
|
+
size="s"
|
|
264
|
+
>
|
|
265
|
+
${[1, 2, 3, 4].map(
|
|
266
|
+
(index) => html`
|
|
267
|
+
<overlay-trigger>
|
|
268
|
+
<sp-button slot="trigger" id="button-${index}">
|
|
269
|
+
Button with Tooltip ${index}
|
|
270
|
+
</sp-button>
|
|
271
|
+
<sp-tooltip slot="hover-content">
|
|
272
|
+
Tooltip ${index}
|
|
273
|
+
</sp-tooltip>
|
|
274
|
+
</overlay-trigger>
|
|
275
|
+
`
|
|
276
|
+
)}
|
|
277
|
+
</sp-dialog-wrapper>
|
|
278
|
+
</overlay-trigger>
|
|
279
|
+
`);
|
|
280
|
+
await elementUpdated(el);
|
|
281
|
+
const button = el.querySelector("sp-button");
|
|
282
|
+
const dialog = el.querySelector("sp-dialog-wrapper");
|
|
283
|
+
const button1 = dialog.querySelector("#button-1");
|
|
284
|
+
const button2 = dialog.querySelector("#button-2");
|
|
285
|
+
const button3 = dialog.querySelector("#button-3");
|
|
286
|
+
await elementUpdated(button);
|
|
287
|
+
await elementUpdated(dialog);
|
|
288
|
+
let opened = oneEvent(button, "sp-opened");
|
|
289
|
+
const openedHint = oneEvent(button1, "sp-opened");
|
|
290
|
+
button.dispatchEvent(new Event("click", { bubbles: true }));
|
|
291
|
+
await opened;
|
|
292
|
+
await openedHint;
|
|
293
|
+
expect(button1 === document.activeElement).to.be.true;
|
|
294
|
+
opened = oneEvent(button2, "sp-opened");
|
|
295
|
+
sendKeys({
|
|
296
|
+
press: "Tab"
|
|
297
|
+
});
|
|
298
|
+
await opened;
|
|
299
|
+
expect(button2 === document.activeElement).to.be.true;
|
|
300
|
+
opened = oneEvent(button3, "sp-opened");
|
|
301
|
+
sendKeys({
|
|
302
|
+
press: "Tab"
|
|
303
|
+
});
|
|
304
|
+
await opened;
|
|
305
|
+
expect(button3 === document.activeElement).to.be.true;
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
//# sourceMappingURL=overlay-trigger-hover.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 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 elementUpdated,\n expect,\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';\nimport { Tooltip } from '@spectrum-web-components/tooltip';\nimport {\n fixture,\n ignoreResizeObserverLoopError,\n} from '../../../test/testing-helpers.js';\n\nignoreResizeObserverLoopError(before, after);\n\nasync function styledFixture<T extends Element>(\n story: TemplateResult\n): Promise<T> {\n const test = await fixture<Theme>(html`\n <sp-theme system=\"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 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 describe('\"tooltip\" mouse interactions', () => {\n let el: OverlayTrigger;\n let button: ActionButton;\n let tooltip: Tooltip;\n beforeEach(async () => {\n 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-tooltip slot=\"hover-content\" tip>\n Magnify\n </sp-tooltip>\n </overlay-trigger>\n `)()\n );\n await elementUpdated(el);\n button = el.querySelector('sp-action-button') as ActionButton;\n tooltip = el.querySelector('sp-tooltip') as Tooltip;\n });\n it('allows pointer to enter the \"tooltip\" without closing the \"tooltip\"', async () => {\n const opened = oneEvent(button, 'sp-opened');\n button.dispatchEvent(\n new MouseEvent('pointerenter', {\n bubbles: true,\n composed: true,\n })\n );\n await nextFrame();\n await nextFrame();\n await nextFrame();\n await nextFrame();\n expect(tooltip.open).to.be.true;\n\n button.dispatchEvent(\n new MouseEvent('pointerleave', {\n bubbles: true,\n composed: true,\n })\n );\n await nextFrame();\n\n button.dispatchEvent(\n new MouseEvent('pointerenter', {\n bubbles: true,\n composed: true,\n })\n );\n await nextFrame();\n\n tooltip.dispatchEvent(\n new MouseEvent('pointerleave', {\n bubbles: true,\n composed: true,\n })\n );\n await nextFrame();\n\n button.dispatchEvent(\n new MouseEvent('pointerenter', {\n bubbles: true,\n composed: true,\n })\n );\n await opened;\n\n expect(el.open).to.equal('hover');\n\n const closed = oneEvent(button, 'sp-closed');\n button.dispatchEvent(\n new MouseEvent('pointerleave', {\n relatedTarget: null,\n bubbles: true,\n composed: true,\n })\n );\n await closed;\n\n expect(el.open).to.be.undefined;\n });\n it('closes the \"tooltip\" when leaving the \"tooltip\"', async () => {\n const opened = oneEvent(button, 'sp-opened');\n button.dispatchEvent(\n new MouseEvent('pointerenter', {\n bubbles: true,\n composed: true,\n })\n );\n await nextFrame();\n button.dispatchEvent(\n new MouseEvent('pointerleave', {\n relatedTarget: tooltip,\n bubbles: true,\n composed: true,\n })\n );\n await opened;\n\n expect(el.open).to.equal('hover');\n\n const closed = oneEvent(button, 'sp-closed');\n tooltip.dispatchEvent(\n new MouseEvent('pointerleave', {\n relatedTarget: null,\n bubbles: true,\n composed: true,\n })\n );\n await closed;\n\n expect(el.open).to.be.undefined;\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 const opened = oneEvent(trigger, 'sp-opened');\n trigger.dispatchEvent(\n new Event('pointerenter', {\n bubbles: true,\n composed: true,\n })\n );\n await opened;\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 let opened = oneEvent(trigger, 'sp-opened');\n trigger.dispatchEvent(\n new Event('pointerenter', {\n bubbles: true,\n })\n );\n await opened;\n\n expect(el.open).to.equal('hover');\n\n opened = oneEvent(trigger, 'sp-opened');\n trigger.dispatchEvent(\n new Event('longpress', {\n bubbles: true,\n })\n );\n await opened;\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 const input = document.createElement('input');\n el.insertAdjacentElement('beforebegin', input);\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 input.focus();\n await sendKeys({\n press: 'Tab',\n });\n await opened;\n\n expect(el.open).to.equal('hover');\n\n const closed = oneEvent(el, 'sp-closed');\n trigger.blur();\n await closed;\n\n expect(el.open).to.be.undefined;\n });\n it('will not return focus to a \"modal\" parent', async () => {\n const el = await styledFixture<OverlayTrigger>(html`\n <overlay-trigger type=\"modal\">\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 const button1 = dialog.querySelector('#button-1') as Button;\n const button2 = dialog.querySelector('#button-2') as Button;\n const button3 = dialog.querySelector('#button-3') as Button;\n await elementUpdated(button);\n await elementUpdated(dialog);\n\n let opened = oneEvent(button, 'sp-opened');\n const openedHint = oneEvent(button1, 'sp-opened');\n button.dispatchEvent(new Event('click', { bubbles: true }));\n await opened;\n await openedHint;\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 expect(button2 === document.activeElement).to.be.true;\n\n opened = oneEvent(button3, 'sp-opened');\n sendKeys({\n press: 'Tab',\n });\n await opened;\n\n expect(button3 === document.activeElement).to.be.true;\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|