mirror of
https://github.com/shoelace-style/shoelace.git
synced 2026-01-12 11:09:13 +00:00
fix nested dialog focus
This commit is contained in:
@@ -63,11 +63,13 @@ export default class Modal {
|
||||
}
|
||||
|
||||
private handleFocusIn = () => {
|
||||
if (!this.isActive()) return
|
||||
this.checkFocus();
|
||||
};
|
||||
|
||||
private handleKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.key !== 'Tab' || this.isExternalActivated) return;
|
||||
if (!this.isActive()) return
|
||||
|
||||
if (event.shiftKey) {
|
||||
this.tabDirection = 'backward';
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { elementUpdated, expect, fixture } from '@open-wc/testing';
|
||||
import { aTimeout, elementUpdated, expect, fixture } from '@open-wc/testing';
|
||||
|
||||
import '../../dist/shoelace.js';
|
||||
import { activeElements, getDeepestActiveElement } from './active-elements.js';
|
||||
import { html } from 'lit';
|
||||
import { sendKeys } from '@web/test-runner-commands';
|
||||
import { SlDialog } from '../../dist/shoelace.js';
|
||||
import { clickOnElement } from './test.js';
|
||||
|
||||
async function holdShiftKey(callback: () => Promise<void>) {
|
||||
await sendKeys({ down: 'Shift' });
|
||||
@@ -174,3 +176,45 @@ it('Should account for when focus is changed from outside sources (like clicking
|
||||
await holdShiftKey(async () => await sendKeys({ press: tabKey }));
|
||||
expect(activeElementsArray()).to.include(closeButton);
|
||||
});
|
||||
|
||||
// https://github.com/shoelace-style/shoelace/issues/1710
|
||||
it("Should respect nested modal instances", async () => {
|
||||
const dialogOne = () => document.querySelector("#dialog-1") as SlDialog
|
||||
const dialogTwo = () => document.querySelector("#dialog-2") as SlDialog
|
||||
|
||||
await fixture(html`
|
||||
<div>
|
||||
<sl-button id="open-dialog-1" @click=${() => dialogOne().show()}></sl-button>
|
||||
<sl-dialog id="dialog-1" label="Dialog 1">
|
||||
<sl-button @click=${() => dialogTwo().show()} id="open-dialog-2">Open Dialog 2</sl-button>
|
||||
<sl-button slot="footer" variant="primary">Close</sl-button>
|
||||
</sl-dialog>
|
||||
|
||||
<sl-dialog id="dialog-2" label="Dialog 2">
|
||||
<sl-input
|
||||
id="focus-1"
|
||||
autofocus=""
|
||||
placeholder="I will have focus when the dialog is opened"
|
||||
></sl-input>
|
||||
<sl-input id="focus-2" placeholder="Second input"></sl-input>
|
||||
<sl-button slot="footer" variant="primary" class="close-2">Close</sl-button>
|
||||
</sl-dialog>
|
||||
</div>
|
||||
`)
|
||||
|
||||
const firstFocusedEl = document.querySelector("#focus-1")
|
||||
const secondFocusedEl = document.querySelector("#focus-2")
|
||||
|
||||
// So we can trigger auto-focus stuff
|
||||
await clickOnElement(document.querySelector("#open-dialog-1") as Element)
|
||||
// These clicks need a ~10ms timeout. Not sure why, if we don't do this, tests get flaky.
|
||||
await aTimeout(100)
|
||||
await clickOnElement(document.querySelector("#open-dialog-2") as Element)
|
||||
await aTimeout(100)
|
||||
|
||||
expect(activeElementsArray()).to.include(firstFocusedEl)
|
||||
|
||||
await sendKeys({ press: tabKey })
|
||||
expect(activeElementsArray()).to.include(secondFocusedEl)
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user