ourshelf/src/components/PageBreadCrumb.tsx

105 lines
2.9 KiB
TypeScript

import Link from 'next/link'
import {
Breadcrumb,
BreadcrumbEllipsis,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from './ui/breadcrumb'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from './ui/dropdown-menu'
import { Fragment } from 'react'
import NaviagteBackButton from './NavigateBackButton'
export type Route = {
href: string
label: string
}
type RouteGroups = {
mostRecent: Route[]
inBetween: Route[]
root: Route
}
const groupBreadCrumbHistory = (routes: Route[]) => {
const mostRecent =
routes.length >= 3
? [routes[routes.length - 2], routes[routes.length - 1]]
: [routes[routes.length - 1]]
const inBetween = routes.length >= 3 ? routes.splice(1, routes.length - 3) : []
const groups: RouteGroups = {
root: routes[0],
mostRecent,
inBetween,
}
return groups
}
type Props = {
routes: Route[]
}
export function PageBreadCrumb(props: Props) {
const { routes } = props
const groups = groupBreadCrumbHistory(routes)
return (
<div className="">
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<NaviagteBackButton />
</BreadcrumbItem>
<BreadcrumbItem>
<BreadcrumbLink href={groups.root.href}>{groups.root.label}</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
{!!groups.inBetween.length && (
<>
<BreadcrumbItem>
<DropdownMenu>
<DropdownMenuTrigger className="flex items-center gap-1">
<BreadcrumbEllipsis className="h-4 w-4" />
<span className="sr-only">Toggle menu</span>
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
{groups.inBetween.map((r) => (
<DropdownMenuItem key={r.label + r.href}>
<Link href={r.href}>{r.label}</Link>
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
</BreadcrumbItem>
<BreadcrumbSeparator />
</>
)}
{groups.mostRecent.map((r, index) => {
if (index != groups.mostRecent.length - 1)
return (
<Fragment key={r.label + r.href}>
<BreadcrumbItem>
<BreadcrumbLink href={r.href}>{r.label}</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
</Fragment>
)
else
return (
<BreadcrumbItem key={r.label + r.href}>
<BreadcrumbPage>{r.label}</BreadcrumbPage>
</BreadcrumbItem>
)
})}
</BreadcrumbList>
</Breadcrumb>
</div>
)
}