Quantcast
Channel: Active questions tagged flexbox - Stack Overflow
Viewing all articles
Browse latest Browse all 1314

How to make container scrollable but fill horizontally with React and Tailwind

$
0
0

I want a dashboard with a top and side bar and then the content in the middle. I want the content to be scrollable but I want it to fill the available height. The only issue is that when I try to fill the height it goes past the screen making the whole window scrollable and then is no longer scrollable itself. I have been reading its something to do with flex box but cannot tell. Im using React with typescript and Tailwindcss

App.tsx

import "./App.css";import { Route, Routes, BrowserRouter } from "react-router-dom";import Chat from "./components/Chat";import ChatList from "./components/ChatList/ChatList";import Topbar from "./components/Navigation/TopBar";import Bottombar from "./components/Navigation/BottomBar";function App() {    return (<BrowserRouter><div className="flex h-screen flex-col"><Topbar /><div className="grid grid-cols-8"><div className="col-span-1"></div><div className="col-span-7"><Routes><Route path="/chat/:id" element={<Chat />}></Route><Route path="/list" element={<ChatList />}></Route></Routes></div></div><Bottombar /></div></BrowserRouter>    );}export default App;

Chat.tsx

import MessagePane from "./MessagePane/MessagePane";import "../App.css";import { useParams } from "react-router-dom";interface ChatProps {  id: number;}export default function Chat() {  const { id } = useParams<{ id?: string }>();    const chatId = id ? parseInt(id, 10) : undefined;    if (chatId === undefined) {        return <div>Invalid chat ID</div>; // Display an error message or handle the case where id is undefined    }    return (<div className="flex-grow overflow-hidden bg-red-400"><MessagePane id={chatId} /></div>    );}

MessagePane.tsx

import { useEffect, useRef, useState } from "react";import { Message } from "../../interfaces/message.interface";import ChatBubble from "./ChatBubble";import "../../App.css";interface MessagePaneProps {    id: number;}export default function MessagePane({ id }: MessagePaneProps) {    const [messages, setMessages] = useState<Message[]>([]);    const [renderedMessages, setRenderedMessages] = useState<Message[]>([]);    const [loadCount, setLoadCount] = useState<number>(10); // Number of messages to load at a time    const chatContainerRef = useRef<HTMLDivElement>(null);    const topMessageIdRef = useRef<number | null>(null);    useEffect(() => {        const fetchMessages = async () => {            if (messages.length === 0) {                try {                    const response = await fetch(                        `http://localhost:3000/messages/${id}`                    );                    if (response.ok) {                        const data = await response.json();                        setMessages(data); // Ensure messages are in the correct order                    }                } catch (error) {                    console.error("Error fetching messages", error);                }            }        };        fetchMessages();    }, [id]);    useEffect(() => {        if (messages.length > 0) {            setRenderedMessages(messages.slice(-loadCount));            setTimeout(() => {                if (chatContainerRef.current) {                    chatContainerRef.current.scrollTop =                        chatContainerRef.current.scrollHeight;                }            }, 0);        }    }, [messages]);    const loadMoreMessages = () => {        if (chatContainerRef.current) {            const scrollTopBefore = chatContainerRef.current.scrollTop;            const scrollHeightBefore = chatContainerRef.current.scrollHeight;            const newRenderCount = Math.min(                renderedMessages.length + loadCount,                messages.length            );            setRenderedMessages(messages.slice(-newRenderCount));            requestAnimationFrame(() => {                if (chatContainerRef.current) {                    const scrollHeightAfter =                        chatContainerRef.current.scrollHeight;                    chatContainerRef.current.scrollTop =                        scrollHeightAfter -                        scrollHeightBefore +                        scrollTopBefore;                }            });        }    };    const handleScroll = () => {        if (chatContainerRef.current) {            const { scrollTop } = chatContainerRef.current;            if (scrollTop === 0) {                // Get the ROWID of the top message                const topMessageElement = chatContainerRef.current.querySelector(".chat-container > div:first-child"                );                if (topMessageElement) {                    const topMessageId = parseInt(                        topMessageElement.getAttribute("data-rowid") || ""                    );                    topMessageIdRef.current = topMessageId;                }                loadMoreMessages();            }        }    };    useEffect(() => {        const chatContainer = chatContainerRef.current;        if (chatContainer) {            chatContainer.addEventListener("scroll", handleScroll);        }        return () => {            if (chatContainer) {                chatContainer.removeEventListener("scroll", handleScroll);            }        };    }, [renderedMessages]);    // Scroll to the top message when new messages are loaded    useEffect(() => {        if (topMessageIdRef.current !== null) {            const topMessageElement = document.querySelector(                `#message-${topMessageIdRef.current}`            ) as HTMLElement;            if (topMessageElement && chatContainerRef.current) {                chatContainerRef.current.scrollTop =                    topMessageElement.offsetTop - chatContainerRef.current.offsetTop;            }        }    }, [renderedMessages]);    return (<div            className="chat-container flex-grow overflow-y-auto"            ref={chatContainerRef}>            {renderedMessages.map((message: Message, index: number) => (<div                    key={index}                    id={`message-${message.ROWID}`}                    data-rowid={message.ROWID} // Store the ROWID as data attribute><p>{message.ROWID}</p><ChatBubble sender={message.is_from_me} >                        {message.text}</ChatBubble></div>            ))}</div>    );}

Viewing all articles
Browse latest Browse all 1314

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>