@lion/ui 0.0.9 → 0.0.10
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/components/core/src/SlotMixin.js +2 -1
- package/components/dialog/test/lion-dialog.test.js +3 -7
- package/components/form-integrations/test/form-group-methods.test.js +6 -4
- package/components/form-integrations/test/form-integrations.test.js +10 -5
- package/components/form-integrations/test/helpers/umbrella-form.js +10 -0
- package/components/form-integrations/test/model-value-consistency.test.js +29 -20
- package/components/input-datepicker/src/LionInputDatepicker.js +64 -100
- package/components/input-datepicker/src/localizeNamespaceLoader.js +188 -0
- package/components/input-datepicker/test/lion-input-datepicker.test.js +15 -20
- package/components/input-datepicker/test-helpers/DatepickerInputObject.js +3 -3
- package/components/input-tel/src/parsers.js +1 -1
- package/components/listbox/test-suites/ListboxMixin.suite.js +3 -3
- package/components/localize/test/number/formatNumber.test.js +2 -6
- package/components/overlays/src/OverlayController.js +236 -289
- package/components/overlays/src/OverlayMixin.js +17 -18
- package/components/overlays/src/OverlaysManager.js +28 -53
- package/components/overlays/src/overlayDocumentStyle.js +24 -0
- package/components/overlays/src/overlayShadowDomStyle.js +138 -0
- package/components/overlays/src/singleton.js +3 -1
- package/components/overlays/test/ArrowMixin.test.js +0 -1
- package/components/overlays/test/OverlayController.test.js +306 -273
- package/components/overlays/test/OverlaysManager.test.js +23 -32
- package/components/overlays/test/global-positioning.test.js +4 -15
- package/components/overlays/test/local-positioning.test.js +65 -38
- package/components/overlays/test-suites/OverlayMixin.suite.js +18 -26
- package/components/overlays/types/OverlayConfig.ts +32 -11
- package/components/overlays/types/OverlayMixinTypes.ts +2 -2
- package/components/select-rich/src/LionSelectInvoker.js +2 -3
- package/components/select-rich/src/LionSelectRich.js +22 -20
- package/components/select-rich/test/lion-select-rich.test.js +5 -7
- package/custom-elements.json +251 -362
- package/dist-types/components/core/src/SlotMixin.d.ts.map +1 -1
- package/dist-types/components/form-integrations/test/helpers/umbrella-form.d.ts +4 -0
- package/dist-types/components/form-integrations/test/helpers/umbrella-form.d.ts.map +1 -1
- package/dist-types/components/form-integrations/test/model-value-consistency.test.d.ts.map +1 -1
- package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts +3 -3
- package/dist-types/components/input-datepicker/src/LionInputDatepicker.d.ts.map +1 -1
- package/dist-types/components/input-datepicker/src/localizeNamespaceLoader.d.ts +4 -0
- package/dist-types/components/input-datepicker/src/localizeNamespaceLoader.d.ts.map +1 -0
- package/dist-types/components/overlays/src/OverlayController.d.ts +46 -101
- package/dist-types/components/overlays/src/OverlayController.d.ts.map +1 -1
- package/dist-types/components/overlays/src/OverlayMixin.d.ts.map +1 -1
- package/dist-types/components/overlays/src/OverlaysManager.d.ts +0 -7
- package/dist-types/components/overlays/src/OverlaysManager.d.ts.map +1 -1
- package/dist-types/components/overlays/src/overlayDocumentStyle.d.ts +2 -0
- package/dist-types/components/overlays/src/overlayDocumentStyle.d.ts.map +1 -0
- package/dist-types/components/overlays/src/overlayShadowDomStyle.d.ts +2 -0
- package/dist-types/components/overlays/src/overlayShadowDomStyle.d.ts.map +1 -0
- package/dist-types/components/overlays/src/singleton.d.ts +2 -1
- package/dist-types/components/overlays/src/singleton.d.ts.map +1 -1
- package/dist-types/components/overlays/test-suites/OverlayMixin.suite.d.ts.map +1 -1
- package/dist-types/components/overlays/types/OverlayConfig.d.ts +14 -10
- package/dist-types/components/overlays/types/OverlayConfig.d.ts.map +1 -1
- package/dist-types/components/overlays/types/OverlayMixinTypes.d.ts +2 -2
- package/dist-types/components/overlays/types/OverlayMixinTypes.d.ts.map +1 -1
- package/dist-types/components/select-rich/src/LionSelectInvoker.d.ts +3 -27
- package/dist-types/components/select-rich/src/LionSelectInvoker.d.ts.map +1 -1
- package/dist-types/components/select-rich/src/LionSelectRich.d.ts.map +1 -1
- package/dist-types/components/select-rich/test/lion-select-rich.test.d.ts.map +1 -1
- package/dist-types/exports/input-datepicker.d.ts +0 -1
- package/dist-types/exports/overlays.d.ts +0 -1
- package/dist-types/exports/types/overlays.d.ts +1 -0
- package/dist-types/exports/types/overlays.d.ts.map +1 -1
- package/dist-types/tsconfig.tsbuildinfo +1 -1
- package/docs/components/checkbox-group/overview.md +2 -2
- package/docs/components/collapsible/overview.md +1 -1
- package/docs/components/combobox/overview.md +1 -1
- package/docs/components/combobox/use-cases.md +1 -1
- package/docs/components/dialog/overview.md +5 -9
- package/docs/components/dialog/use-cases.md +43 -87
- package/docs/components/fieldset/overview.md +5 -5
- package/docs/components/form/overview.md +3 -3
- package/docs/components/icon/use-cases.md +1 -1
- package/docs/components/input/overview.md +1 -1
- package/docs/components/input-amount/overview.md +3 -3
- package/docs/components/input-date/overview.md +3 -3
- package/docs/components/input-datepicker/overview.md +5 -5
- package/docs/components/input-email/overview.md +2 -2
- package/docs/components/input-iban/overview.md +2 -2
- package/docs/components/input-range/overview.md +2 -2
- package/docs/components/input-stepper/overview.md +1 -1
- package/docs/components/input-tel/overview.md +1 -1
- package/docs/components/input-tel/use-cases.md +6 -6
- package/docs/components/input-tel-dropdown/overview.md +1 -1
- package/docs/components/radio-group/overview.md +3 -3
- package/docs/components/select-rich/use-cases.md +1 -1
- package/docs/components/tabs/examples.md +1 -1
- package/docs/fundamentals/index.md +4 -4
- package/docs/fundamentals/node-tools/providence-analytics/LocalConfiguration.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/QueryResult.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/analyzer.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/dashboard.md +1 -1
- package/docs/fundamentals/node-tools/providence-analytics/overview.md +3 -3
- package/docs/fundamentals/node-tools/publish-docs/overview.md +3 -3
- package/docs/fundamentals/node-tools/rocket-preset-extend-lion-docs/overview.md +2 -2
- package/docs/fundamentals/systems/core/overview.md +1 -1
- package/docs/fundamentals/systems/form/formatting-and-parsing.md +4 -4
- package/docs/fundamentals/systems/form/model-value.md +1 -1
- package/docs/fundamentals/systems/form/overview.md +28 -28
- package/docs/fundamentals/systems/form/use-cases.md +4 -0
- package/docs/fundamentals/systems/form/validate.md +1 -1
- package/docs/fundamentals/systems/localize/overview.md +4 -4
- package/docs/fundamentals/systems/overlays/assets/{applyDemoOverlayStyles.js → applyDemoOverlayStyles.mjs} +2 -1
- package/docs/fundamentals/systems/overlays/assets/demo-el-using-overlaymixin.mjs +119 -0
- package/docs/fundamentals/systems/overlays/assets/{demo-overlay-backdrop.js → demo-overlay-backdrop.mjs} +3 -4
- package/docs/fundamentals/systems/overlays/assets/demo-overlay-positioning.mjs +537 -0
- package/docs/fundamentals/systems/overlays/assets/umbrella-form.js +9 -2
- package/docs/fundamentals/systems/overlays/configuration.md +56 -54
- package/docs/fundamentals/systems/overlays/overview.md +5 -5
- package/docs/fundamentals/systems/overlays/use-cases.md +83 -77
- package/docs/fundamentals/tools/helpers/overview.md +1 -1
- package/docs/fundamentals/tools/singleton-manager/overview.md +4 -4
- package/docs/guides/how-to/create-a-custom-field.md +6 -6
- package/docs/guides/how-to/extend-a-native-input.md +3 -3
- package/docs/guides/index.md +8 -8
- package/docs/guides/principles/index.md +5 -5
- package/docs/guides/principles/styling.md +1 -1
- package/exports/input-datepicker.js +0 -1
- package/exports/overlays.js +0 -1
- package/exports/types/overlays.ts +1 -0
- package/package.json +2 -1
- package/components/input-datepicker/src/LionCalendarOverlayFrame.js +0 -125
- package/components/overlays/src/globalOverlaysStyle.js +0 -139
- package/dist-types/components/input-datepicker/src/LionCalendarOverlayFrame.d.ts +0 -10
- package/dist-types/components/input-datepicker/src/LionCalendarOverlayFrame.d.ts.map +0 -1
- package/dist-types/components/overlays/src/globalOverlaysStyle.d.ts +0 -2
- package/dist-types/components/overlays/src/globalOverlaysStyle.d.ts.map +0 -1
- package/dist-types/exports/define/lion-calendar-overlay-frame.d.ts +0 -2
- package/dist-types/exports/define/lion-calendar-overlay-frame.d.ts.map +0 -1
- package/docs/fundamentals/systems/overlays/assets/demo-overlay-system.js +0 -42
- package/docs/fundamentals/systems/overlays/form-integration.md +0 -65
- package/docs/fundamentals/systems/overlays/scope.md +0 -176
- package/exports/define/lion-calendar-overlay-frame.js +0 -3
|
@@ -20,6 +20,17 @@ import { simulateTab } from '../src/utils/simulate-tab.js';
|
|
|
20
20
|
* @typedef {import('../types/OverlayConfig.js').ViewportPlacement} ViewportPlacement
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
+
const wrappingDialogNodeStyle = 'display: none; z-index: 9999;';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @param {HTMLElement} node
|
|
27
|
+
*/
|
|
28
|
+
function normalizeOverlayContentWapper(node) {
|
|
29
|
+
if (node.hasAttribute('style') && !node.style.cssText) {
|
|
30
|
+
node.removeAttribute('style');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
23
34
|
/**
|
|
24
35
|
* @param {OverlayController} overlayControllerEl
|
|
25
36
|
*/
|
|
@@ -66,7 +77,7 @@ describe('OverlayController', () => {
|
|
|
66
77
|
...withGlobalTestConfig(),
|
|
67
78
|
});
|
|
68
79
|
expect(ctrl.content).not.to.be.undefined;
|
|
69
|
-
expect(ctrl.contentNode.parentElement).to.equal(ctrl.
|
|
80
|
+
expect(ctrl.contentNode.parentElement).to.equal(ctrl.contentWrapperNode);
|
|
70
81
|
});
|
|
71
82
|
|
|
72
83
|
describe('Z-index on local overlays', () => {
|
|
@@ -106,17 +117,21 @@ describe('OverlayController', () => {
|
|
|
106
117
|
contentNode: await createZNode('auto', { mode: 'global' }),
|
|
107
118
|
});
|
|
108
119
|
await ctrl.show();
|
|
109
|
-
expect
|
|
120
|
+
// @ts-expect-error find out why config would/could be undfined
|
|
121
|
+
expect(ctrl.content.style.zIndex).to.equal(`${ctrl.config.zIndex + 1}`);
|
|
110
122
|
ctrl.updateConfig({ contentNode: await createZNode('auto', { mode: 'inline' }) });
|
|
111
123
|
await ctrl.show();
|
|
112
|
-
expect
|
|
124
|
+
// @ts-expect-error find out why config would/could be undfined
|
|
125
|
+
expect(ctrl.content.style.zIndex).to.equal(`${ctrl.config.zIndex + 1}`);
|
|
113
126
|
|
|
114
127
|
ctrl.updateConfig({ contentNode: await createZNode('0', { mode: 'global' }) });
|
|
115
128
|
await ctrl.show();
|
|
116
|
-
expect
|
|
129
|
+
// @ts-expect-error find out why config would/could be undfined
|
|
130
|
+
expect(ctrl.content.style.zIndex).to.equal(`${ctrl.config.zIndex + 1}`);
|
|
117
131
|
ctrl.updateConfig({ contentNode: await createZNode('0', { mode: 'inline' }) });
|
|
118
132
|
await ctrl.show();
|
|
119
|
-
expect
|
|
133
|
+
// @ts-expect-error find out why config would/could be undfined
|
|
134
|
+
expect(ctrl.content.style.zIndex).to.equal(`${ctrl.config.zIndex + 1}`);
|
|
120
135
|
});
|
|
121
136
|
|
|
122
137
|
it.skip("doesn't set a z-index when contentNode already has >= 1", async () => {
|
|
@@ -147,42 +162,7 @@ describe('OverlayController', () => {
|
|
|
147
162
|
});
|
|
148
163
|
});
|
|
149
164
|
|
|
150
|
-
describe('
|
|
151
|
-
it('creates global target for placement mode "global"', async () => {
|
|
152
|
-
const ctrl = new OverlayController({
|
|
153
|
-
...withGlobalTestConfig(),
|
|
154
|
-
});
|
|
155
|
-
const { renderTarget } = getProtectedMembers(ctrl);
|
|
156
|
-
expect(renderTarget).to.equal(overlays.globalRootNode);
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
it.skip('creates local target next to sibling for placement mode "local"', async () => {
|
|
160
|
-
const ctrl = new OverlayController({
|
|
161
|
-
...withLocalTestConfig(),
|
|
162
|
-
invokerNode: /** @type {HTMLElement} */ (await fixture(html`<button>Invoker</button>`)),
|
|
163
|
-
});
|
|
164
|
-
const { renderTarget } = getProtectedMembers(ctrl);
|
|
165
|
-
expect(renderTarget).to.be.undefined;
|
|
166
|
-
expect(ctrl.content).to.equal(ctrl.invokerNode?.nextElementSibling);
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
it('keeps local target for placement mode "local" when already connected', async () => {
|
|
170
|
-
const parentNode = /** @type {HTMLElement} */ (
|
|
171
|
-
await fixture(html`
|
|
172
|
-
<div id="parent">
|
|
173
|
-
<div id="content">Content</div>
|
|
174
|
-
</div>
|
|
175
|
-
`)
|
|
176
|
-
);
|
|
177
|
-
const contentNode = /** @type {HTMLElement} */ (parentNode.querySelector('#content'));
|
|
178
|
-
const ctrl = new OverlayController({
|
|
179
|
-
...withLocalTestConfig(),
|
|
180
|
-
contentNode,
|
|
181
|
-
});
|
|
182
|
-
const { renderTarget } = getProtectedMembers(ctrl);
|
|
183
|
-
expect(renderTarget).to.equal(parentNode);
|
|
184
|
-
});
|
|
185
|
-
|
|
165
|
+
describe('Offline content', () => {
|
|
186
166
|
it('throws when passing a content node that was created "offline"', async () => {
|
|
187
167
|
const contentNode = document.createElement('div');
|
|
188
168
|
const createOverlayController = () => {
|
|
@@ -197,113 +177,250 @@ describe('OverlayController', () => {
|
|
|
197
177
|
});
|
|
198
178
|
|
|
199
179
|
it('succeeds when passing a content node that was created "online"', async () => {
|
|
200
|
-
const contentNode =
|
|
201
|
-
document.body.appendChild(contentNode);
|
|
180
|
+
const contentNode = /** @type {HTMLElement} */ (fixtureSync('<div>'));
|
|
202
181
|
const overlay = new OverlayController({
|
|
203
182
|
...withLocalTestConfig(),
|
|
204
183
|
contentNode,
|
|
205
184
|
});
|
|
206
|
-
const { renderTarget } = getProtectedMembers(overlay);
|
|
207
|
-
|
|
208
185
|
expect(overlay.contentNode.isConnected).to.be.true;
|
|
209
|
-
expect(renderTarget).to.not.be.undefined;
|
|
210
186
|
});
|
|
211
187
|
});
|
|
212
188
|
});
|
|
213
189
|
|
|
214
190
|
// TODO: Add teardown feature tests
|
|
215
|
-
describe('Teardown', () => {
|
|
216
|
-
it('removes the contentWrapperNode from global rootnode upon teardown', async () => {
|
|
217
|
-
const ctrl = new OverlayController({
|
|
218
|
-
...withGlobalTestConfig(),
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
expect(ctrl.manager.globalRootNode.children.length).to.equal(1);
|
|
222
|
-
ctrl.teardown();
|
|
223
|
-
expect(ctrl.manager.globalRootNode.children.length).to.equal(0);
|
|
224
|
-
});
|
|
191
|
+
describe('Teardown', () => {});
|
|
225
192
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
193
|
+
describe('Node Configuration', () => {
|
|
194
|
+
describe('Content', async () => {
|
|
195
|
+
it('accepts a .contentNode for displaying content of the overlay', async () => {
|
|
196
|
+
const myContentNode = /** @type {HTMLElement} */ (fixtureSync('<p>direct node</p>'));
|
|
197
|
+
const ctrl = new OverlayController({
|
|
198
|
+
...withGlobalTestConfig(),
|
|
199
|
+
contentNode: myContentNode,
|
|
200
|
+
});
|
|
201
|
+
expect(ctrl.contentNode).to.have.trimmed.text('direct node');
|
|
202
|
+
expect(ctrl.contentNode).to.equal(myContentNode);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
describe('Embedded dom structure', async () => {
|
|
206
|
+
describe('When projected in shadow dom', async () => {
|
|
207
|
+
it('wraps a .contentWrapperNode for style application and a <dialog role="none"> for top layer paints', async () => {
|
|
208
|
+
const tagString = defineCE(
|
|
209
|
+
class extends HTMLElement {
|
|
210
|
+
constructor() {
|
|
211
|
+
super();
|
|
212
|
+
this.attachShadow({ mode: 'open' });
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
connectedCallback() {
|
|
216
|
+
/** @type {ShadowRoot} */
|
|
217
|
+
(this.shadowRoot).innerHTML = '<slot name="content"></slot>';
|
|
218
|
+
this.innerHTML = '<div slot="content">projected</div>';
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
const el = /** @type {HTMLElement} */ (fixtureSync(`<${tagString}></${tagString}>`));
|
|
224
|
+
const myContentNode = /** @type {HTMLElement} */ (el.querySelector('[slot=content]'));
|
|
225
|
+
const ctrl = new OverlayController({
|
|
226
|
+
...withGlobalTestConfig(),
|
|
227
|
+
contentNode: myContentNode,
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
expect(ctrl.contentNode.assignedSlot?.parentElement).to.equal(ctrl.contentWrapperNode);
|
|
231
|
+
expect(ctrl.contentWrapperNode.parentElement?.tagName).to.equal('DIALOG');
|
|
232
|
+
|
|
233
|
+
normalizeOverlayContentWapper(ctrl.contentWrapperNode);
|
|
234
|
+
|
|
235
|
+
// The total dom structure created...
|
|
236
|
+
expect(el).shadowDom.to.equal(`
|
|
237
|
+
<dialog data-overlay-outer-wrapper="" open="" role="none" style="${wrappingDialogNodeStyle}">
|
|
238
|
+
<div data-id="content-wrapper">
|
|
239
|
+
<slot name="content">
|
|
240
|
+
</slot>
|
|
241
|
+
</div>
|
|
242
|
+
</dialog>
|
|
243
|
+
`);
|
|
244
|
+
|
|
245
|
+
expect(el).lightDom.to.equal(`<div slot="content">projected</div>`);
|
|
246
|
+
});
|
|
247
|
+
});
|
|
240
248
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
249
|
+
describe('When in light dom', async () => {
|
|
250
|
+
it('wraps a .contentWrapperNode for style application and a <dialog role="none"> for top layer paints', async () => {
|
|
251
|
+
const el = fixtureSync('<section><div id="content">non projected</div></section>');
|
|
252
|
+
const myContentNode = /** @type {HTMLElement} */ (el.querySelector('#content'));
|
|
253
|
+
const ctrl = new OverlayController({
|
|
254
|
+
...withGlobalTestConfig(),
|
|
255
|
+
contentNode: myContentNode,
|
|
256
|
+
});
|
|
257
|
+
expect(ctrl.contentNode.parentElement).to.equal(ctrl.contentWrapperNode);
|
|
258
|
+
expect(ctrl.contentWrapperNode.parentElement?.tagName).to.equal('DIALOG');
|
|
259
|
+
|
|
260
|
+
normalizeOverlayContentWapper(ctrl.contentWrapperNode);
|
|
261
|
+
|
|
262
|
+
// The total dom structure created...
|
|
263
|
+
expect(el).lightDom.to.equal(`
|
|
264
|
+
<dialog data-overlay-outer-wrapper="" open="" role="none" style="${wrappingDialogNodeStyle}">
|
|
265
|
+
<div data-id="content-wrapper">
|
|
266
|
+
<div id="content">non projected</div>
|
|
267
|
+
</div>
|
|
268
|
+
</dialog>
|
|
269
|
+
`);
|
|
270
|
+
});
|
|
271
|
+
});
|
|
244
272
|
|
|
245
|
-
|
|
246
|
-
|
|
273
|
+
describe('When .contenWrapperNode provided', async () => {
|
|
274
|
+
it('keeps the .contentWrapperNode for style application and wraps a <dialog role="none"> for top layer paints', async () => {
|
|
275
|
+
const tagString = defineCE(
|
|
276
|
+
class extends HTMLElement {
|
|
277
|
+
constructor() {
|
|
278
|
+
super();
|
|
279
|
+
this.attachShadow({ mode: 'open' });
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
connectedCallback() {
|
|
283
|
+
/** @type {ShadowRoot} */
|
|
284
|
+
(this.shadowRoot).innerHTML = '<div><slot name="content"></slot></div>';
|
|
285
|
+
this.innerHTML = '<div slot="content">projected</div>';
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
const el = /** @type {HTMLElement} */ (fixtureSync(`<${tagString}></${tagString}>`));
|
|
291
|
+
const myContentNode = /** @type {HTMLElement} */ (el.querySelector('[slot=content]'));
|
|
292
|
+
const myContentWrapper = /** @type {HTMLElement} */ (
|
|
293
|
+
el.shadowRoot?.querySelector('div')
|
|
294
|
+
);
|
|
295
|
+
const ctrl = new OverlayController({
|
|
296
|
+
...withGlobalTestConfig(),
|
|
297
|
+
contentNode: myContentNode,
|
|
298
|
+
contentWrapperNode: myContentWrapper,
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
normalizeOverlayContentWapper(ctrl.contentWrapperNode);
|
|
302
|
+
|
|
303
|
+
// The total dom structure created...
|
|
304
|
+
expect(el).shadowDom.to.equal(`
|
|
305
|
+
<dialog data-overlay-outer-wrapper="" open="" role="none" style="${wrappingDialogNodeStyle}">
|
|
306
|
+
<div data-id="content-wrapper">
|
|
307
|
+
<slot name="content"></slot>
|
|
308
|
+
</div>
|
|
309
|
+
</dialog>
|
|
310
|
+
`);
|
|
311
|
+
});
|
|
247
312
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
313
|
+
it("uses the .contentWrapperNode as container for Popper's arrow", async () => {
|
|
314
|
+
const tagString = defineCE(
|
|
315
|
+
class extends HTMLElement {
|
|
316
|
+
constructor() {
|
|
317
|
+
super();
|
|
318
|
+
this.attachShadow({ mode: 'open' });
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
connectedCallback() {
|
|
322
|
+
/** @type {ShadowRoot} */
|
|
323
|
+
(this.shadowRoot).innerHTML = `
|
|
324
|
+
<div>
|
|
325
|
+
<div id="arrow"></div>
|
|
326
|
+
<slot name="content"></slot>
|
|
327
|
+
</div>`;
|
|
328
|
+
this.innerHTML = '<div slot="content">projected</div>';
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
);
|
|
332
|
+
|
|
333
|
+
const el = /** @type {HTMLElement} */ (fixtureSync(`<${tagString}></${tagString}>`));
|
|
334
|
+
const myContentNode = /** @type {HTMLElement} */ (el.querySelector('[slot=content]'));
|
|
335
|
+
const myContentWrapper = /** @type {HTMLElement} */ (
|
|
336
|
+
el.shadowRoot?.querySelector('div')
|
|
337
|
+
);
|
|
338
|
+
const ctrl = new OverlayController({
|
|
339
|
+
...withLocalTestConfig(),
|
|
340
|
+
contentNode: myContentNode,
|
|
341
|
+
contentWrapperNode: myContentWrapper,
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
normalizeOverlayContentWapper(ctrl.contentWrapperNode);
|
|
345
|
+
|
|
346
|
+
// The total dom structure created...
|
|
347
|
+
expect(el).shadowDom.to.equal(`
|
|
348
|
+
<dialog data-overlay-outer-wrapper="" open="" role="none" style="${wrappingDialogNodeStyle}">
|
|
349
|
+
<div data-id="content-wrapper">
|
|
350
|
+
<div id="arrow"></div>
|
|
351
|
+
<slot name="content"></slot>
|
|
352
|
+
</div>
|
|
353
|
+
</dialog>
|
|
354
|
+
`);
|
|
355
|
+
});
|
|
356
|
+
});
|
|
253
357
|
});
|
|
254
|
-
|
|
255
|
-
// has no children as content gets moved to the body
|
|
256
|
-
expect(shadowHost.children.length).to.equal(0);
|
|
257
|
-
ctrl.teardown();
|
|
258
|
-
|
|
259
|
-
// restores original light dom in teardown
|
|
260
|
-
expect(shadowHost.children.length).to.equal(1);
|
|
261
358
|
});
|
|
262
|
-
});
|
|
263
359
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
360
|
+
describe('Invoker / Reference', async () => {
|
|
361
|
+
it('accepts a .invokerNode to directly set invoker', async () => {
|
|
362
|
+
const myInvokerNode = /** @type {HTMLElement} */ (fixtureSync('<button>invoke</button>'));
|
|
363
|
+
const ctrl = new OverlayController({
|
|
364
|
+
...withGlobalTestConfig(),
|
|
365
|
+
invokerNode: myInvokerNode,
|
|
366
|
+
});
|
|
367
|
+
expect(ctrl.invokerNode).to.equal(myInvokerNode);
|
|
368
|
+
expect(ctrl.referenceNode).to.equal(undefined);
|
|
269
369
|
});
|
|
270
|
-
expect(ctrl.contentNode).to.have.trimmed.text('direct node');
|
|
271
|
-
});
|
|
272
370
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
371
|
+
it('accepts a .referenceNode as positioning anchor different from .invokerNode', async () => {
|
|
372
|
+
const myInvokerNode = /** @type {HTMLElement} */ (fixtureSync('<button>invoke</button>'));
|
|
373
|
+
const myReferenceNode = /** @type {HTMLElement} */ (fixtureSync('<div>anchor</div>'));
|
|
374
|
+
const ctrl = new OverlayController({
|
|
375
|
+
...withGlobalTestConfig(),
|
|
376
|
+
invokerNode: myInvokerNode,
|
|
377
|
+
referenceNode: myReferenceNode,
|
|
378
|
+
});
|
|
379
|
+
expect(ctrl.referenceNode).to.equal(myReferenceNode);
|
|
380
|
+
expect(ctrl.invokerNode).to.not.equal(ctrl.referenceNode);
|
|
277
381
|
});
|
|
278
|
-
expect(ctrl.invokerNode).to.have.trimmed.text('invoke');
|
|
279
382
|
});
|
|
280
383
|
|
|
281
|
-
describe('
|
|
282
|
-
it('
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
</div>
|
|
290
|
-
`;
|
|
291
|
-
const contentNode = document.createElement('div');
|
|
292
|
-
contentNode.slot = 'contentNode';
|
|
293
|
-
shadowHost.appendChild(contentNode);
|
|
384
|
+
describe('Backdrop', () => {
|
|
385
|
+
it('creates a .backdropNode inside <dialog> for guaranteed top layer paints and positioning opportunities', async () => {
|
|
386
|
+
const tagString = defineCE(
|
|
387
|
+
class extends HTMLElement {
|
|
388
|
+
constructor() {
|
|
389
|
+
super();
|
|
390
|
+
this.attachShadow({ mode: 'open' });
|
|
391
|
+
}
|
|
294
392
|
|
|
295
|
-
|
|
296
|
-
|
|
393
|
+
connectedCallback() {
|
|
394
|
+
/** @type {ShadowRoot} */
|
|
395
|
+
(this.shadowRoot).innerHTML = '<slot name="content"></slot>';
|
|
396
|
+
this.innerHTML = '<div slot="content">projected</div>';
|
|
397
|
+
}
|
|
398
|
+
},
|
|
399
|
+
);
|
|
400
|
+
|
|
401
|
+
const el = /** @type {HTMLElement} */ (fixtureSync(`<${tagString}></${tagString}>`));
|
|
402
|
+
const myContentNode = /** @type {HTMLElement} */ (el.querySelector('[slot=content]'));
|
|
297
403
|
|
|
298
404
|
const ctrl = new OverlayController({
|
|
299
|
-
...
|
|
300
|
-
contentNode,
|
|
301
|
-
|
|
302
|
-
/** @type {ShadowRoot} */ (shadowHost.shadowRoot).getElementById('contentWrapperNode')
|
|
303
|
-
),
|
|
405
|
+
...withGlobalTestConfig(),
|
|
406
|
+
contentNode: myContentNode,
|
|
407
|
+
hasBackdrop: true,
|
|
304
408
|
});
|
|
305
409
|
|
|
306
|
-
|
|
410
|
+
normalizeOverlayContentWapper(ctrl.contentWrapperNode);
|
|
411
|
+
|
|
412
|
+
// The total dom structure created...
|
|
413
|
+
expect(el).shadowDom.to.equal(
|
|
414
|
+
`
|
|
415
|
+
<dialog data-overlay-outer-wrapper="" open="" role="none" style="${wrappingDialogNodeStyle}">
|
|
416
|
+
<div class="overlays__backdrop"></div>
|
|
417
|
+
<div data-id="content-wrapper">
|
|
418
|
+
<slot name="content">
|
|
419
|
+
</slot>
|
|
420
|
+
</div>
|
|
421
|
+
</dialog>
|
|
422
|
+
`,
|
|
423
|
+
);
|
|
307
424
|
});
|
|
308
425
|
});
|
|
309
426
|
|
|
@@ -446,6 +563,18 @@ describe('OverlayController', () => {
|
|
|
446
563
|
document.dispatchEvent(new KeyboardEvent('keyup', { key: 'Escape' }));
|
|
447
564
|
expect(ctrl.isShown).to.be.true;
|
|
448
565
|
});
|
|
566
|
+
|
|
567
|
+
it('does not hide when [escape] is pressed with modal <dialog> and "hidesOnEsc" is false', async () => {
|
|
568
|
+
const ctrl = new OverlayController({
|
|
569
|
+
...withGlobalTestConfig(),
|
|
570
|
+
trapsKeyboardFocus: true,
|
|
571
|
+
hidesOnEsc: false,
|
|
572
|
+
});
|
|
573
|
+
await ctrl.show();
|
|
574
|
+
ctrl.contentNode.dispatchEvent(new KeyboardEvent('keyup', { key: 'Escape' }));
|
|
575
|
+
await aTimeout(0);
|
|
576
|
+
expect(ctrl.isShown).to.be.true;
|
|
577
|
+
});
|
|
449
578
|
});
|
|
450
579
|
|
|
451
580
|
describe('hidesOnOutsideEsc', () => {
|
|
@@ -760,6 +889,35 @@ describe('OverlayController', () => {
|
|
|
760
889
|
expect(document.activeElement).to.equal(input);
|
|
761
890
|
});
|
|
762
891
|
|
|
892
|
+
it('supports elementToFocusAfterHide option when shadowRoot involved involved', async () => {
|
|
893
|
+
const input = /** @type {HTMLElement} */ (await fixture('<input />'));
|
|
894
|
+
const contentNode = /** @type {HTMLElement} */ (
|
|
895
|
+
await fixture('<div><textarea></textarea></div>')
|
|
896
|
+
);
|
|
897
|
+
|
|
898
|
+
const shadowEl = document.createElement('div');
|
|
899
|
+
shadowEl.attachShadow({ mode: 'open' });
|
|
900
|
+
/** @type {ShadowRoot} */ (shadowEl.shadowRoot).innerHTML = `<slot></slot>`;
|
|
901
|
+
shadowEl.appendChild(contentNode);
|
|
902
|
+
document.body.appendChild(shadowEl);
|
|
903
|
+
|
|
904
|
+
const ctrl = new OverlayController({
|
|
905
|
+
...withGlobalTestConfig(),
|
|
906
|
+
elementToFocusAfterHide: input,
|
|
907
|
+
contentNode,
|
|
908
|
+
});
|
|
909
|
+
|
|
910
|
+
await ctrl.show();
|
|
911
|
+
const textarea = /** @type {HTMLTextAreaElement} */ (contentNode.querySelector('textarea'));
|
|
912
|
+
textarea.focus();
|
|
913
|
+
expect(document.activeElement).to.equal(textarea);
|
|
914
|
+
|
|
915
|
+
await ctrl.hide();
|
|
916
|
+
expect(document.activeElement).to.equal(input);
|
|
917
|
+
|
|
918
|
+
document.body.removeChild(shadowEl);
|
|
919
|
+
});
|
|
920
|
+
|
|
763
921
|
it(`only sets focus when outside world didn't take over already`, async () => {
|
|
764
922
|
const input = /** @type {HTMLElement} */ (await fixture('<input />'));
|
|
765
923
|
const outsideButton = /** @type {HTMLButtonElement} */ (await fixture('<button></button>'));
|
|
@@ -810,10 +968,10 @@ describe('OverlayController', () => {
|
|
|
810
968
|
});
|
|
811
969
|
|
|
812
970
|
await ctrl.show();
|
|
813
|
-
expect(
|
|
971
|
+
expect(Array.from(document.body.classList)).to.contain('overlays-scroll-lock');
|
|
814
972
|
|
|
815
973
|
await ctrl.hide();
|
|
816
|
-
expect(
|
|
974
|
+
expect(Array.from(document.body.classList)).to.not.contain('overlays-scroll-lock');
|
|
817
975
|
});
|
|
818
976
|
|
|
819
977
|
it('keeps preventing of scrolling when multiple overlays are opened and closed', async () => {
|
|
@@ -829,7 +987,7 @@ describe('OverlayController', () => {
|
|
|
829
987
|
await ctrl0.show();
|
|
830
988
|
await ctrl1.show();
|
|
831
989
|
await ctrl1.hide();
|
|
832
|
-
expect(
|
|
990
|
+
expect(Array.from(document.body.classList)).to.contain('overlays-scroll-lock');
|
|
833
991
|
});
|
|
834
992
|
});
|
|
835
993
|
|
|
@@ -856,7 +1014,7 @@ describe('OverlayController', () => {
|
|
|
856
1014
|
hasBackdrop: true,
|
|
857
1015
|
});
|
|
858
1016
|
await controllerWithBackdrop.show();
|
|
859
|
-
expect(controllerWithBackdrop.backdropNode).to.have.class('
|
|
1017
|
+
expect(controllerWithBackdrop.backdropNode).to.have.class('overlays__backdrop');
|
|
860
1018
|
});
|
|
861
1019
|
|
|
862
1020
|
it('reenables the backdrop when shown/hidden/shown', async () => {
|
|
@@ -865,10 +1023,10 @@ describe('OverlayController', () => {
|
|
|
865
1023
|
hasBackdrop: true,
|
|
866
1024
|
});
|
|
867
1025
|
await ctrl.show();
|
|
868
|
-
expect(ctrl.backdropNode).to.have.class('
|
|
1026
|
+
expect(ctrl.backdropNode).to.have.class('overlays__backdrop');
|
|
869
1027
|
await ctrl.hide();
|
|
870
1028
|
await ctrl.show();
|
|
871
|
-
expect(ctrl.backdropNode).to.have.class('
|
|
1029
|
+
expect(ctrl.backdropNode).to.have.class('overlays__backdrop');
|
|
872
1030
|
});
|
|
873
1031
|
|
|
874
1032
|
it('adds and stacks backdrops if .hasBackdrop is enabled', async () => {
|
|
@@ -877,14 +1035,14 @@ describe('OverlayController', () => {
|
|
|
877
1035
|
hasBackdrop: true,
|
|
878
1036
|
});
|
|
879
1037
|
await ctrl0.show();
|
|
880
|
-
expect(ctrl0.backdropNode).to.have.class('
|
|
1038
|
+
expect(ctrl0.backdropNode).to.have.class('overlays__backdrop');
|
|
881
1039
|
|
|
882
1040
|
const ctrl1 = new OverlayController({
|
|
883
1041
|
...withGlobalTestConfig(),
|
|
884
1042
|
hasBackdrop: false,
|
|
885
1043
|
});
|
|
886
1044
|
await ctrl1.show();
|
|
887
|
-
expect(ctrl0.backdropNode).to.have.class('
|
|
1045
|
+
expect(ctrl0.backdropNode).to.have.class('overlays__backdrop');
|
|
888
1046
|
expect(ctrl1.backdropNode).to.be.undefined;
|
|
889
1047
|
|
|
890
1048
|
const ctrl2 = new OverlayController({
|
|
@@ -893,9 +1051,9 @@ describe('OverlayController', () => {
|
|
|
893
1051
|
});
|
|
894
1052
|
await ctrl2.show();
|
|
895
1053
|
|
|
896
|
-
expect(ctrl0.backdropNode).to.have.class('
|
|
1054
|
+
expect(ctrl0.backdropNode).to.have.class('overlays__backdrop');
|
|
897
1055
|
expect(ctrl1.backdropNode).to.be.undefined;
|
|
898
|
-
expect(ctrl2.backdropNode).to.have.class('
|
|
1056
|
+
expect(ctrl2.backdropNode).to.have.class('overlays__backdrop');
|
|
899
1057
|
});
|
|
900
1058
|
});
|
|
901
1059
|
|
|
@@ -1003,24 +1161,24 @@ describe('OverlayController', () => {
|
|
|
1003
1161
|
await ctrl0.show();
|
|
1004
1162
|
await ctrl1.show();
|
|
1005
1163
|
await ctrl2.show(); // blocking
|
|
1006
|
-
expect(ctrl0.
|
|
1007
|
-
expect(ctrl1.
|
|
1008
|
-
expect(ctrl2.
|
|
1164
|
+
expect(ctrl0.__wrappingDialogNode).to.not.be.displayed;
|
|
1165
|
+
expect(ctrl1.__wrappingDialogNode).to.not.be.displayed;
|
|
1166
|
+
expect(ctrl2.__wrappingDialogNode).to.be.displayed;
|
|
1009
1167
|
|
|
1010
1168
|
await ctrl3.show();
|
|
1011
1169
|
await ctrl3._showComplete;
|
|
1012
|
-
expect(ctrl3.
|
|
1170
|
+
expect(ctrl3.__wrappingDialogNode).to.be.displayed;
|
|
1013
1171
|
|
|
1014
1172
|
await ctrl2.hide();
|
|
1015
1173
|
await ctrl2._hideComplete;
|
|
1016
|
-
expect(ctrl0.
|
|
1017
|
-
expect(ctrl1.
|
|
1174
|
+
expect(ctrl0.__wrappingDialogNode).to.be.displayed;
|
|
1175
|
+
expect(ctrl1.__wrappingDialogNode).to.be.displayed;
|
|
1018
1176
|
|
|
1019
1177
|
await ctrl2.show(); // blocking
|
|
1020
|
-
expect(ctrl0.
|
|
1021
|
-
expect(ctrl1.
|
|
1022
|
-
expect(ctrl2.
|
|
1023
|
-
expect(ctrl3.
|
|
1178
|
+
expect(ctrl0.__wrappingDialogNode).to.not.be.displayed;
|
|
1179
|
+
expect(ctrl1.__wrappingDialogNode).to.not.be.displayed;
|
|
1180
|
+
expect(ctrl2.__wrappingDialogNode).to.be.displayed;
|
|
1181
|
+
expect(ctrl3.__wrappingDialogNode).to.not.be.displayed;
|
|
1024
1182
|
});
|
|
1025
1183
|
|
|
1026
1184
|
it('keeps backdrop status when used in combination with blocking', async () => {
|
|
@@ -1197,11 +1355,11 @@ describe('OverlayController', () => {
|
|
|
1197
1355
|
|
|
1198
1356
|
ctrl.hide();
|
|
1199
1357
|
|
|
1200
|
-
expect(getComputedStyle(ctrl.
|
|
1358
|
+
expect(getComputedStyle(ctrl.content).display).to.equal('block');
|
|
1201
1359
|
setTimeout(() => {
|
|
1202
1360
|
hideTransitionFinished();
|
|
1203
1361
|
setTimeout(() => {
|
|
1204
|
-
expect(getComputedStyle(ctrl.
|
|
1362
|
+
expect(getComputedStyle(ctrl.content).display).to.equal('none');
|
|
1205
1363
|
done();
|
|
1206
1364
|
}, 0);
|
|
1207
1365
|
}, 0);
|
|
@@ -1285,15 +1443,11 @@ describe('OverlayController', () => {
|
|
|
1285
1443
|
});
|
|
1286
1444
|
|
|
1287
1445
|
ctrl.show();
|
|
1288
|
-
expect(
|
|
1289
|
-
ctrl.contentWrapperNode.classList.contains('global-overlays__overlay-container--center'),
|
|
1290
|
-
);
|
|
1446
|
+
expect(ctrl.contentWrapperNode.classList.contains('overlays__overlay-container--center'));
|
|
1291
1447
|
expect(ctrl.isShown).to.be.true;
|
|
1292
1448
|
|
|
1293
1449
|
ctrl.updateConfig({ viewportConfig: { placement: 'top-right' } });
|
|
1294
|
-
expect(
|
|
1295
|
-
ctrl.contentWrapperNode.classList.contains('global-overlays__overlay-container--top-right'),
|
|
1296
|
-
);
|
|
1450
|
+
expect(ctrl.contentWrapperNode.classList.contains('overlays__overlay-container--top-right'));
|
|
1297
1451
|
expect(ctrl.isShown).to.be.true;
|
|
1298
1452
|
});
|
|
1299
1453
|
});
|
|
@@ -1379,89 +1533,9 @@ describe('OverlayController', () => {
|
|
|
1379
1533
|
expect(properlyInstantiated).to.be.true;
|
|
1380
1534
|
});
|
|
1381
1535
|
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
trapsKeyboardFocus: true,
|
|
1386
|
-
});
|
|
1387
|
-
|
|
1388
|
-
const sibling1 = document.createElement('div');
|
|
1389
|
-
const sibling2 = document.createElement('div');
|
|
1390
|
-
document.body.insertBefore(sibling1, ctrl.manager.globalRootNode);
|
|
1391
|
-
document.body.appendChild(sibling2);
|
|
1392
|
-
|
|
1393
|
-
await ctrl.show();
|
|
1394
|
-
|
|
1395
|
-
[sibling1, sibling2].forEach(sibling => {
|
|
1396
|
-
expect(sibling).to.have.attribute('aria-hidden', 'true');
|
|
1397
|
-
expect(sibling).to.have.attribute('inert');
|
|
1398
|
-
});
|
|
1399
|
-
expect(ctrl.content.hasAttribute('aria-hidden')).to.be.false;
|
|
1400
|
-
expect(ctrl.content.hasAttribute('inert')).to.be.false;
|
|
1401
|
-
|
|
1402
|
-
await ctrl.hide();
|
|
1403
|
-
|
|
1404
|
-
[sibling1, sibling2].forEach(sibling => {
|
|
1405
|
-
expect(sibling).to.not.have.attribute('aria-hidden');
|
|
1406
|
-
expect(sibling).to.not.have.attribute('inert');
|
|
1407
|
-
});
|
|
1408
|
-
|
|
1409
|
-
// cleanup
|
|
1410
|
-
document.body.removeChild(sibling1);
|
|
1411
|
-
document.body.removeChild(sibling2);
|
|
1412
|
-
});
|
|
1413
|
-
|
|
1414
|
-
/**
|
|
1415
|
-
* style.userSelect:
|
|
1416
|
-
* - chrome: 'none'
|
|
1417
|
-
* - rest: undefined
|
|
1418
|
-
*
|
|
1419
|
-
* style.pointerEvents:
|
|
1420
|
-
* - chrome: auto
|
|
1421
|
-
* - IE11: visiblePainted
|
|
1422
|
-
*/
|
|
1423
|
-
it('disables pointer events and selection on inert elements', async () => {
|
|
1424
|
-
const ctrl = new OverlayController({
|
|
1425
|
-
...withGlobalTestConfig(),
|
|
1426
|
-
trapsKeyboardFocus: true,
|
|
1427
|
-
});
|
|
1428
|
-
|
|
1429
|
-
// show+hide are needed to create a root node
|
|
1430
|
-
await ctrl.show();
|
|
1431
|
-
await ctrl.hide();
|
|
1432
|
-
|
|
1433
|
-
const sibling1 = document.createElement('div');
|
|
1434
|
-
const sibling2 = document.createElement('div');
|
|
1435
|
-
document.body.insertBefore(sibling1, ctrl.manager.globalRootNode);
|
|
1436
|
-
document.body.appendChild(sibling2);
|
|
1437
|
-
|
|
1438
|
-
await ctrl.show();
|
|
1439
|
-
|
|
1440
|
-
[sibling1, sibling2].forEach(sibling => {
|
|
1441
|
-
expect(window.getComputedStyle(sibling).userSelect).to.be.oneOf(['none', undefined]);
|
|
1442
|
-
expect(window.getComputedStyle(sibling).pointerEvents).to.equal('none');
|
|
1443
|
-
});
|
|
1444
|
-
|
|
1445
|
-
expect(window.getComputedStyle(ctrl.contentNode).userSelect).to.be.oneOf(['auto', undefined]);
|
|
1446
|
-
expect(window.getComputedStyle(ctrl.contentNode).pointerEvents).to.be.oneOf([
|
|
1447
|
-
'auto',
|
|
1448
|
-
'visiblePainted',
|
|
1449
|
-
]);
|
|
1450
|
-
|
|
1451
|
-
await ctrl.hide();
|
|
1452
|
-
|
|
1453
|
-
[sibling1, sibling2].forEach(sibling => {
|
|
1454
|
-
expect(window.getComputedStyle(sibling).userSelect).to.be.oneOf(['auto', undefined]);
|
|
1455
|
-
expect(window.getComputedStyle(sibling).pointerEvents).to.be.oneOf([
|
|
1456
|
-
'auto',
|
|
1457
|
-
'visiblePainted',
|
|
1458
|
-
]);
|
|
1459
|
-
});
|
|
1460
|
-
|
|
1461
|
-
// cleanup
|
|
1462
|
-
document.body.removeChild(sibling1);
|
|
1463
|
-
document.body.removeChild(sibling2);
|
|
1464
|
-
});
|
|
1536
|
+
// TODO: check if we covered all functionality. "Inertness" should be handled by the platform with a modal overlay...
|
|
1537
|
+
it.skip('adds attributes inert and aria-hidden="true" on all siblings of rootNode if an overlay is shown', async () => {});
|
|
1538
|
+
it.skip('disables pointer events and selection on inert elements', async () => {});
|
|
1465
1539
|
|
|
1466
1540
|
describe('Tooltip', () => {
|
|
1467
1541
|
it('adds [aria-describedby] on invoker', async () => {
|
|
@@ -1616,47 +1690,6 @@ describe('OverlayController', () => {
|
|
|
1616
1690
|
}).to.throw('[OverlayController] You need to provide a .contentNode');
|
|
1617
1691
|
});
|
|
1618
1692
|
|
|
1619
|
-
it('throws if contentNodeWrapper is not provided for projected contentNode', async () => {
|
|
1620
|
-
const shadowHost = document.createElement('div');
|
|
1621
|
-
shadowHost.attachShadow({ mode: 'open' });
|
|
1622
|
-
/** @type {ShadowRoot} */ (shadowHost.shadowRoot).innerHTML = `
|
|
1623
|
-
<div id="contentWrapperNode">
|
|
1624
|
-
<slot name="contentNode"></slot>
|
|
1625
|
-
<my-arrow></my-arrow>
|
|
1626
|
-
</div>
|
|
1627
|
-
`;
|
|
1628
|
-
const contentNode = document.createElement('div');
|
|
1629
|
-
contentNode.slot = 'contentNode';
|
|
1630
|
-
shadowHost.appendChild(contentNode);
|
|
1631
|
-
|
|
1632
|
-
// Ensure the contentNode is connected to DOM
|
|
1633
|
-
document.body.appendChild(shadowHost);
|
|
1634
|
-
|
|
1635
|
-
expect(() => {
|
|
1636
|
-
new OverlayController({
|
|
1637
|
-
...withLocalTestConfig(),
|
|
1638
|
-
contentNode,
|
|
1639
|
-
});
|
|
1640
|
-
}).to.throw(
|
|
1641
|
-
'[OverlayController] You need to provide a .contentWrapperNode when .contentNode is projected',
|
|
1642
|
-
);
|
|
1643
|
-
});
|
|
1644
|
-
|
|
1645
|
-
it('throws if placementMode is global for a tooltip', async () => {
|
|
1646
|
-
const contentNode = document.createElement('div');
|
|
1647
|
-
document.body.appendChild(contentNode);
|
|
1648
|
-
expect(() => {
|
|
1649
|
-
new OverlayController({
|
|
1650
|
-
placementMode: 'global',
|
|
1651
|
-
contentNode,
|
|
1652
|
-
isTooltip: true,
|
|
1653
|
-
handlesAccessibility: true,
|
|
1654
|
-
});
|
|
1655
|
-
}).to.throw(
|
|
1656
|
-
'[OverlayController] .isTooltip should be configured with .placementMode "local"',
|
|
1657
|
-
);
|
|
1658
|
-
});
|
|
1659
|
-
|
|
1660
1693
|
it('throws if handlesAccessibility is false for a tooltip', async () => {
|
|
1661
1694
|
const contentNode = document.createElement('div');
|
|
1662
1695
|
document.body.appendChild(contentNode);
|