From 0293b78732b8d0d774a7cb19e5b95d5f31d741a4 Mon Sep 17 00:00:00 2001 From: kmhalvin <53615235+kmhalvin@users.noreply.github.com> Date: Tue, 23 Sep 2025 22:00:36 +0700 Subject: [PATCH 1/2] window scroll support --- demo/DemoWindow.tsx | 93 +++++++++++++++++++++++++++++++++++++++++ src/useStickToBottom.ts | 8 ++-- 2 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 demo/DemoWindow.tsx diff --git a/demo/DemoWindow.tsx b/demo/DemoWindow.tsx new file mode 100644 index 0000000..a505cbf --- /dev/null +++ b/demo/DemoWindow.tsx @@ -0,0 +1,93 @@ +import {useEffect, useState} from 'react'; +import { useFakeMessages } from './useFakeMessages'; +import {useStickToBottom, ScrollToBottom} from "../src"; + +function ScrollToBottomButton({isAtBottom, scrollToBottom}: {isAtBottom: boolean, scrollToBottom: ScrollToBottom}) { + return ( + !isAtBottom && ( + + + + ); +} + +function Messages({ animation, speed }: { animation: ScrollBehavior; speed: number }) { + const messages = useFakeMessages(speed); + + return ( +
+

{animation}:

+ +
+ +
+
+ ); +} + +export function DemoWindow() { + const [speed, setSpeed] = useState(0.2); + + return ( +
+ setSpeed(+e.target.value)} + min={0} + max={1} + step={0.01} + > + +
+ +
+
+ ); +} + +function Message({ children }: { children: React.ReactNode }) { + return
{children}
; +} diff --git a/src/useStickToBottom.ts b/src/useStickToBottom.ts index b6dbdf8..168c4ec 100644 --- a/src/useStickToBottom.ts +++ b/src/useStickToBottom.ts @@ -398,7 +398,7 @@ export const useStickToBottom = ( const handleScroll = useCallback( ({ target }: Event) => { - if (target !== scrollRef.current) { + if (target !== document && target !== scrollRef.current) { return; } @@ -469,7 +469,7 @@ export const useStickToBottom = ( ({ target, deltaY }: WheelEvent) => { let element = target as HTMLElement; - while (!["scroll", "auto"].includes(getComputedStyle(element).overflow)) { + while (element !== document.documentElement && !["scroll", "auto"].includes(getComputedStyle(element).overflow)) { if (!element.parentElement) { return; } @@ -595,7 +595,7 @@ export interface StickToBottomInstance { contentRef: React.MutableRefObject & React.RefCallback; scrollRef: React.MutableRefObject & - React.RefCallback; + React.RefCallback; scrollToBottom: ScrollToBottom; stopScroll: StopScroll; isAtBottom: boolean; @@ -610,7 +610,7 @@ function useRefCallback any>( ) { // biome-ignore lint/correctness/useExhaustiveDependencies: not needed const result = useCallback((ref: HTMLElement | null) => { - result.current = ref; + result.current = ref instanceof Window ? document.documentElement : ref; return callback(ref); }, deps) as any as MutableRefObject & RefCallback; From a5c46d942874563e42cfddb153c8f5b2af8e24e3 Mon Sep 17 00:00:00 2001 From: kmhalvin <53615235+kmhalvin@users.noreply.github.com> Date: Wed, 24 Sep 2025 05:58:31 +0700 Subject: [PATCH 2/2] demo stop scroll --- demo/DemoWindow.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/demo/DemoWindow.tsx b/demo/DemoWindow.tsx index a505cbf..0fc8c03 100644 --- a/demo/DemoWindow.tsx +++ b/demo/DemoWindow.tsx @@ -14,7 +14,7 @@ function ScrollToBottomButton({isAtBottom, scrollToBottom}: {isAtBottom: boolean } function MessagesContent({ messages }: { messages: React.ReactNode[][] }) { - const { scrollRef, contentRef, isAtBottom, scrollToBottom } = useStickToBottom({ + const { scrollRef, contentRef, isAtBottom, scrollToBottom, stopScroll } = useStickToBottom({ resize: 'smooth', initial: 'smooth' }); @@ -42,7 +42,7 @@ function MessagesContent({ messages }: { messages: React.ReactNode[][] }) {
-