105 lines
2.9 KiB
TypeScript
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>
|
|
)
|
|
}
|