I want to make a date divider like in the Slack app. This is a divider in a select task. Messages belonging to a certain date appear under the divider. When I scroll up the page, the divider goes up to the top of the area in which it is located and starts to act as sticky. When it comes to the previous date, the date inside the divider select changes with the other date and continues to perform the same function. I added the example of what I wanted as a screen recording via loom.
**What I want : **
**ChatCard.tsx (Divider usage part) : **
<Box
height={isMobile ? "100%" : "100%"}
padding={"0 20px"}
className="chat-card-messages-area"
>
<Stack
justifyContent={"center"}
alignItems={"center"}
width={"100%"}
pt={"20px"}
>
<Chip
className="B-12-18-600"
label={lastMessageReceivedAt}
sx={{
display: "flex",
height: "32px",
padding: "6px 12px",
justifyContent: "center",
alignItems: "center",
gap: "6px",
color: "var(--Gray-500, #667085)",
}}
></Chip>
</Stack>
<Stack
justifyContent={"center"}
alignItems={"center"}
textAlign={"center"}
width={"100%"}
>
<span className="B-12-18-500">
We analyze messages for safety, support, product enhancement, or
other purposes.
<Button
sx={{
color: "var(--Gray-Gray-600, #7E8299)",
fontFamily: "Inter",
fontSize: "12px",
fontStyle: "normal",
fontWeight: "700",
lineHeight: "20px",
textDecorationLine: "underline",
":hover": {
backgroundColor: "initial",
textDecorationLine: "underline",
},
}}
>
<span>Learn more</span>
</Button>
</span>
</Stack>
{messageitem && messageitem.length > 0 ? (
Object.keys(messageGroups).map((minuteKey) => (
<React.Fragment key={minuteKey}>
<DateDivider
date={moment(minuteKey).format("YYYY-MM-DD")}
onTimeRangeChange={handleTimeRangeChange}
/>
{messageGroups[minuteKey].map((message, index) => (
<Chat
key={message.Id}
id={message.Id}
avatarSrc={
message.Sender === "property"
? OwnerAvatar
: CustomerAvatar
}
senderName={capitalizeWords(message.Sender)}
messageTime={moment(message.CreatedAt).format("HH:mm")}
messageText={message.Message}
showTime={true}
/>
))}
</React.Fragment>
))
) : (
<Box
display="flex"
justifyContent="center"
alignItems="center"
height="100%"
width={"100%"}
>
<p
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
textAlign: "center",
height: "100%",
}}
className="B-14-14-600"
>
{t("inboxpage.letstartchatting")}
</p>
</Box>
)}
<div ref={messagesEndRef} />
</Box>
**DateDivider.tsx : **
import React, { useState } from "react";
import { Box, MenuItem, Popover } from "@mui/material";
import moment from "moment";
import ArrowDown from "../../../../assets/images/icons/arrow-down-messages.svg";
import { chatBoxStyles } from "../ChatBoxStyles";
interface DateDividerProps {
date: string;
onTimeRangeChange: (value: string) => void;
}
const DateDivider: React.FC<DateDividerProps> = ({
date,
onTimeRangeChange,
}) => {
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const formattedDate = moment(date).calendar(null, {
sameDay: "[Today]",
lastDay: "[Yesterday]",
lastWeek: "[Last] dddd",
sameElse: "MMMM D, YYYY",
});
const timeRanges = [
{ label: "Today", value: "today" },
{ label: "Yesterday", value: "yesterday" },
{ label: "Last Week", value: "lastWeek" },
{ label: "Last Month", value: "lastMonth" },
{ label: "Beginning of the Chat", value: "beginning" },
];
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const open = Boolean(anchorEl);
const id = open ? "simple-popover" : undefined;
const [selectedValue, setSelectedValue] = useState<string>("");
const handleMenuItemClick = (value: any) => {
setSelectedValue(value);
onTimeRangeChange(value);
handleClose();
};
return (
<Box
display="flex"
alignItems="center"
justifyContent="center"
width="100%"
>
<Box flex="1" height="1px" bgcolor="#F1F1F2"></Box>
<Box
display="flex"
alignItems="center"
onClick={handleClick}
sx={chatBoxStyles.chatBoxSelectDivider}
>
{formattedDate}
<img
style={{ cursor: "pointer", marginLeft: 8 }}
src={ArrowDown}
alt="arrow-down"
/>
</Box>
<Popover
id={id}
open={open}
anchorEl={anchorEl}
onClose={handleClose}
anchorOrigin={{
vertical: "bottom",
horizontal: "center",
}}
>
<Box
sx={{
display: "flex",
padding: "10px 12px",
flexDirection: "column",
alignItems: "flex-start",
alignSelf: "stretch",
width: "180px",
boxShadow:
"0px 1px 2px 0px rgba(0, 0, 0, 0.30), 0px 2px 6px 2px rgba(0, 0, 0, 0.15)",
borderRadius: "12px",
overflow: "visible",
gap: "5px",
}}
>
<em
style={{
display: "flex",
padding: "4px 10px",
alignItems: "flex-start",
alignSelf: "stretch",
color: "#7E8299",
fontFamily: "Inter",
fontSize: "12px",
fontStyle: "normal",
fontWeight: 500,
lineHeight: "20px",
}}
>
Jump to..
</em>
{timeRanges.map((range) => (
<MenuItem
key={range.value}
onClick={() => handleMenuItemClick(range.value)}
sx={{
display: "flex",
padding: "7px 10px",
alignItems: "flex-start",
alignSelf: "stretch",
color: "#181C32",
fontFamily: "Inter",
fontSize: "14px",
fontStyle: "normal",
fontWeight: 500,
lineHeight: "20px",
borderRadius: "10px",
}}
>
{range.label}
</MenuItem>
))}
</Box>
</Popover>
<Box flex="1" height="1px" bgcolor="#F1F1F2"></Box>
</Box>
);
};
export default DateDivider;
I tried every way that came to my mind, but the divider remains constant in the code I can do. All kinds of functions work. But I couldn’t move up with the scroll I mentioned and then the replacement with the other date.
My Version :