fix(ui): read panel keys at window capture so tasks cannot eat tab

This commit is contained in:
hh committed 2026-09-01 00:11:09 +02:00
1 parent d692dff19a
commit 0cc4655f9f
1 file changed
+11 -2
+11 -2
View File
@@ -51,6 +51,7 @@
function mount(node: HTMLElement) {
panel = node;
const win = node.ownerDocument.defaultView ?? window;
measure();
if (autofocus) {
(node.querySelector<HTMLElement>("input") ?? node).focus({
@@ -64,17 +65,27 @@
const reflow = (): void => measure();
document.addEventListener("pointerdown", outside, true);
window.addEventListener("resize", reflow);
win.addEventListener("keydown", keys, true);
return {
destroy() {
document.removeEventListener("pointerdown", outside, true);
window.removeEventListener("resize", reflow);
win.removeEventListener("keydown", keys, true);
panel = null;
},
};
}
/**
* Read at the window's capture phase rather than on the panel itself.
* Obsidian's keymap listens there first, and a plugin that claims a key
* through `app.scope` — Tasks claims Tab — stops the event before it ever
* reaches an element handler. A listener on the same node still runs after
* that, so this is the one place the panel's keys cannot be taken away.
*/
function keys(event: KeyboardEvent): void {
if (!panel?.contains(event.target as Node)) return;
event.stopPropagation();
if (event.key === "Escape" && !event.defaultPrevented) {
event.preventDefault();
@@ -91,13 +102,11 @@
</script>
<Portal to={view.portal()}>
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
<div
class={cn(
"fixed z-50 overflow-hidden rounded-xl border border-border bg-popover text-popover-foreground shadow-[0_16px_40px_-12px_rgb(0_0_0/45%)] outline-none",
className,
)}
onkeydown={keys}
role="dialog"
style="top: {at.top}px; left: {at.left}px; opacity: {placed ? 1 : 0}"
tabindex="-1"