From 8fda9aed717d8e2d01668d5bdd8d7072a03efcc9 Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Wed, 4 Feb 2026 14:20:50 +0000 Subject: [PATCH] fix(ui): focus prompt on session activate --- .../src/components/session/session-view.tsx | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/packages/ui/src/components/session/session-view.tsx b/packages/ui/src/components/session/session-view.tsx index df0e6bc1..b75dd046 100644 --- a/packages/ui/src/components/session/session-view.tsx +++ b/packages/ui/src/components/session/session-view.tsx @@ -1,4 +1,4 @@ -import { Show, For, createMemo, createEffect, type Component } from "solid-js" +import { Show, For, createMemo, createEffect, on, type Component } from "solid-js" import { Expand } from "lucide-solid" import type { Session } from "../../types/session" import type { Attachment } from "../../types/attachment" @@ -112,6 +112,43 @@ export const SessionView: Component = (props) => { if (!props.isActive) return scheduleScrollToBottom() }) + + createEffect( + on( + () => props.isActive, + (isActive) => { + if (!isActive) return + + // Don't steal focus from other inputs (command palette, dialogs, selectors, etc.) + if (typeof document === "undefined") return + const activeEl = document.activeElement as HTMLElement | null + const activeIsInput = + activeEl?.tagName === "INPUT" || + activeEl?.tagName === "TEXTAREA" || + activeEl?.tagName === "SELECT" || + Boolean(activeEl?.isContentEditable) + if (activeIsInput) return + + const modalOpen = Boolean(document.querySelector('[role="dialog"][aria-modal="true"]')) + if (modalOpen) return + + // Defer until the session pane is visible and the textarea is mounted. + requestAnimationFrame(() => { + requestAnimationFrame(() => { + const textarea = rootRef?.querySelector(".prompt-input") + if (!textarea) return + if (textarea.disabled) return + + try { + textarea.focus({ preventScroll: true } as any) + } catch { + textarea.focus() + } + }) + }) + }, + ), + ) let quoteHandler: ((text: string, mode: "quote" | "code") => void) | null = null createEffect(() => {