Skip to content

Commit a2d895d

Browse files
authored
Merge pull request #29 from github/radio-events
Fix radio input check triggering multiple details-menu-select events
2 parents 2028b68 + 082851d commit a2d895d

File tree

3 files changed

+25
-21
lines changed

3 files changed

+25
-21
lines changed

index.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,16 @@ function shouldCommit(event: Event) {
169169
// Ignore clicks from nested details.
170170
if (target.closest('details') !== details) return
171171

172-
const menuitem =
173-
event.type === 'change'
174-
? target.closest('[role="menuitemradio"], [role="menuitemcheckbox"]')
175-
: target.closest('[role="menuitem"], [role="menuitemradio"]')
176-
if (menuitem) commit(menuitem, details)
172+
if (event.type === 'click') {
173+
const menuitem = target.closest('[role="menuitem"], [role="menuitemradio"]')
174+
const onlyCommitOnChangeEvent = menuitem && menuitem.tagName === 'LABEL' && menuitem.querySelector('input')
175+
if (menuitem && !onlyCommitOnChangeEvent) {
176+
commit(menuitem, details)
177+
}
178+
} else if (event.type === 'change') {
179+
const menuitem = target.closest('[role="menuitemradio"], [role="menuitemcheckbox"]')
180+
if (menuitem) commit(menuitem, details)
181+
}
177182
}
178183

179184
function updateChecked(selected: Element, details: Element) {

package-lock.json

Lines changed: 5 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/test.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,13 +248,17 @@ describe('details-menu element', function() {
248248
document.body.innerHTML = ''
249249
})
250250

251-
it('manages checked state', function() {
251+
it('manages checked state and fires events', function() {
252252
const details = document.querySelector('details')
253253
const item = details.querySelector('button')
254+
let eventCounter = 0
255+
document.addEventListener('details-menu-selected', () => eventCounter++, true)
256+
254257
assert.equal(item.getAttribute('aria-checked'), 'false')
255258
item.dispatchEvent(new MouseEvent('click', {bubbles: true}))
256259
assert.equal(item.getAttribute('aria-checked'), 'true')
257260
assert.equal(details.querySelectorAll('[aria-checked="true"]').length, 1)
261+
assert.equal(eventCounter, 1, 'selected event is fired once')
258262
})
259263
})
260264

@@ -278,13 +282,17 @@ describe('details-menu element', function() {
278282
document.body.innerHTML = ''
279283
})
280284

281-
it('manages checked state', function() {
285+
it('manages checked state and fires events', function() {
282286
const details = document.querySelector('details')
283287
const item = details.querySelector('label')
288+
let eventCounter = 0
289+
document.addEventListener('details-menu-selected', () => eventCounter++, true)
290+
284291
assert.equal(item.getAttribute('aria-checked'), 'false')
285292
item.dispatchEvent(new MouseEvent('click', {bubbles: true}))
286293
assert.equal(item.getAttribute('aria-checked'), 'true')
287294
assert.equal(details.querySelectorAll('[aria-checked="true"]').length, 1)
295+
assert.equal(eventCounter, 1, 'selected event is fired once')
288296
})
289297
})
290298

0 commit comments

Comments
 (0)