import { RefObject } from 'react'; /** * Escape closes a dropdown inside the assistant panel — and closes ONLY it. * * ★★★ WHY CAPTURE. Both dropdowns used to listen on `window` in the bubble * phase. `window` is the LAST node an event reaches, so the panel's own * shortcut hook — on `document`, also bubbling — always ran first, saw focus * inside the panel, found no full-surface overlay open, and closed the WHOLE * assistant. One press dismissed a dropdown and destroyed the streaming turn, * the draft and the attachments; this handler then ran on an unmounted * component. Capture on `document` reaches this node ahead of every bubble * listener on it, whatever order they registered in — the only placement that * reliably wins. * * ★★★ WHY IT IS STILL SCOPED TO FOCUS. Consuming Escape unconditionally while * open is the same mistake pointing the other way: the dropdown stays mounted * when focus leaves it without a click (open it from the keyboard, Tab to the * transcript toggle, press Enter), and it would then swallow an Escape meant * for the layer the user actually opened last, closing a menu they cannot even * see. So the key is taken only while focus is still inside the menu or on its * trigger — the same containment question `focusIsInsidePanel` answers for the * panel, and the same one this component's outside-click handler already asks. * * ★ `stopPropagation`, NOT `stopImmediatePropagation`: stopping in the capture * phase already prevents every bubble listener from seeing the key. The * immediate variant would additionally kill unrelated capture listeners on * `document`, which are none of a dropdown's business. * * Shared by `AssistantMoreMenu` and `AssistantAttachmentButton` so the rule * lives in one place — the two copies had drifted into being identical * comment-for-comment, which is a third copy waiting to happen. */ export declare function useDropdownEscape(open: boolean, menuRef: RefObject, buttonRef: RefObject, close: () => void): void; //# sourceMappingURL=useDropdownEscape.d.ts.map