fix: make sure that voiceover + safari modals are accessible
This commit is contained in:
parent
6d2e9975af
commit
382a9aab64
3 changed files with 41 additions and 3 deletions
5
.changeset/wise-mirrors-grab.md
Normal file
5
.changeset/wise-mirrors-grab.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'@lion/ui': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
make sure that voiceover + safari modals are accessible
|
||||||
|
|
@ -1121,6 +1121,15 @@ export class OverlayController extends EventTarget {
|
||||||
if (this.manager) {
|
if (this.manager) {
|
||||||
this.manager.disableTrapsKeyboardFocusForAll();
|
this.manager.disableTrapsKeyboardFocusForAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isContentShadowHost = Boolean(this.contentNode.shadowRoot);
|
||||||
|
if (isContentShadowHost) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.warn(
|
||||||
|
'[overlays]: For best accessibility (compatibility with Safari + VoiceOver), provide a contentNode that is not a host for a shadow root',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this._containFocusHandler = containFocus(this.contentNode);
|
this._containFocusHandler = containFocus(this.contentNode);
|
||||||
this.__hasActiveTrapsKeyboardFocus = true;
|
this.__hasActiveTrapsKeyboardFocus = true;
|
||||||
if (this.manager) {
|
if (this.manager) {
|
||||||
|
|
|
||||||
|
|
@ -603,8 +603,8 @@ describe('OverlayController', () => {
|
||||||
event.keyCode = keyCodes.tab;
|
event.keyCode = keyCodes.tab;
|
||||||
window.dispatchEvent(event);
|
window.dispatchEvent(event);
|
||||||
|
|
||||||
expect(elOutside).to.not.equal(document.activeElement);
|
expect(isActiveElement(elOutside)).to.be.false;
|
||||||
expect(input1).to.equal(document.activeElement);
|
expect(isActiveElement(input1)).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('allows to move the focus outside of the overlay if trapsKeyboardFocus is disabled', async () => {
|
it('allows to move the focus outside of the overlay if trapsKeyboardFocus is disabled', async () => {
|
||||||
|
|
@ -625,7 +625,7 @@ describe('OverlayController', () => {
|
||||||
input.focus();
|
input.focus();
|
||||||
simulateTab();
|
simulateTab();
|
||||||
|
|
||||||
expect(elOutside).to.equal(document.activeElement);
|
expect(isActiveElement(elOutside)).to.be.true;
|
||||||
});
|
});
|
||||||
|
|
||||||
it('keeps focus within overlay with multiple overlays with all traps on true', async () => {
|
it('keeps focus within overlay with multiple overlays with all traps on true', async () => {
|
||||||
|
|
@ -648,6 +648,30 @@ describe('OverlayController', () => {
|
||||||
expect(ctrl0.hasActiveTrapsKeyboardFocus).to.be.true;
|
expect(ctrl0.hasActiveTrapsKeyboardFocus).to.be.true;
|
||||||
expect(ctrl1.hasActiveTrapsKeyboardFocus).to.be.false;
|
expect(ctrl1.hasActiveTrapsKeyboardFocus).to.be.false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('warns when contentNode is a host for a shadowRoot', async () => {
|
||||||
|
const warnSpy = sinon.spy(console, 'warn');
|
||||||
|
|
||||||
|
const contentNode = /** @type {HTMLDivElement} */ (await fixture(html` <div></div> `));
|
||||||
|
contentNode.attachShadow({ mode: 'open' });
|
||||||
|
const shadowRootContentNode = /** @type {HTMLElement} */ (
|
||||||
|
await fixture(html` <div><input id="input1" /><input id="input2" /></div> `)
|
||||||
|
);
|
||||||
|
contentNode.shadowRoot?.appendChild(shadowRootContentNode);
|
||||||
|
|
||||||
|
const ctrl = new OverlayController({
|
||||||
|
...withGlobalTestConfig(),
|
||||||
|
trapsKeyboardFocus: true,
|
||||||
|
contentNode,
|
||||||
|
});
|
||||||
|
await ctrl.show();
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
|
expect(console.warn.args[0][0]).to.equal(
|
||||||
|
'[overlays]: For best accessibility (compatibility with Safari + VoiceOver), provide a contentNode that is not a host for a shadow root',
|
||||||
|
);
|
||||||
|
warnSpy.restore();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('hidesOnEsc', () => {
|
describe('hidesOnEsc', () => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue