0

I am trying to scroll to bottom when messages are dynamically added in perfect-scroll-bar. When the response gets back from server, I am typing messages with some interval to give it a animation style. So while messages typing, scrollbar height changes so I want to scroll to bottom. But Resize detector not workign with perfect scrollbar. On height changes its calling onResize method but scrollHeight not getting changed. While I replace PerfectScrollbar with simple div overflow: 'auto' it is working fine.

import { forwardRef } from 'react';
import PropTypes from 'prop-types';
import PerfectScrollbar from 'react-perfect-scrollbar';
import type { ScrollBarProps as PerfectScrollbarProps } from 'react-perfect-scrollbar';
import { Box } from '@material-ui/core';

interface ScrollbarProps extends PerfectScrollbarProps {
}

const Scrollbar = forwardRef<HTMLDivElement, ScrollbarProps>((props, ref) => {
  const { children, ...other } = props;

  const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);

  if (isMobile) {
    return (
      <Box
        ref={ref}
        sx={{ overflowX: 'auto', height: '100%' }}
      >
        {children}
      </Box>
    );
  }

  return (
    <PerfectScrollbar
      // @ts-ignore
      ref={ref}
      {...other}
    >
      {children}
    </PerfectScrollbar>
  );
});

Scrollbar.propTypes = {
  children: PropTypes.node
};

export default Scrollbar;

Here goes the second component where I am using Scrollbar

import { useEffect, useRef } from 'react';
import type { Message } from 'src/types/chat';
import Scrollbar from '../../Scrollbar';
import ResizeDetector from 'react-resize-detector';

const ChatMessages = (props) => {
  const { messages, threadKey, thread, ...other } = props;
  const rootRef = useRef<any>(null);
  const { id } = userProfile;

  const scrollToBottom = () => {
    // eslint-disable-next-line no-underscore-dangle
    if (rootRef?.current?._container) {
      // eslint-disable-next-line no-underscore-dangle
      rootRef.current._container.scrollTop =
        rootRef.current._container.scrollHeight;
    }
  };

  useEffect(() => {
    scrollToBottom();
  }, [messages, scrollToBottom]);

  const now = new Date();
  return (
    <ResizeDetector
      handleWidth
      handleHeight
      onResize={(width?: number, height?: number) => {
        if (rootRef?.current?._container) {
          // this height is not changing when content is being adding in
          console.log('scroll height: '+ rootRef?.current?._container.scrollHeight);
          scrollToBottom();
        }
      }}
    >
      <Scrollbar options={{ suppressScrollX: true }} ref={rootRef} {...other}>
    
        <Box ref={bottomRef}>
          {messages?.map((message, index) => {
                //rest of the code
          })}
        </Box>
      </Scrollbar>
    </ResizeDetector>
  );
};

If I just repalce this line <Scrollbar options={{ suppressScrollX: true }} ref={rootRef} {...other}> with <div style={{ overflow: 'auto'}} ref={rootRef} > then everything works fine.

I tried but its not working.

I tried but still not working

0 Answers0