I'm making a chatting app and want to add an opportunity to scroll messages. I've added 'overflow-y-scroll', but it just displays a disactivated scrollbar, although the messages get cut.
The overflow is used in the CurrentChat component, where lots of Message components are.
CurrentChat.tsx - the component that displays the currently active chat:
import React, { Dispatch, SetStateAction } from 'react';
import { chats } from '@/db/db';
import Message from './Message';
import UserBar from './UserBar';
import SendMessage from './SendMessage';
type propsType = {
currChat: string | null;
setCurrChat: Dispatch<SetStateAction<string | null>>;
}
export default function CurrentChat({ currChat, setCurrChat }: propsType) {
const chat = chats.filter(chat => chat.user.name === currChat)[0];
return (
<div>
<div className='bg-[#E7E8D1] flex min-h-full min-w-[65vw] align-bottom'>
{currChat === null
?
<div className='flex justify-center items-center min-h-[100vh] w-full select-none'>
<p>
Select a chat to start a conversation
</p>
</div>
:
<div className='flex flex-col justify-end w-full h-[100vh]'>
<div className='flex flex-col justify-self-start flex-auto'>
<UserBar />
</div>
<div className="h-[90%] overflow-y-scroll">
<div className='flex flex-col justify-end h-[100%] w-full'>
<Message message={chat.messages[0]} />
<Message message={chat.messages[1]} />
<Message message={chat.messages[2]} />
<Message message={chat.messages[0]} />
<Message message={chat.messages[1]} />
<Message message={chat.messages[2]} />
<Message message={chat.messages[0]} />
<Message message={chat.messages[1]} />
<Message message={chat.messages[2]} />
<Message message={chat.messages[0]} />
<Message message={chat.messages[1]} />
<Message message={chat.messages[2]} />
<Message message={chat.messages[0]} />
</div>
</div>
<SendMessage />
</div>
}
</div>
</div>
)
}
Message.tsx:
import React from 'react';
import { localUser } from '@/db/db';
type propsType = {
message: Message
}
export default function Message(props: { message: Message}) {
const { message } = props;
const time = message.date.split(' ')[1];
const align = message.sender !== localUser
? 'self-start bg-[#f9fae1]' : 'self-end bg-[#e9e9dd]';
return (
<div className={'flex flex-col shadow-sm mx-6 px-6 pt-6 pb-2 w-[fit-content] max-w-[30vw] rounded-3xl m-5 ' + align}>
{message.content}
<div className="flex flex-row justify-end mt-1">
{time}
</div>
</div>
)
}
UserBar.tsx - for displaying the current user you are chatting with:
import React from 'react'
export default function UserBar() {
return (
<div className='z-2 w-full h-[10vh] flex bg-[#fff0] shadow-md flex-row'>
<div className="rounded-full bg-white w-[5rem] h-[5rem] self-center ml-3"></div>
<div className='ml-5 self-center'>Name</div>
</div>
)
}
SendMessage.tsx:
import React from 'react'
export default function SendMessage() {
return (
<div className='w-full h-[8vh] flex bg-[#8f8f8f] flex-row justify-self-end'>
SendMessage
</div>
)
}
I've tried to change the parent div's height and flex properties and applying the overflow on it.
Remove justify-items: end
from the vertical flex layout that holds the <Messages>
– the flex children are justified before the scrolling is calculated. Since the last message is aligned to the bottom of the scrolling container, there is nothing to scroll so no scroll bar appears.
const localUser = 'bar';
function Message(props) {
const { message } = props;
const time = message.date.split(' ')[1];
const align = message.sender !== localUser
? 'self-start bg-[#f9fae1]' : 'self-end bg-[#e9e9dd]';
return (
<div className={'flex flex-col shadow-sm mx-6 px-6 pt-6 pb-2 w-[fit-content] max-w-[30vw] rounded-3xl m-5 ' + align}>
{message.content}
<div className="flex flex-row justify-end mt-1">
{time}
</div>
</div>
)
}
function UserBar() {
return (
<div className='z-2 w-full h-[10vh] flex bg-[#fff0] shadow-md flex-row'>
<div className="rounded-full bg-white w-[5rem] h-[5rem] self-center ml-3"></div>
<div className='ml-5 self-center'>Name</div>
</div>
)
}
function SendMessage() {
return (
<div className='w-full h-[8vh] flex bg-[#8f8f8f] flex-row justify-self-end'>
SendMessage
</div>
)
}
const chats = [
{
user: {
name: 'foo',
},
messages: [
{
sender: 'foo',
date: ' 09:00',
content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque cursus justo eu ante iaculis semper. Donec porttitor urna vitae dolor lacinia, in faucibus justo vehicula. Cras dignissim dui ultricies, porta orci quis, bibendum quam. Maecenas ac risus pulvinar, malesuada lacus eget, condimentum massa. Quisque imperdiet sem id lectus dapibus suscipit. Suspendisse porta, ipsum et cursus sodales, tortor massa viverra ex, eu tincidunt elit libero et quam. Etiam quis purus justo.',
},
{
sender: 'bar',
date: ' 09:00',
content: 'Donec sed diam at diam scelerisque sollicitudin non non elit. Nulla gravida molestie tellus ut elementum. In hac habitasse platea dictumst. Vivamus sed lorem vel mi vestibulum scelerisque. Vestibulum pretium metus at varius consectetur. Donec mattis molestie nunc, nec pharetra urna hendrerit eget. Duis blandit tincidunt interdum. Praesent et velit arcu. Maecenas ullamcorper rhoncus purus, id lobortis ex porta sed. Vivamus ante felis, ultricies elementum ipsum auctor, bibendum consectetur felis. Donec lobortis dolor sit amet nunc hendrerit tristique. Vivamus consequat dolor vitae velit condimentum facilisis. Duis a imperdiet neque, nec euismod purus. Pellentesque elementum felis a venenatis condimentum.',
},
{
sender: 'foo',
date: ' 09:00',
content: 'Aliquam egestas at quam iaculis semper. Sed a ultrices nisl. Integer diam elit, congue non elit in, iaculis commodo est. Nullam quis auctor arcu. Pellentesque eu leo nec lectus gravida finibus porta imperdiet nunc. Ut id nisi vehicula, mattis libero ullamcorper, molestie odio. Maecenas at mauris id velit efficitur laoreet ut et elit. Integer auctor molestie magna, ut facilisis elit auctor nec. Duis id euismod ipsum, vel sodales justo. Vivamus eget iaculis justo, eget viverra odio. Nunc eu sollicitudin felis, vitae fringilla sapien. In sed ligula nisi. Vivamus vitae purus nulla. Vivamus quis nunc placerat, commodo libero et, varius risus. Suspendisse non finibus nisi. In justo justo, efficitur et placerat quis, porta eu mauris.',
},
],
},
];
function CurrentChat({ currChat, setCurrChat }) {
const chat = chats.filter(chat => chat.user.name === currChat)[0];
return (
<div>
<div className='bg-[#E7E8D1] flex min-h-full min-w-[65vw] align-bottom'>
{currChat === null
?
<div className='flex justify-center items-center min-h-[100vh] w-full select-none'>
<p>
Select a chat to start a conversation
</p>
</div>
:
<div className='flex flex-col justify-end w-full h-[100vh]'>
<div className='flex flex-col justify-self-start flex-auto'>
<UserBar />
</div>
<div className="h-[90%] overflow-y-scroll">
<div className='flex flex-col h-[100%] w-full'>
<Message message={chat.messages[0]} />
<Message message={chat.messages[1]} />
<Message message={chat.messages[2]} />
<Message message={chat.messages[0]} />
<Message message={chat.messages[1]} />
<Message message={chat.messages[2]} />
<Message message={chat.messages[0]} />
<Message message={chat.messages[1]} />
<Message message={chat.messages[2]} />
<Message message={chat.messages[0]} />
<Message message={chat.messages[1]} />
<Message message={chat.messages[2]} />
<Message message={chat.messages[0]} />
</div>
</div>
<SendMessage />
</div>
}
</div>
</div>
)
}
ReactDOM.createRoot(document.getElementById('app')).render(<CurrentChat currChat="foo"/>);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.tailwindcss.com/3.3.3"></script>
<div id="app"></div>
To have the scrolling container start at the bottom, set the scrollTop
of the scrolling container to the maximum bound in JavaScript instead.