feat(terminal): focus management — terminal on open, composer on close

- Opening terminal: xterm.focus() called after fit in the visibility effect
- Closing terminal: ProseMirror editor focused via querySelector after rAF
- Works for all paths: pill click, ⌘+J toggle, trash icon kill
This commit is contained in:
Taylor Ho
2026-05-21 23:48:10 -07:00
parent 49eb06756e
commit 8d5987cdd4
2 changed files with 17 additions and 1 deletions

View File

@@ -35,6 +35,21 @@ export function TerminalProvider({ children }: { children: React.ReactNode }) {
};
}, []);
// Focus management: return focus to composer when terminal closes.
const prevOpenRef = React.useRef(isOpen);
React.useEffect(() => {
if (prevOpenRef.current && !isOpen) {
// Terminal just closed — focus the composer.
requestAnimationFrame(() => {
const editor = document.querySelector<HTMLElement>(
'[data-testid="message-composer"] .ProseMirror',
);
editor?.focus();
});
}
prevOpenRef.current = isOpen;
}, [isOpen]);
const value = React.useMemo(
() => ({ isOpen, toggle, close }),
[isOpen, toggle, close],

View File

@@ -212,11 +212,12 @@ export function TerminalInstance({
};
}, [channelId, isVisible]);
// Re-fit when visibility changes.
// Re-fit and focus when visibility changes.
React.useEffect(() => {
if (isVisible && fitAddonRef.current) {
requestAnimationFrame(() => {
fitAddonRef.current?.fit();
termRef.current?.focus();
if (sessionIdRef.current && termRef.current) {
invoke("terminal_resize", {
input: {