From 6360fe3d1d7c8e6bb3a97f9db381219c01d5e06c Mon Sep 17 00:00:00 2001 From: Nicolas Meienberger Date: Wed, 24 Sep 2025 18:25:31 +0200 Subject: [PATCH] feat: app breadcrumbs --- apps/client/app/components/app-breadcrumb.tsx | 42 +++++++ apps/client/app/components/layout.tsx | 4 +- apps/client/app/components/ui/breadcrumb.tsx | 109 ++++++++++++++++++ apps/client/app/components/ui/tabs.tsx | 64 ++++++++++ apps/client/app/lib/breadcrumbs.ts | 44 +++++++ apps/client/app/root.tsx | 2 +- apps/client/app/routes/details.tsx | 1 - apps/client/package.json | 1 + bun.lock | 5 + 9 files changed, 269 insertions(+), 3 deletions(-) create mode 100644 apps/client/app/components/app-breadcrumb.tsx create mode 100644 apps/client/app/components/ui/breadcrumb.tsx create mode 100644 apps/client/app/components/ui/tabs.tsx create mode 100644 apps/client/app/lib/breadcrumbs.ts diff --git a/apps/client/app/components/app-breadcrumb.tsx b/apps/client/app/components/app-breadcrumb.tsx new file mode 100644 index 0000000..5500079 --- /dev/null +++ b/apps/client/app/components/app-breadcrumb.tsx @@ -0,0 +1,42 @@ +import { Link } from "react-router"; +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbPage, + BreadcrumbSeparator, +} from "~/components/ui/breadcrumb"; +import { useBreadcrumbs } from "~/lib/breadcrumbs"; +import { cn } from "../lib/utils"; + +export function AppBreadcrumb() { + const breadcrumbs = useBreadcrumbs(); + + return ( + + + {breadcrumbs.map((breadcrumb, index) => { + const isLast = index === breadcrumbs.length - 1; + + return ( +
+ + {isLast || breadcrumb.isCurrentPage ? ( + {breadcrumb.label} + ) : breadcrumb.href ? ( + + {breadcrumb.label} + + ) : ( + {breadcrumb.label} + )} + + {!isLast && } +
+ ); + })} +
+
+ ); +} diff --git a/apps/client/app/components/layout.tsx b/apps/client/app/components/layout.tsx index 3084f35..12f699a 100644 --- a/apps/client/app/components/layout.tsx +++ b/apps/client/app/components/layout.tsx @@ -1,5 +1,6 @@ import { Outlet } from "react-router"; import { cn } from "~/lib/utils"; +import { AppBreadcrumb } from "./app-breadcrumb"; export default function Layout() { return ( @@ -12,7 +13,8 @@ export default function Layout() { )} >
-
+
+
diff --git a/apps/client/app/components/ui/breadcrumb.tsx b/apps/client/app/components/ui/breadcrumb.tsx new file mode 100644 index 0000000..6da6cbc --- /dev/null +++ b/apps/client/app/components/ui/breadcrumb.tsx @@ -0,0 +1,109 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { ChevronRight, MoreHorizontal } from "lucide-react" + +import { cn } from "~/lib/utils" + +function Breadcrumb({ ...props }: React.ComponentProps<"nav">) { + return