mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
8e7b5ce300
* feat(review): refine Call Flow navigation and annotations * fix(review): align viewed controls with panel navigation * feat(review): add Call Flow path search controls * fix(ui): wrap long tooltip identifiers * feat(review): annotate raw Call Flow output * feat(review): refine call flow lens context * fix(review): keep call flow lens search accessible * fix(review): scope call flow find shortcuts
51 lines
1.6 KiB
TypeScript
51 lines
1.6 KiB
TypeScript
import { useEffect, type RefObject } from 'react';
|
|
|
|
export type CallFlowFindShortcutSurface = 'dock' | 'lens';
|
|
|
|
/**
|
|
* Gives Cmd/Ctrl+F to exactly one visible Call Flow search surface.
|
|
*
|
|
* Dockview retains inactive panel portals, so mount state is never sufficient
|
|
* proof of ownership. Callers must pass the Dockview active-panel state for a
|
|
* Dock surface or the Popover open state for a Lens surface. An open Lens wins
|
|
* over the Dock because it is the foreground interaction surface.
|
|
*/
|
|
export function useCallFlowFindShortcut({
|
|
active,
|
|
surface,
|
|
searchOpen,
|
|
inputRef,
|
|
openSearch,
|
|
}: {
|
|
readonly active: boolean;
|
|
readonly surface: CallFlowFindShortcutSurface;
|
|
readonly searchOpen: boolean;
|
|
readonly inputRef: RefObject<HTMLInputElement | null>;
|
|
readonly openSearch: () => void;
|
|
}): void {
|
|
useEffect(() => {
|
|
if (!active) return;
|
|
const onFind = (event: KeyboardEvent) => {
|
|
if (
|
|
!(event.metaKey || event.ctrlKey)
|
|
|| event.shiftKey
|
|
|| event.altKey
|
|
|| event.key.toLocaleLowerCase() !== 'f'
|
|
) return;
|
|
if (document.visibilityState === 'hidden') return;
|
|
if (surface === 'dock' && document.querySelector('[data-call-flow-lens="true"]')) return;
|
|
|
|
event.preventDefault();
|
|
event.stopImmediatePropagation();
|
|
if (searchOpen) {
|
|
inputRef.current?.focus();
|
|
inputRef.current?.select();
|
|
return;
|
|
}
|
|
openSearch();
|
|
};
|
|
window.addEventListener('keydown', onFind, { capture: true });
|
|
return () => window.removeEventListener('keydown', onFind, { capture: true });
|
|
}, [active, inputRef, openSearch, searchOpen, surface]);
|
|
}
|