Skip to content
This repository has been archived by the owner on Sep 22, 2022. It is now read-only.

Commit

Permalink
Support method="dialog" dismissal
Browse files Browse the repository at this point in the history
The `<dialog>` element specifications support dismissing an open element
by submitting a `<form method="dialog">` or by submitting a `<form>`
with a `<button formmethod="dialog">` element.

This commit adds support for either of those methods as an alternative
to a `<button type="button" data-dialog-close>` element.

[method="dialog"]: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog#usage_notes
  • Loading branch information
seanpdoyle committed Sep 15, 2021
1 parent c28aa05 commit 71d937e
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
17 changes: 17 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ type Disableable = HTMLButtonElement | HTMLInputElement | HTMLTextAreaElement |

type Focusable = HTMLElement

type SubmitEvent = Event & { submitter: Element }

function autofocus(el: DetailsDialogElement): void {
let autofocusElement = Array.from(el.querySelectorAll<HTMLElement>('[autofocus]')).filter(focusable)[0]
if (!autofocusElement) {
Expand Down Expand Up @@ -197,6 +199,21 @@ class DetailsDialogElement extends HTMLElement {
toggleDetails(details, false)
}
})
this.addEventListener('submit', function(event: Event) {
if (!(event.target instanceof HTMLFormElement)) return

const {target} = event
const submitEvent = 'submitter' in event ? event as SubmitEvent : null
const method = submitEvent?.submitter.getAttribute('formmethod') || target.getAttribute('method')

if (method == 'dialog') {
event.preventDefault()
const details = target.closest('details')
if (details) {
toggleDetails(details, false)
}
}
})
}

get src(): string | null {
Expand Down
14 changes: 14 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ describe('details-dialog-element', function() {
<button hidden>hidden</button>
<div hidden><button>hidden</button></div>
<details><button>Button in closed details</button></details>
<form method="dialog"><button id="method-dialog">method=dialog</button></form>
<form><button id="formmethod-dialog" formmethod="dialog">formmethod=dialog</button></form>
<button ${CLOSE_ATTR}>Goodbye</button>
</details-dialog>
</details>
Expand Down Expand Up @@ -96,6 +98,10 @@ describe('details-dialog-element', function() {
triggerKeydownEvent(details, 'Tab')
assert.equal(document.activeElement, document.querySelector(`[data-button]`))
triggerKeydownEvent(details, 'Tab')
assert.equal(document.activeElement, document.querySelector(`form[method="dialog"] button`))
triggerKeydownEvent(details, 'Tab')
assert.equal(document.activeElement, document.querySelector(`[formmethod="dialog"]`))
triggerKeydownEvent(details, 'Tab')
assert.equal(document.activeElement, document.querySelector(`[${CLOSE_ATTR}]`))
})

Expand Down Expand Up @@ -199,6 +205,14 @@ describe('details-dialog-element', function() {
assert(details.open)
close.click()
assert(!details.open)
dialog.toggle(true)
assert(details.open)
dialog.querySelector('#method-dialog').click()
assert(!details.open)
dialog.toggle(true)
assert(details.open)
dialog.querySelector('#formmethod-dialog').click()
assert(!details.open)
})

it('closes when escape key is pressed', async function() {
Expand Down

0 comments on commit 71d937e

Please sign in to comment.