UNPKG

@adonis-agora/agent

Version:

Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.

48 lines • 1.91 kB
import { useCallback, useEffect, useRef, useState } from 'react'; /** * Follow a streaming transcript only while the reader is already at the bottom. Reading back * through history during a stream is the case this exists for: an unconditional scroll-to-bottom * yanks the viewport away mid-sentence on every token. */ export function useStickToBottom({ contentKey, threshold = 32, }) { const containerRef = useRef(null); const [isAtBottom, setIsAtBottom] = useState(true); const measure = useCallback(() => { const element = containerRef.current; if (!element) { return; } const distance = element.scrollHeight - element.scrollTop - element.clientHeight; setIsAtBottom(distance <= threshold); }, [threshold]); const scrollToBottom = useCallback(() => { const element = containerRef.current; if (!element) { return; } element.scrollTop = element.scrollHeight; setIsAtBottom(true); }, []); const setContainer = useCallback((element) => { containerRef.current = element; if (element) { measure(); } }, [measure]); // Re-pin as content arrives. Guarded on `isAtBottom` so a reader who scrolled up keeps their // position for the rest of the stream, and re-pins the moment they scroll back down. // biome-ignore lint/correctness/useExhaustiveDependencies: `contentKey` IS the content dependency useEffect(() => { if (isAtBottom) { scrollToBottom(); } }, [contentKey, isAtBottom, scrollToBottom]); const getContainerProps = useCallback(() => ({ ref: setContainer, onScroll: measure }), [setContainer, measure]); return { isAtBottom, showJumpToLatest: !isAtBottom, scrollToBottom, getContainerProps, }; } //# sourceMappingURL=use-stick-to-bottom.js.map