fix(a11y): guard sidebar-toggle keypress against custom widgets and scope transcript font-size effect

- Extend isInputFocused to also bail when document.activeElement sits
  inside a custom widget with role combobox/listbox/radio/switch/menuitem/tab
  so single-letter shortcuts like '[' do not collapse the sidebar while
  focused on SegmentedButton, ZonePicker, etc.
- Move the transcript font-size CSS variable write from documentElement
  to document.body. Consumers inherit body styles, and scoping the write
  there avoids invalidating root-level styles every time fontSize changes.
This commit is contained in:
2026-05-07 11:27:42 +01:00
parent 736896c2b8
commit f4c0635549

View File

@@ -182,15 +182,31 @@
} }
}); });
// Apply font size setting as CSS variable (legacy kept for backwards compat) // Apply font size setting as CSS variable (legacy, kept for backwards compat).
// Scoped to <body> rather than documentElement so the write only invalidates
// styles on the body subtree (transcript surfaces inherit from body anyway).
$effect(() => { $effect(() => {
document.documentElement.style.setProperty("--font-size-transcript", `${settings.fontSize}px`); document.body.style.setProperty("--font-size-transcript", `${settings.fontSize}px`);
}); });
// Check whether the keydown originates from a text input (avoid triggering while typing) // Custom widgets that should swallow single-letter shortcuts so they don't
// accidentally trigger global hotkeys while focused.
const CUSTOM_WIDGET_SELECTOR =
'[role="combobox"], [role="listbox"], [role="radio"], [role="switch"], [role="menuitem"], [role="tab"]';
// Check whether the keydown originates from a text input or custom widget
// (avoid triggering shortcuts while typing or while focus sits in a
// SegmentedButton, ZonePicker, or similar ARIA-roled control).
function isInputFocused(e) { function isInputFocused(e) {
const tag = e.target?.tagName; const tag = e.target?.tagName;
return tag === "INPUT" || tag === "TEXTAREA" || e.target?.isContentEditable; if (tag === "INPUT" || tag === "TEXTAREA" || e.target?.isContentEditable) {
return true;
}
const active = document.activeElement;
if (active && typeof active.closest === "function" && active.closest(CUSTOM_WIDGET_SELECTOR)) {
return true;
}
return false;
} }
function handleKeydown(e) { function handleKeydown(e) {