Skip to content

Commit

Permalink
Merge pull request #398 from KittyGiraudel/nested-dialogs
Browse files Browse the repository at this point in the history
Maintain support for nested dialogs in v8
  • Loading branch information
KittyGiraudel authored Aug 17, 2022
2 parents 2f626f2 + a1565c3 commit 7767e32
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 20 deletions.
4 changes: 2 additions & 2 deletions cypress/e2e/nestedDialogs.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ describe('Nested dialogs', () => {
})

it('should close only the top most dialog when pressing ESC', () => {
cy.get('body').trigger('keydown', { key: 'Escape', keyCode: 27, which: 27 })
cy.realPress('Escape')
cy.get('[data-a11y-dialog="dialog-2"]').then(shouldBeVisible)
cy.get('[data-a11y-dialog="dialog-3"]').then(shouldBeHidden)
})

it('should close only the top most dialog when clicking the backdrop', () => {
cy.get('body').trigger('keydown', { key: 'Escape', keyCode: 27, which: 27 })
cy.get('[data-a11y-dialog="dialog-2"]')
.find('.dialog-overlay')
.first()
.click({ force: true })
cy.get('[data-a11y-dialog="dialog-1"]').then(shouldBeVisible)
cy.get('[data-a11y-dialog="dialog-2"]').then(shouldBeHidden)
Expand Down
29 changes: 14 additions & 15 deletions cypress/fixtures/nested-dialogs.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,27 @@ <h1>Tests — Nested dialogs</h1>
<h1 id="dialog-title-1">Dialog 1</h1>
<button class="link-like" data-a11y-dialog-show="dialog-2">Open dialog 2</button>
</div>
</div>

<div class="dialog" data-a11y-dialog="dialog-2" aria-hidden="true" aria-labelledby="dialog-title-2">
<div class="dialog-overlay" data-a11y-dialog-hide></div>
<div role="document" class="dialog-content">
<button data-a11y-dialog-hide class="dialog-close" aria-label="Close this dialog window">&times;</button>
<div class="dialog" data-a11y-dialog="dialog-2" aria-hidden="true" aria-labelledby="dialog-title-2">
<div class="dialog-overlay" data-a11y-dialog-hide></div>
<div role="document" class="dialog-content">
<button data-a11y-dialog-hide class="dialog-close" aria-label="Close this dialog window">&times;</button>

<h1 id="dialog-title-2">Dialog 2</h1>
<button class="link-like" data-a11y-dialog-show="dialog-3">Open dialog 3</button>
</div>
</div>
<h1 id="dialog-title-2">Dialog 2</h1>
<button class="link-like" data-a11y-dialog-show="dialog-3">Open dialog 3</button>
</div>

<div class="dialog" data-a11y-dialog="dialog-3" aria-hidden="true" aria-labelledby="dialog-title-3">
<div class="dialog-overlay" data-a11y-dialog-hide></div>
<div role="document" class="dialog-content">
<button data-a11y-dialog-hide class="dialog-close" aria-label="Close this dialog window">&times;</button>
<div class="dialog" data-a11y-dialog="dialog-3" aria-hidden="true" aria-labelledby="dialog-title-3">
<div class="dialog-overlay" data-a11y-dialog-hide></div>
<div role="document" class="dialog-content">
<button data-a11y-dialog-hide class="dialog-close" aria-label="Close this dialog window">&times;</button>

<h1 id="dialog-title-3">Dialog 3</h1>
<h1 id="dialog-title-3">Dialog 3</h1>
</div>
</div>
</div>
</div>


<script src="./a11y-dialog.js"></script>
</body>

Expand Down
1 change: 1 addition & 0 deletions cypress/fixtures/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ dialog[open] {
left: 0;
bottom: 0;
right: 0;
z-index: 2;
}

.dialog {
Expand Down
12 changes: 9 additions & 3 deletions src/a11y-dialog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,9 @@ export default class A11yDialog {
}

if (
target.matches(
`[data-a11y-dialog="${this.id}"] [data-a11y-dialog-hide], #${this.id} [data-a11y-dialog-hide], [data-a11y-dialog-hide="${this.id}"]`
)
target.matches(`[data-a11y-dialog-hide="${this.id}"]`) ||
(target.matches('[data-a11y-dialog-hide]') &&
target.closest('[aria-modal="true"]') === this.$el)
) {
this.hide(event)
}
Expand All @@ -160,6 +160,12 @@ export default class A11yDialog {
* (namely ESC and TAB)
*/
private bindKeypress = (event: KeyboardEvent) => {
// This is an escape hatch in case there are nested open dialogs, so that
// only the top most dialog gets interacted with
if (document.activeElement?.closest('[aria-modal="true"]') !== this.$el) {
return
}

// If the dialog is shown and the ESC key is pressed, prevent any further
// effects from the ESC key and hide the dialog, unless its role is
// `alertdialog`, which should be modal
Expand Down

0 comments on commit 7767e32

Please sign in to comment.