fix: light dismiss for header menu/search overlays (outside tap closes, never activates)
This commit is contained in:
+28
-4
@@ -110,11 +110,35 @@ const links = [
|
||||
<script is:inline>
|
||||
// Header search suggestions (desktop field + mobile reveal); the forms
|
||||
// are plain GET /search, so everything below is progressive enhancement.
|
||||
newsSearch({ input: 'hdr-q', list: 'hdr-suggest', status: 'hdr-suggest-status', limit: 6, unit: 'suggestion' });
|
||||
newsSearch({ input: 'pop-q', list: 'pop-suggest', status: 'pop-suggest-status', limit: 6, unit: 'suggestion' });
|
||||
newsSearch({ input: 'hdr-q', list: 'hdr-suggest', status: 'hdr-suggest-status', limit: 6, unit: 'suggestion', dismiss: true });
|
||||
newsSearch({ input: 'pop-q', list: 'pop-suggest', status: 'pop-suggest-status', limit: 6, unit: 'suggestion', dismiss: true });
|
||||
var pop = document.querySelector('.search-pop');
|
||||
pop.addEventListener('toggle', function () {
|
||||
if (pop.open) document.getElementById('pop-q').focus();
|
||||
if (pop) pop.addEventListener('toggle', function () {
|
||||
var q = document.getElementById('pop-q');
|
||||
if (pop.open && q) q.focus();
|
||||
});
|
||||
// Light dismiss for the header panels (menu + search reveal) — scrim
|
||||
// convention (Material/iOS, NN/g error prevention): a tap outside an
|
||||
// open panel ONLY closes it and must never activate what's underneath.
|
||||
// <details> has no native light dismiss; the Popover API was evaluated
|
||||
// and rejected here — its light dismiss deliberately lets the outside
|
||||
// click THROUGH (::backdrop is spec-forced pointer-events: none), the
|
||||
// exact behavior research ruled out. Canceling pointerdown doesn't
|
||||
// cancel the later click (Pointer Events spec), hence the click guard.
|
||||
var swallow = false;
|
||||
document.addEventListener('pointerdown', function (e) {
|
||||
var open = document.querySelector('details[name="header-panel"][open]');
|
||||
swallow = !!(open && !open.contains(e.target));
|
||||
if (swallow) { open.open = false; e.preventDefault(); }
|
||||
}, true);
|
||||
document.addEventListener('click', function (e) {
|
||||
if (swallow) { swallow = false; e.preventDefault(); e.stopPropagation(); }
|
||||
}, true);
|
||||
// Escape closes the open panel and returns focus to its trigger button
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.key !== 'Escape') return;
|
||||
var open = document.querySelector('details[name="header-panel"][open]');
|
||||
if (open) { open.open = false; open.querySelector('summary').focus(); }
|
||||
});
|
||||
</script>
|
||||
<main id="main">
|
||||
|
||||
Reference in New Issue
Block a user