"use client"
/**
* NavUser — WCAG 2.1 AA profile menu
*
* AA checklist:
* ✓ aria-label on trigger (1.3.1, 4.1.2)
* ✓ Icon-only items have sr-only text (1.1.1)
* ✓ App preferences link to Settings (appearance lives there)
* ✓ Keyboard: full arrow-key + Enter/Space navigation via Radix (2.1.1)
* ✓ Focus ring visible on every item (2.4.11)
* ✓ Colour contrast: all labels ≥ 4.5:1 on popover bg (1.4.3)
* ✓ Active theme shown via Mode segmented control (aria-checked on segments) (4.1.3)
*/
import * as React from "react"
import { Link } from "react-router"
import { listWorkspaceConsoleProducts } from "@exxatdesignux/product-framework/product-brand"
import {
Avatar,
AvatarFallback,
AvatarImage,
} from "../ui/avatar"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "../ui/dropdown-menu"
import {
SidebarMenu,
SidebarMenuButton,
SidebarMenuItem,
useSidebar,
} from "../ui/sidebar"
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "../ui/tooltip"
import { useAppShellSlots } from "./app-shell-slots"
import { useProductSwitch } from "./product-route-sync"
import { cn } from "../../lib/utils"
export function NavUser({
user,
}: {
user: {
name: string
email: string
avatar: string
}
}) {
const { isMobile, state } = useSidebar()
const iconRailCollapsed = state === "collapsed" && !isMobile
const { slots, on, data } = useAppShellSlots()
const preferenceGroups = slots.userMenuPreferences ?? []
const consoleItems = slots.userMenuConsoleItems ?? []
const accountItems = slots.userMenuAccountItems ?? []
const switchProduct = useProductSwitch()
const workspaceConsoles = listWorkspaceConsoleProducts()
const workspaceSettingsHref = data.useWorkspaceSettingsHref()
const profileTrigger = (
span:last-child]:!overflow-visible [&>span:last-child]:!whitespace-normal [&>span:last-child]:text-clip",
"group-data-[collapsible=icon]:[&>span:last-child]:hidden",
)}
>
{user.name.slice(0, 2).toUpperCase()}
{user.name}
{user.email}
)
return (
{profileTrigger}
{user.name}
{/* ── User identity ──────────────────────────────── */}
{user.name.slice(0, 2).toUpperCase()}
{user.name}
{user.email}
{/* ── Account actions ────────────────────────────── */}
Account
Billing
Notifications
Profile settings
Workspace settings
{/* App-supplied account rows — switch organization, support
handoff, anything that belongs beside settings rather than
down with the consoles. */}
{accountItems.map((AccountItem, index) => (
))}
{/* ── Preferences (theme, search mode, layout) ───── */}
{preferenceGroups.map((PreferenceGroup, index) => (
))}
{/* ── Registry consoles + app-supplied rows ──────── */}
{workspaceConsoles.map(consoleProduct => (
switchProduct(consoleProduct.id)}
>
{consoleProduct.label}
))}
{consoleItems.map((ConsoleItem, index) => (
))}
{/* ── Sign out ───────────────────────────────────── */}
on.logOut?.()}>
Log out
)
}