ultisuite-client/components/gmail/mail-folder-stack-indicator.tsx
2026-05-16 20:30:50 +02:00

117 lines
2.9 KiB
TypeScript

"use client"
import { Fragment, useMemo } from "react"
import { Icon } from "@iconify/react"
import type { FolderTreeNode } from "@/lib/sidebar-nav-maps"
import type { LabelRowItem } from "@/lib/sidebar-nav-data"
import { breadcrumbItemsForVisitKey } from "@/lib/mail-folder-display"
import { resolveMailNavIcon } from "@/lib/mail-nav-icons"
import { cn } from "@/lib/utils"
type MailFolderStackIndicatorProps = {
currentKey: string
folderTree: FolderTreeNode[]
folderIdToLabel: Record<string, string>
labelRows?: readonly LabelRowItem[]
className?: string
}
function MailNavIconGlyph({
visitKey,
folderTree,
labelRows,
}: {
visitKey: string
folderTree: FolderTreeNode[]
labelRows?: readonly LabelRowItem[]
}) {
const resolved = useMemo(
() => resolveMailNavIcon(visitKey, folderTree, labelRows),
[visitKey, folderTree, labelRows]
)
if (resolved.kind === "folder-dot") {
return (
<span
className={cn(
"inline-block size-4 shrink-0 rounded-full",
resolved.colorClass
)}
aria-hidden
/>
)
}
if (resolved.kind === "iconify") {
return (
<Icon
icon={resolved.icon}
className="size-4 shrink-0 text-[#5f6368]"
aria-hidden
/>
)
}
const { Icon: LucideIcon } = resolved
return (
<LucideIcon
className="size-4 shrink-0 text-[#5f6368]"
strokeWidth={1.5}
aria-hidden
/>
)
}
export function MailFolderStackIndicator({
currentKey,
folderTree,
folderIdToLabel,
labelRows,
className,
}: MailFolderStackIndicatorProps) {
const items = useMemo(
() => breadcrumbItemsForVisitKey(currentKey, folderTree, folderIdToLabel),
[currentKey, folderTree, folderIdToLabel]
)
const ariaLabel = items.map((i) => i.label).join(" · ")
return (
<div
role="status"
aria-live="polite"
aria-label={`Boîte actuelle : ${ariaLabel}`}
className={cn(
"flex max-w-[min(360px,calc(100vw-1rem))] items-center",
"border-t border-r border-[#dadce0]/90",
"bg-white/78 px-3.5 py-2.5 text-sm font-medium leading-snug text-[#3c4043]",
"rounded-tr-2xl shadow-sm backdrop-blur-md",
className
)}
>
<span className="flex min-w-0 items-center gap-1.5">
{items.map((item, i) => (
<Fragment key={`${item.visitKey}-${i}`}>
{i > 0 ? (
<span
className="shrink-0 text-xs leading-none text-[#9aa0a6]"
aria-hidden
>
·
</span>
) : null}
<span className="flex min-w-0 items-center gap-1.5">
<MailNavIconGlyph
visitKey={item.visitKey}
folderTree={folderTree}
labelRows={labelRows}
/>
<span className="truncate">{item.label}</span>
</span>
</Fragment>
))}
</span>
</div>
)
}