fix(nav): numeric inbox badge with active-state contrast
Show the unread count as a number on the collapsed nav rail (not just a dot), and invert the badge colours on the active row so it isn't an accent-on-accent red blob; centre the number on the circle.
This commit is contained in:
parent
ed4194a8d3
commit
00d07b9153
1 changed files with 40 additions and 24 deletions
|
|
@ -147,31 +147,47 @@ export default function NavSidebar({
|
|||
"w-full flex items-center gap-3 rounded-lg px-2.5 py-2 text-sm transition";
|
||||
const name = me.display_name ?? me.email.split("@")[0];
|
||||
|
||||
const renderItem = ({ page: p, icon: Icon, label, badge }: NavItem) => (
|
||||
const renderItem = ({ page: p, icon: Icon, label, badge }: NavItem) => {
|
||||
const active = page === p;
|
||||
// On the active row the background is the accent colour, so a same-accent badge would be
|
||||
// red-on-red. Invert it there (light pill, accent-coloured number) for clean contrast.
|
||||
const badgeColor = active ? "bg-accent-fg text-accent" : "bg-accent text-accent-fg";
|
||||
const show = !!badge && badge > 0;
|
||||
return (
|
||||
<button
|
||||
key={p}
|
||||
onClick={() => setPage(p)}
|
||||
title={collapsed ? label : undefined}
|
||||
aria-current={page === p ? "page" : undefined}
|
||||
aria-current={active ? "page" : undefined}
|
||||
className={`${rowBase} ${collapsed ? "justify-center px-0" : ""} relative ${
|
||||
page === p ? "bg-accent text-accent-fg" : "text-muted hover:text-fg hover:bg-card"
|
||||
active ? "bg-accent text-accent-fg" : "text-muted hover:text-fg hover:bg-card"
|
||||
}`}
|
||||
>
|
||||
<span className="relative shrink-0">
|
||||
<Icon className="w-[18px] h-[18px]" />
|
||||
{/* Collapsed rail: a small dot on the icon; expanded: a numeric pill at the row end. */}
|
||||
{!!badge && badge > 0 && collapsed && (
|
||||
<span className="absolute -top-1 -right-1 w-2 h-2 rounded-full bg-accent ring-2 ring-bg" />
|
||||
{/* Collapsed rail: a numeric badge centred on a circle at the icon corner; the ring
|
||||
matches the row background so it reads cleanly whether the row is active or not. */}
|
||||
{show && collapsed && (
|
||||
<span
|
||||
className={`absolute -top-2 -right-2 min-w-[16px] h-4 px-1 rounded-full text-[10px] font-bold leading-none grid place-items-center ring-2 ${badgeColor} ${
|
||||
active ? "ring-accent" : "ring-bg"
|
||||
}`}
|
||||
>
|
||||
{badge > 9 ? "9+" : badge}
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
{!collapsed && <span className="truncate">{label}</span>}
|
||||
{!!badge && badge > 0 && !collapsed && (
|
||||
<span className="ml-auto min-w-[18px] h-[18px] px-1 rounded-full bg-accent text-accent-fg text-[11px] font-semibold inline-flex items-center justify-center tabular-nums">
|
||||
{show && !collapsed && (
|
||||
<span
|
||||
className={`ml-auto min-w-[18px] h-[18px] px-1.5 rounded-full text-[11px] font-semibold leading-none inline-flex items-center justify-center tabular-nums ${badgeColor}`}
|
||||
>
|
||||
{badge > 99 ? "99+" : badge}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<nav
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue