mirror of
https://github.com/block/buzz.git
synced 2026-10-28 21:11:48 +00:00
Polish message row hover states (#880)
This commit is contained in:
@@ -6,7 +6,7 @@ export function DayDivider({ label }: { label: string }) {
|
||||
data-testid="message-timeline-day-divider"
|
||||
data-day-label={label}
|
||||
>
|
||||
<p className="shrink-0 rounded-full bg-background/90 px-2 py-0.5 text-[10px] font-medium tracking-[0.02em] text-muted-foreground/65 backdrop-blur-sm">
|
||||
<p className="shrink-0 rounded-lg border border-border/70 bg-background/95 px-2 py-1 text-[10px] font-medium tracking-[0.02em] text-muted-foreground/70 shadow-xs backdrop-blur-sm">
|
||||
{label}
|
||||
</p>
|
||||
</section>
|
||||
|
||||
@@ -30,6 +30,7 @@ export const MessageRow = React.memo(
|
||||
function MessageRow({
|
||||
channelId = null,
|
||||
highlighted = false,
|
||||
hoverBackground = true,
|
||||
isFollowingThread,
|
||||
layoutVariant = "default",
|
||||
message,
|
||||
@@ -45,6 +46,7 @@ export const MessageRow = React.memo(
|
||||
}: {
|
||||
channelId?: string | null;
|
||||
highlighted?: boolean;
|
||||
hoverBackground?: boolean;
|
||||
isFollowingThread?: boolean;
|
||||
layoutVariant?: "default" | "thread-reply";
|
||||
message: TimelineMessage;
|
||||
@@ -314,7 +316,8 @@ export const MessageRow = React.memo(
|
||||
|
||||
<article
|
||||
className={cn(
|
||||
"group/message relative rounded-2xl px-2 py-1 transition-colors",
|
||||
"group/message relative rounded-2xl px-3 py-2 transition-colors",
|
||||
hoverBackground && "hover:bg-muted/50 focus-within:bg-muted/50",
|
||||
"flex items-start gap-2.5",
|
||||
highlighted
|
||||
? "-mx-4 rounded-none px-6 before:absolute before:-inset-y-1.5 before:inset-x-0 before:animate-[route-target-highlight-fade_2s_ease-out_forwards] before:bg-primary/10 before:content-[''] motion-reduce:before:animate-none sm:-mx-6 sm:px-8"
|
||||
@@ -448,6 +451,7 @@ export const MessageRow = React.memo(
|
||||
prev.message.role === next.message.role &&
|
||||
prev.message.personaDisplayName === next.message.personaDisplayName &&
|
||||
prev.highlighted === next.highlighted &&
|
||||
prev.hoverBackground === next.hoverBackground &&
|
||||
prev.isFollowingThread === next.isFollowingThread &&
|
||||
prev.layoutVariant === next.layoutVariant &&
|
||||
prev.profiles === next.profiles &&
|
||||
|
||||
@@ -309,11 +309,16 @@ export function MessageThreadPanel({
|
||||
{threadReplies.map((entry) => {
|
||||
return (
|
||||
<div
|
||||
className="flex flex-col gap-1"
|
||||
className={cn(
|
||||
"flex flex-col gap-1",
|
||||
entry.summary &&
|
||||
"group/message -mx-1 rounded-2xl px-1 py-1 transition-colors hover:bg-muted/50 focus-within:bg-muted/50",
|
||||
)}
|
||||
key={entry.message.id}
|
||||
>
|
||||
<MessageRow
|
||||
channelId={channelId}
|
||||
hoverBackground={!entry.summary}
|
||||
layoutVariant="thread-reply"
|
||||
message={entry.message}
|
||||
onDelete={
|
||||
|
||||
@@ -321,7 +321,7 @@ export const SystemMessageRow = React.memo(function SystemMessageRow({
|
||||
|
||||
return (
|
||||
<div
|
||||
className="group/message relative rounded-2xl px-2 py-1 transition-colors"
|
||||
className="group/message relative rounded-2xl px-3 py-2 transition-colors hover:bg-muted/50 focus-within:bg-muted/50"
|
||||
data-testid="system-message-row"
|
||||
>
|
||||
<div className="flex items-start gap-2.5">
|
||||
|
||||
@@ -108,7 +108,7 @@ export const TimelineMessageList = React.memo(function TimelineMessageList({
|
||||
<div
|
||||
key={message.id}
|
||||
className={cn(
|
||||
"relative flex flex-col gap-0",
|
||||
"group/message relative -mx-1 flex flex-col gap-0 rounded-2xl px-1 py-1 transition-colors hover:bg-muted/50 focus-within:bg-muted/50",
|
||||
isHighlighted &&
|
||||
"-mx-4 px-4 before:absolute before:-inset-y-1.5 before:inset-x-0 before:animate-[route-target-highlight-fade_2s_ease-out_forwards] before:bg-primary/10 before:content-[''] motion-reduce:before:animate-none sm:-mx-6 sm:px-6",
|
||||
)}
|
||||
@@ -116,6 +116,7 @@ export const TimelineMessageList = React.memo(function TimelineMessageList({
|
||||
<MessageRow
|
||||
channelId={channelId}
|
||||
highlighted={false}
|
||||
hoverBackground={false}
|
||||
isFollowingThread={
|
||||
isFollowingThreadById
|
||||
? isFollowingThreadById(message.id)
|
||||
|
||||
@@ -403,6 +403,7 @@ test("opens a single-level thread panel with inline expansion", async ({
|
||||
const siblingReply = `Sibling threaded reply ${timestamp}`;
|
||||
const nestedReply = `Nested threaded reply ${timestamp}`;
|
||||
const nestedReplyFromBob = `Nested reply from Bob ${timestamp}`;
|
||||
const nestedReplyVisibleTopMaxPx = 260;
|
||||
const fillerReplies = Array.from(
|
||||
{ length: 14 },
|
||||
(_, index) => `Thread filler reply ${index} ${timestamp}`,
|
||||
@@ -524,7 +525,7 @@ test("opens a single-level thread panel with inline expansion", async ({
|
||||
return rowRect.top - bodyRect.top;
|
||||
});
|
||||
})
|
||||
.toBeLessThanOrEqual(240);
|
||||
.toBeLessThanOrEqual(nestedReplyVisibleTopMaxPx);
|
||||
|
||||
const firstReplyId = await firstReplyRow.getAttribute("data-message-id");
|
||||
if (!firstReplyId) {
|
||||
@@ -578,7 +579,7 @@ test("opens a single-level thread panel with inline expansion", async ({
|
||||
return rowRect.top - bodyRect.top;
|
||||
});
|
||||
})
|
||||
.toBeLessThanOrEqual(240);
|
||||
.toBeLessThanOrEqual(nestedReplyVisibleTopMaxPx);
|
||||
|
||||
await firstReplySummaryRow.click();
|
||||
await expect(
|
||||
|
||||
Reference in New Issue
Block a user