useStickToBottom
AI チャット ボットを念頭に置いて設計され、StackBlitz によるbolt.new
強化
依存性のない 軽量の React フック + コンポーネント。コンテナーの下部に自動的に貼り付けられ、新しいコンテンツが追加されている間、コンテンツをスムーズにアニメーション化して画面上の視覚的な位置を維持します。
特徴 Safari がサポートしていないoverflow-anchor
ブラウザ レベルの CSS サポートは必要ありません。 refs 付きのフックを使用して既存のコンポーネントに接続できます。または、単に提供されたコンポーネントを使用すると、参照が処理され、コンテキストも提供されます。これにより、子コンポーネントはisAtBottom
チェックし、プログラムで一番下までスクロールできます。 最新でありながら十分にサポートされているResizeObserver
API を使用して、コンテンツのサイズ変更を検出します。単に高くなるだけでなく、粘着性を失うことなくコンテンツの縮小をサポートします。 スクロールアンカーを正しく処理します。これは、ビューポート上のコンテンツのサイズが変更されても、現在ビューポートに表示されているコンテンツが上下にジャンプすることを引き起こすものではありません。 ユーザーは上にスクロールすることでいつでもスティッキーをキャンセルできます。賢いロジックにより、ユーザーのスクロールとカスタム アニメーション スクロール イベントが区別されます (一部のイベントが見逃される可能性のあるデバウンスは行われません)。 モバイル デバイスもこのロジックでうまく動作します。 カスタム実装されたスムーズ スクロール アルゴリズムを使用し、速度ベースのスプリング アニメーション (構成可能なパラメーター付き) を特徴とします。他のライブラリでは、代わりに期間を指定したイージング関数を使用しますが、AI チャットボットのユースケースで一般的な、可変サイズの新しいコンテンツをストリーミングする場合、これらはうまく機能しません。 scrollToBottom
スクロールが成功するとすぐにtrue
に解決されるPromise
を返し、スクロールがキャンセルされた場合はfalse
解決されます。
使用法
コンポーネント
{messages.map((message) => (
))}
{/* This component uses `useStickToBottomContext` to scroll to bottom when the user enters a message */}
);
}
function ScrollToBottom() {
const { isAtBottom, scrollToBottom } = useStickToBottomContext();
return (
!isAtBottom && (
scrollToBottom()}
/>
)
);
}"> import { StickToBottom , useStickToBottomContext } from 'use-stick-to-bottom' ;
function Chat ( ) {
return (
< StickToBottom className = "h-[50vh] relative" resize = "smooth" initial = "smooth" >
< StickToBottom . Content className = "flex flex-col gap-4" >
{ messages . map ( ( message ) => (
< Message key = { message . id } message = { message } / >
) ) }
< / StickToBottom . Content >
< ScrollToBottom / >
{ /* This component uses `useStickToBottomContext` to scroll to bottom when the user enters a message */ }
< ChatBox / >
< / StickToBottom >
) ;
}
function ScrollToBottom ( ) {
const { isAtBottom , scrollToBottom } = useStickToBottomContext ( ) ;
return (
! isAtBottom && (
< button
className = "absolute i-ph-arrow-circle-down-fill text-4xl rounded-lg left-[50%] translate-x-[-50%] bottom-0"
onClick = { ( ) => scrollToBottom ( ) }
/ >
)
) ;
}
useStickToBottom
フック import { useStickToBottom } from 'use-stick-to-bottom' ;
function Component ( ) {
const { scrollRef , contentRef } = useStickToBottom ( ) ;
return (
< div style = { { overflow : 'auto' } } ref = { scrollRef } >
< div ref = { contentRef } >
{ messages . map ( ( message ) => (
< Message key = { message . id } message = { message } / >
) ) }
< / div >
< / div >
) ;
}