Chat
One conversation with bubbles, reactions and a composer.
Chat with Ayesha Khan
Ayesha Khan
Senior product designer · Online
Ayesha Khan
Hi Sara, can I take Friday 17 Oct off for a family event?
Ayesha Khan:
I have 12 days of annual leave left.
Sara Malik approved 1 day of annual leave
Sara Malik:
Ayesha KhanCan I take Friday 17 Oct off?
Approved. Enjoy the long weekend.
Read
Sara Malik:
I have added it to the team calendar.
Read
Ayesha Khan
Thank you! I will hand over the design review to Luis.
Ayesha is typing
Enter sends the message. Shift+Enter adds a new line.
chat.tsx
"use client";
import { useState } from "react";
import { LuEllipsis, LuHeart, LuSearch, LuThumbsUp } from "react-icons/lu";
import {
Avatar,
ChatHeader,
Composer,
DateSeparator,
IconButton,
Menu,
MenuItem,
MessageBubble,
Presence,
Reaction,
SystemMessage,
TypingIndicator,
} from "@nexera-ui/react";
interface Sent {
text: string;
file?: boolean;
}
/** Chat: one conversation between People Ops and an employee, with reactions, a typing indicator and a composer. */
export default function Chat() {
const [sent, setSent] = useState<Sent[]>([]);
const [liked, setLiked] = useState(true);
const [loved, setLoved] = useState(false);
const [muted, setMuted] = useState(false);
const ayesha = <Avatar size="md" initials="AK" isDecorative />;
return (
<div className="@container bg-page px-4 py-8 @3xl:px-8">
<section
aria-labelledby="chat-title"
className="mx-auto flex h-[640px] w-full max-w-3xl flex-col overflow-hidden rounded-xl border border-default bg-surface shadow-sm"
>
<h2 id="chat-title" className="sr-only">
Chat with Ayesha Khan
</h2>
<ChatHeader
name="Ayesha Khan"
headingLevel={3}
status={muted ? "Senior product designer · Muted" : "Senior product designer · Online"}
avatar={
<Avatar size="md" initials="AK" isDecorative presence={<Presence isDecorative />} />
}
actions={
<>
<IconButton variant="ghost" aria-label="Search in conversation" icon={<LuSearch />} />
<Menu
trigger={
<IconButton variant="ghost" aria-label="More options" icon={<LuEllipsis />} />
}
>
<MenuItem id="profile" label="View profile" href="#people/ayesha-khan" />
<MenuItem
id="mute"
label={muted ? "Unmute notifications" : "Mute notifications"}
onAction={() => {
setMuted((m) => !m);
}}
/>
</Menu>
</>
}
/>
<div
role="log"
aria-label="Messages"
className="flex min-h-0 flex-1 flex-col gap-1.5 overflow-y-auto p-4"
>
<DateSeparator label="Today" dateTime="2026-10-14" />
<MessageBubble
name="Ayesha Khan"
avatar={ayesha}
time="10:24"
dateTime="2026-10-14T10:24"
>
Hi Sara, can I take Friday 17 Oct off for a family event?
</MessageBubble>
<MessageBubble
name="Ayesha Khan"
avatar={ayesha}
group="continued"
time="10:24"
dateTime="2026-10-14T10:24"
>
I have 12 days of annual leave left.
</MessageBubble>
<SystemMessage>Sara Malik approved 1 day of annual leave</SystemMessage>
<MessageBubble
direction="outgoing"
type="reply"
quote="Can I take Friday 17 Oct off?"
quoteAuthor="Ayesha Khan"
name="Sara Malik"
time="10:31"
dateTime="2026-10-14T10:31"
status="read"
>
Approved. Enjoy the long weekend.
</MessageBubble>
<MessageBubble
direction="outgoing"
group="continued"
name="Sara Malik"
time="10:31"
dateTime="2026-10-14T10:31"
status="read"
>
I have added it to the team calendar.
</MessageBubble>
<MessageBubble
name="Ayesha Khan"
avatar={ayesha}
time="10:33"
dateTime="2026-10-14T10:33"
>
Thank you! I will hand over the design review to Luis.
</MessageBubble>
<div
role="group"
aria-label="Reactions to Ayesha's message"
className="flex flex-wrap gap-1 ps-10"
>
<Reaction
icon={<LuThumbsUp />}
label="Thumbs up"
count={liked ? 2 : 1}
isSelected={liked}
onChange={setLiked}
/>
<Reaction
icon={<LuHeart />}
label="Heart"
count={loved ? 1 : 0}
isSelected={loved}
onChange={setLoved}
/>
</div>
{sent.map((message, i) =>
message.file ? (
<MessageBubble
key={i}
direction="outgoing"
type="file"
name="Sara Malik"
fileName={message.text}
fileDetails="PDF · 84 KB"
time="Now"
status="sent"
/>
) : (
<MessageBubble
key={i}
direction="outgoing"
name="Sara Malik"
time="Now"
status="sent"
>
{message.text}
</MessageBubble>
),
)}
<TypingIndicator>Ayesha is typing</TypingIndicator>
</div>
<div className="border-t border-default">
<Composer
aria-label="Message Ayesha Khan"
placeholder="Message Ayesha"
onSend={(text) => {
setSent((s) => [...s, { text }]);
}}
onAttach={() => {
setSent((s) => [...s, { text: "Leave policy 2026.pdf", file: true }]);
}}
/>
</div>
</section>
</div>
);
}
More messaging and collaboration blocks
- InboxConversation list beside the open chat.
- Helpdesk assistantAsk HR or support a question and get answers.
- Comment threadDiscuss a record with replies and reactions.
- Notification centreUnread notifications in a popover.
- AnnouncementA banner for news that affects everyone.
- Document editorWrite and format text with links and lists.
- Day separators and system notesShow who joined and where each day starts.