webui: rotating with a sheet open must not inert-lock the page

The mobile sheets are native modal dialogs now, and above 700px their
CSS hides them -- but showModal() keeps the rest of the page inert
regardless of the dialog's display: rotating a phone to landscape with
a sheet open left the whole UI untappable, with no visible dialog and
no Escape on touch, until rotating back. Crossing into the desktop
layout now closes the sheet.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
jolavillette 2026-09-10 21:54:17 +02:00
parent e0b226c0b8
commit 2fe6ea2407

View File

@ -4,16 +4,38 @@ const m = require('mithril');
// and provide dialog semantics; callers own the open state and sheet content.
const Dialog = () => {
let opener;
let onclose = () => { };
let desktopQuery;
let onLayoutChange;
return {
oncreate: ({ dom }) => {
opener = document.activeElement;
dom.showModal();
// The sheets are phone chrome: above 700px their CSS hides the dialog,
// but showModal() keeps the whole page inert regardless -- rotating to
// landscape with a sheet open left the UI untappable with no visible
// way out. Crossing into the desktop layout closes the sheet instead.
desktopQuery = window.matchMedia('(min-width: 701px)');
onLayoutChange = (event) => {
if (event.matches) {
onclose();
m.redraw();
}
};
if (desktopQuery.addEventListener) desktopQuery.addEventListener('change', onLayoutChange);
else desktopQuery.addListener(onLayoutChange);
},
onremove: ({ dom }) => {
if (desktopQuery && onLayoutChange) {
if (desktopQuery.removeEventListener) desktopQuery.removeEventListener('change', onLayoutChange);
else desktopQuery.removeListener(onLayoutChange);
}
dom.close();
if (opener && opener.isConnected) opener.focus();
},
view: ({ attrs, children }) => m('dialog.accessible-dialog', {
view: ({ attrs, children }) => {
onclose = attrs.onclose;
return m('dialog.accessible-dialog', {
class: attrs.overlayClass,
'aria-label': attrs.label,
'aria-modal': 'true',
@ -44,7 +66,8 @@ const Dialog = () => {
first.focus();
}
},
}, m('div', { class: attrs.sheetClass }, children)),
}, m('div', { class: attrs.sheetClass }, children));
},
};
};