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

Commit 6357225

Browse files
authored
Merge pull request #71 from seanpdoyle/method-dialog-dismiss
Support `method="dialog"` dismissal
2 parents a24a79c + 2aa3a08 commit 6357225

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ If the `preload` attribute is present, hovering over the `<details>` element wil
6060
`details-dialog-close` event is fired from `<details-dialog>` when a request to close the dialog is made from
6161
6262
- pressing <kbd>escape</kbd>,
63-
- clicking on `summary, [data-close-dialog]`, or
63+
- submitting a `form[method="dialog"]`
64+
- clicking on `summary, form button[formmethod="dialog"], [data-close-dialog]`, or
6465
- `dialog.toggle(false)`
6566
6667
This event bubbles, and can be canceled to keep the dialog open.

src/index.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ type Disableable = HTMLButtonElement | HTMLInputElement | HTMLTextAreaElement |
77

88
type Focusable = HTMLElement
99

10+
type SubmitEvent = Event & { submitter: Element | null }
11+
1012
function autofocus(el: DetailsDialogElement): void {
1113
let autofocusElement = Array.from(el.querySelectorAll<HTMLElement>('[autofocus]')).filter(focusable)[0]
1214
if (!autofocusElement) {
@@ -197,6 +199,22 @@ class DetailsDialogElement extends HTMLElement {
197199
toggleDetails(details, false)
198200
}
199201
})
202+
this.addEventListener('submit', function(event: Event) {
203+
if (!(event.target instanceof HTMLFormElement)) return
204+
205+
const {target} = event
206+
const submitEvent = 'submitter' in event ? event as SubmitEvent : null
207+
const submitter = submitEvent?.submitter
208+
const method = submitter?.getAttribute('formmethod') || target.getAttribute('method')
209+
210+
if (method == 'dialog') {
211+
event.preventDefault()
212+
const details = target.closest('details')
213+
if (details) {
214+
toggleDetails(details, false)
215+
}
216+
}
217+
})
200218
}
201219

202220
get src(): string | null {

test/test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ describe('details-dialog-element', function() {
3131
<button hidden>hidden</button>
3232
<div hidden><button>hidden</button></div>
3333
<details><button>Button in closed details</button></details>
34+
<form method="dialog"><button id="method-dialog">method=dialog</button></form>
35+
<form><button id="formmethod-dialog" formmethod="dialog">formmethod=dialog</button></form>
3436
<button ${CLOSE_ATTR}>Goodbye</button>
3537
</details-dialog>
3638
</details>
@@ -96,6 +98,10 @@ describe('details-dialog-element', function() {
9698
triggerKeydownEvent(details, 'Tab')
9799
assert.equal(document.activeElement, document.querySelector(`[data-button]`))
98100
triggerKeydownEvent(details, 'Tab')
101+
assert.equal(document.activeElement, document.querySelector(`form[method="dialog"] button`))
102+
triggerKeydownEvent(details, 'Tab')
103+
assert.equal(document.activeElement, document.querySelector(`[formmethod="dialog"]`))
104+
triggerKeydownEvent(details, 'Tab')
99105
assert.equal(document.activeElement, document.querySelector(`[${CLOSE_ATTR}]`))
100106
})
101107

@@ -199,6 +205,14 @@ describe('details-dialog-element', function() {
199205
assert(details.open)
200206
close.click()
201207
assert(!details.open)
208+
dialog.toggle(true)
209+
assert(details.open)
210+
dialog.querySelector('#method-dialog').click()
211+
assert(!details.open)
212+
dialog.toggle(true)
213+
assert(details.open)
214+
dialog.querySelector('#formmethod-dialog').click()
215+
assert(!details.open)
202216
})
203217

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

0 commit comments

Comments
 (0)