Skip to content

Commit 7c72ee7

Browse files
authored
Prevent event propagation when in SelectPanel (#3700)
1 parent c132e30 commit 7c72ee7

3 files changed

Lines changed: 46 additions & 1 deletion

File tree

.changeset/proud-baths-brake.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@primer/view-components': minor
3+
---
4+
5+
SelectPanel: Prevents `keydown` events from escaping the SelectPanel when within the items.

app/components/primer/alpha/select_panel_element.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,18 @@ export class SelectPanelElement extends HTMLElement {
449449
return
450450
}
451451

452+
if (
453+
event.type === 'keydown' &&
454+
event instanceof KeyboardEvent &&
455+
(event.target as Element).closest(visibleMenuItemSelectors)
456+
) {
457+
const hasModifier = event.ctrlKey || event.altKey || event.metaKey
458+
const isAlphabetKey = event.key.length === 1 && /[a-z\d]/i.test(event.key)
459+
460+
// eslint-disable-next-line no-restricted-syntax
461+
if (!hasModifier && isAlphabetKey) event.stopPropagation()
462+
}
463+
452464
if (event.target === this.dialog && event.type === 'close') {
453465
// Remove data-ready so it can be set the next time the panel is opened
454466
this.dialog.removeAttribute('data-ready')

test/system/alpha/select_panel_test.rb

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1365,5 +1365,33 @@ def test_announces_error_on_filter_failure
13651365
end
13661366
end
13671367
end
1368+
1369+
def test_prevents_events_from_bubbling
1370+
visit_preview(:default)
1371+
1372+
click_on_invoker_button
1373+
1374+
keyboard.type(:tab)
1375+
1376+
evaluate_multiline_script(<<~JS)
1377+
document.body.addEventListener('keydown', (event) => {
1378+
window.bodyKeydownFired = true
1379+
}, { once: true })
1380+
JS
1381+
1382+
assert_includes active_element.text, "Item 1"
1383+
1384+
keyboard.type("a") # type an alphabetic key, which should be stopped from propagating
1385+
1386+
refute page.evaluate_script("window.bodyKeydownFired")
1387+
1388+
keyboard.type(:escape) # close the panel
1389+
1390+
refute_selector "select-panel dialog[open]"
1391+
1392+
keyboard.type("a")
1393+
1394+
assert page.evaluate_script("window.bodyKeydownFired")
1395+
end
13681396
end
1369-
end
1397+
end

0 commit comments

Comments
 (0)