Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | import { useRef, useEffect, useCallback } from 'react' /** * Keeps a chat input focused across send → stream → idle cycles. * * When `disabled={isStreaming}` kicks in, the browser blurs the input. * This hook snapshots whether the input had focus before the send, * then restores focus once streaming finishes. * * Also provides `preventFocusLoss` — put it on `onMouseDown` of buttons * (like the send button) that should not steal focus from the input. */ export function useChatInputFocus( inputRef: React.RefObject<HTMLInputElement | null>, isStreaming: boolean ) { const hadFocusRef = useRef(false) /** Call right before sending to snapshot the focus state. */ const markFocusBeforeSend = useCallback(() => { if (inputRef.current && document.activeElement === inputRef.current) { hadFocusRef.current = true } }, [inputRef]) /** Put on `onMouseDown` of the send button to prevent it from stealing focus. */ const preventFocusLoss = useCallback((e: React.MouseEvent) => { e.preventDefault() }, []) // Restore focus when streaming ends useEffect(() => { if (!isStreaming && hadFocusRef.current) { hadFocusRef.current = false requestAnimationFrame(() => inputRef.current?.focus()) } }, [isStreaming, inputRef]) return { markFocusBeforeSend, preventFocusLoss } } |