Files
MyIP/frontend/composables/use-overlay-shortcuts.js
Claude 96525d2fc7 Chore: trim the branch — leftovers, redundancy, comments
A pass over every file the branch touched, after the iOS animation hunt
left tries and reverts behind it. Removed what nothing reaches: the
view-transition rule for a transition no code starts, an unreachable
guard in the transition hook, a no-op KeepAlive key branch, a sign-in
guard the menu already enforces, usage-dialog wrappers that only
forwarded to the store, a duplicated modifier-click check and card
filter (isPlainClick / listedTools), a test that hand-rolled
listedTools, a drawer-era fixture parameter. auth-flow.js folded into
auth-redirect.js. Comments cut to what the code cannot say itself —
file headers of a few lines, the measured iOS reasons, non-obvious
orderings — and stale ones fixed (Nav under KeepAlive, Home.vue
reusing DEFAULT_META, "from Nav", enabledCards). AGENTS.md sections
tightened to the code as it is now.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GbLTGMZ45MV78qd2tHoco
2026-10-05 16:50:16 +00:00

43 lines
1.7 KiB
JavaScript

// Suspends the global keyboard shortcuts while an overlay is open.
//
// Called from the `ui/` overlay roots (Dialog / Sheet / Drawer) rather than
// from their callers, so every overlay built on them is covered without any
// per-component wiring — including ones no shortcut opens. Esc and the native
// scrolling keys still work: reka-ui / vaul and the browser own those.
//
// Sync flush on purpose: a keystroke arriving in the same tick as the open
// flip must already see the overlay.
//
// An overlay on a kept-alive page counts only while that page is on screen, and
// is closed when the page is left: its <body> portal would outlive it.
import { getCurrentInstance, getCurrentScope, onDeactivated, onScopeDispose, toValue, watch } from 'vue';
import { openOverlay, closeOverlay } from '@/utils/shortcut.js';
import { useRouteActive } from './use-route-active.js';
export const useOverlayShortcuts = (isOpen) => {
let counted = false;
const sync = (open) => {
const next = Boolean(open);
if (next === counted) return;
counted = next;
(next ? openOverlay : closeOverlay)();
};
const active = useRouteActive();
watch(() => active.value && toValue(isOpen), sync, { immediate: true, flush: 'sync' });
// The root declares `update:open`, so its v-model / handler closes it.
const instance = getCurrentInstance();
if (instance) {
onDeactivated(() => {
if (toValue(isOpen)) instance.emit('update:open', false);
});
}
// An overlay torn down while still open (its parent unmounting) never
// flips `open` back to false — release the count here instead of leaking.
if (getCurrentScope()) onScopeDispose(() => sync(false));
};