Scroll to bottom without the animation?
pranavmehta opened this issue · 6 comments
Is there a way to scroll to the bottom without the animation especially during the initial load?
I am using this in a chat-like an interface, and the animation gets extremely annoying when the conversation is long and it animates every time user switches the contact. I would like the scroll to be positioned at the bottom to begin with (without the animation) and then the usual scroll animation for future updates to the UI.
Is this possible?
I also need the same thing. I need to set the scroll bar initially to the bottom(without animation), and then to animate when something is changed. Is there any way to do that? @pranavmehta Did you found any solution?
This will disable initial animation<ScrollToBottom initialScrollBehavior={'auto'}>
Anyone figure out how to make this work? I tried initialScrollBehavior
, but it doesn't seem to work.
hey y'all - sharing how I got this to work just now. It seems the initialScrollBehavior
doesn't work as intended while the size of the container is changing - e.g while you're loading the content dynamically. I figured this out by turning on the debug mode.
What worked for me was to not render the component at all until my content loaded, and then on initial render it loads at the bottom as intended, without scrolling.
{messages?.length && (
<ScrollToBottom
initialScrollBehavior="auto"
{...scrollProps}
mode="bottom"
debug={true}
className="h-full x-dark:bg-gray-800"
>
<ScrollContent messages={messages} />
</ScrollToBottom>
)}
Hope this helps others!
hey y'all - sharing how I got this to work just now. It seems the
initialScrollBehavior
doesn't work as intended while the size of the container is changing - e.g while you're loading the content dynamically. I figured this out by turning on the debug mode. What worked for me was to not render the component at all until my content loaded, and then on initial render it loads at the bottom as intended, without scrolling.{messages?.length && ( <ScrollToBottom initialScrollBehavior="auto" {...scrollProps} mode="bottom" debug={true} className="h-full x-dark:bg-gray-800" > <ScrollContent messages={messages} /> </ScrollToBottom> )}
Hope this helps others!
yup, just verified this, having the messages?.length
as a verifier before works and it starts directly at the bottom, thank you very much, I've wasted hours with this
hey y'all - sharing how I got this to work just now. It seems the
initialScrollBehavior
doesn't work as intended while the size of the container is changing - e.g while you're loading the content dynamically. I figured this out by turning on the debug mode. What worked for me was to not render the component at all until my content loaded, and then on initial render it loads at the bottom as intended, without scrolling.{messages?.length && ( <ScrollToBottom initialScrollBehavior="auto" {...scrollProps} mode="bottom" debug={true} className="h-full x-dark:bg-gray-800" > <ScrollContent messages={messages} /> </ScrollToBottom> )}
Hope this helps others!
Even with this change, there are seems still some issues. I gave up, because my use case is very simple—just scrolling to the bottom. So I'll write one myself.
// ScrollToBottom.tsx
import React, { useState, useEffect, useRef, useCallback, ReactNode } from 'react';
import { debounce } from 'lodash-es';
import ScrollToBottomButton from './ScrollToBottomButton'
interface ScrollToBottomProps {
children: ReactNode;
}
const ScrollToBottom: React.FC<ScrollToBottomProps> = ({ children }) => {
const containerRef = useRef<HTMLDivElement | null>(null);
const [isAtBottom, setIsAtBottom] = useState(true);
// to bottom directly
const scrollToBottom = () => {
if (containerRef.current) {
containerRef.current.scrollTop = containerRef.current.scrollHeight;
}
};
// to bottom smooth
const scrollToBottomSmooth = () => {
if (containerRef.current) {
containerRef.current.scrollTo({
top: containerRef.current.scrollHeight,
behavior: 'smooth',
});
}
};
// check isbottom
const handleScroll = () => {
if (containerRef.current) {
const isBottom = containerRef.current.scrollHeight - containerRef.current.scrollTop === containerRef.current.clientHeight;
setIsAtBottom(isBottom);
}
};
const debouncedHandleScroll = useCallback(debounce(handleScroll, 100), []);
useEffect(() => {
scrollToBottom();
}, [children]);
return (
<div
ref={containerRef}
className='h-full dark:bg-gray-800 overflow-y-auto'
onScroll={debouncedHandleScroll}
>
{children}
<ScrollToBottomButton isAtBottom={isAtBottom} handleClick={scrollToBottomSmooth}></ScrollToBottomButton>
</div>
);
};
export default ScrollToBottom;