Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions apps/web/src/components/SidebarV2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,11 @@ function WorkingDuration(props: { startedAt: string | null }) {
return () => window.clearInterval(id);
}, [startedMs]);
if (Number.isNaN(startedMs)) return null;
return <span className="tabular-nums">{formatWorkingDurationLabel(Date.now() - startedMs)}</span>;
return (
<span className="font-mono tabular-nums">
{formatWorkingDurationLabel(Date.now() - startedMs)}
</span>
);
}

function SidebarV2ThreadTooltip({
Expand Down Expand Up @@ -881,11 +885,15 @@ const SidebarV2Row = memo(function SidebarV2Row(props: {
) : (
<span className="flex-1" />
)}
<span className="relative ml-auto flex h-5 min-w-8 shrink-0 items-center justify-end pl-1 text-xs">
{/* The visible state owns this slot's width: status at rest,
actions on hover/focus or while the popover is open. Keeping
the hidden state out of flow lets the project label reclaim
space without either state overlapping it. */}
<span className="group/v2-status-slot relative ml-auto flex h-5 min-w-8 shrink-0 items-stretch justify-end text-xs">
<span
className={cn(
"tabular-nums text-muted-foreground/65 transition-opacity group-hover/v2-row:opacity-0",
snoozeMenuOpen && "opacity-0",
"self-center justify-self-end tabular-nums text-muted-foreground/65 transition-opacity group-focus-within/v2-status-slot:absolute group-focus-within/v2-status-slot:right-0 group-hover/v2-row:absolute group-hover/v2-row:right-0 group-hover/v2-row:opacity-0",
snoozeMenuOpen && "absolute right-0 opacity-0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Status overlaps actions on focus

Medium Severity

Keyboard focus on the status slot makes the status text absolute but doesn't hide it, causing it to overlap with the visible snooze/settle actions. This differs from hover or an open snooze menu, which correctly hide the status.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 7df171f. Configure here.

)}
>
{topStatus ? (
Expand Down Expand Up @@ -919,8 +927,8 @@ const SidebarV2Row = memo(function SidebarV2Row(props: {
{props.settlementSupported || showSnoozeButton ? (
<span
className={cn(
"absolute inset-y-0 right-0 flex items-stretch opacity-0 transition-opacity focus-within:opacity-100 group-hover/v2-row:opacity-100",
snoozeMenuOpen && "opacity-100",
"absolute inset-y-0 right-0 flex items-stretch opacity-0 transition-opacity focus-within:static focus-within:opacity-100 group-hover/v2-row:static group-hover/v2-row:opacity-100",
snoozeMenuOpen && "static opacity-100",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hidden status blocks action clicks

High Severity

When a row is hovered or the snooze menu is open, the status element becomes absolutely positioned and transparent, while the action buttons become static. This allows the invisible status element to intercept pointer events, blocking clicks on the visible snooze and settle buttons.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 7df171f. Configure here.

)}
>
{showSnoozeButton ? (
Expand Down
Loading