Skip to content

Commit 73444cd

Browse files
committed
chore: add breadcrumbs
1 parent b17f210 commit 73444cd

File tree

8 files changed

+167
-4
lines changed

8 files changed

+167
-4
lines changed

src/components/Breadcrumbs.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { PropsWithChildren } from "react";
2+
import { Breadcrumb, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from "@/components/ui/breadcrumb";
3+
import { Link } from "react-router";
4+
5+
export function Breadcrumbs({ children }: PropsWithChildren<unknown>) {
6+
return (
7+
<Breadcrumb>
8+
<BreadcrumbList>
9+
<BreadcrumbItem>
10+
<BreadcrumbLink asChild>
11+
<Link to="/">Home</Link>
12+
</BreadcrumbLink>
13+
</BreadcrumbItem>
14+
<BreadcrumbSeparator />
15+
<BreadcrumbItem>
16+
<BreadcrumbPage>{children}</BreadcrumbPage>
17+
</BreadcrumbItem>
18+
</BreadcrumbList>
19+
</Breadcrumb>
20+
)
21+
}

src/components/H2.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { PropsWithChildren } from "react";
2+
3+
export function H2({ children }: PropsWithChildren<unknown>) {
4+
return (
5+
<h2 className="scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl">
6+
{children}
7+
</h2>
8+
)
9+
}

src/components/PageTitle.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { PropsWithChildren } from "react";
2+
import { H2 } from "./H2";
3+
4+
export function PageTitle({ children }: PropsWithChildren<unknown>) {
5+
return (
6+
<H2>
7+
{children}
8+
</H2>
9+
)
10+
}

src/components/ui/breadcrumb.tsx

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
import * as React from "react"
2+
import { Slot } from "@radix-ui/react-slot"
3+
import { ChevronRight, MoreHorizontal } from "lucide-react"
4+
5+
import { cn } from "@/lib/utils"
6+
7+
function Breadcrumb({ ...props }: React.ComponentProps<"nav">) {
8+
return <nav aria-label="breadcrumb" data-slot="breadcrumb" {...props} />
9+
}
10+
11+
function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">) {
12+
return (
13+
<ol
14+
data-slot="breadcrumb-list"
15+
className={cn(
16+
"text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5",
17+
className
18+
)}
19+
{...props}
20+
/>
21+
)
22+
}
23+
24+
function BreadcrumbItem({ className, ...props }: React.ComponentProps<"li">) {
25+
return (
26+
<li
27+
data-slot="breadcrumb-item"
28+
className={cn("inline-flex items-center gap-1.5", className)}
29+
{...props}
30+
/>
31+
)
32+
}
33+
34+
function BreadcrumbLink({
35+
asChild,
36+
className,
37+
...props
38+
}: React.ComponentProps<"a"> & {
39+
asChild?: boolean
40+
}) {
41+
const Comp = asChild ? Slot : "a"
42+
43+
return (
44+
<Comp
45+
data-slot="breadcrumb-link"
46+
className={cn("hover:text-foreground transition-colors", className)}
47+
{...props}
48+
/>
49+
)
50+
}
51+
52+
function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">) {
53+
return (
54+
<span
55+
data-slot="breadcrumb-page"
56+
role="link"
57+
aria-disabled="true"
58+
aria-current="page"
59+
className={cn("text-foreground font-normal", className)}
60+
{...props}
61+
/>
62+
)
63+
}
64+
65+
function BreadcrumbSeparator({
66+
children,
67+
className,
68+
...props
69+
}: React.ComponentProps<"li">) {
70+
return (
71+
<li
72+
data-slot="breadcrumb-separator"
73+
role="presentation"
74+
aria-hidden="true"
75+
className={cn("[&>svg]:size-3.5", className)}
76+
{...props}
77+
>
78+
{children ?? <ChevronRight />}
79+
</li>
80+
)
81+
}
82+
83+
function BreadcrumbEllipsis({
84+
className,
85+
...props
86+
}: React.ComponentProps<"span">) {
87+
return (
88+
<span
89+
data-slot="breadcrumb-ellipsis"
90+
role="presentation"
91+
aria-hidden="true"
92+
className={cn("flex size-9 items-center justify-center", className)}
93+
{...props}
94+
>
95+
<MoreHorizontal className="size-4" />
96+
<span className="sr-only">More</span>
97+
</span>
98+
)
99+
}
100+
101+
export {
102+
Breadcrumb,
103+
BreadcrumbList,
104+
BreadcrumbItem,
105+
BreadcrumbLink,
106+
BreadcrumbPage,
107+
BreadcrumbSeparator,
108+
BreadcrumbEllipsis,
109+
}

src/pages/balances/BalancesPage.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
import { Breadcrumbs } from "@/components/Breadcrumbs";
2+
import { PageTitle } from "@/components/PageTitle";
3+
14
export default function BalancesPage() {
25
return (
36
<>
4-
<h2>Balances</h2>
7+
<Breadcrumbs>Balances</Breadcrumbs>
8+
<PageTitle>Balances</PageTitle>
59
</>
610
)
711
}

src/pages/home/HomePage.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import { PageTitle } from "@/components/PageTitle";
2+
13
export default function HomePage() {
24
return (
35
<>
4-
<h2>Home</h2>
6+
<PageTitle>Home</PageTitle>
57
</>
68
)
79
}

src/pages/quotes/QuotesPage.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
import { Breadcrumbs } from "@/components/Breadcrumbs";
2+
import { PageTitle } from "@/components/PageTitle";
3+
14
export default function QuotesPage() {
25
return (
36
<>
4-
<h2>Quotes</h2>
7+
<Breadcrumbs>Quotes</Breadcrumbs>
8+
<PageTitle>Quotes</PageTitle>
59
</>
610
)
711
}

src/pages/settings/SettingsPage.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
import { Breadcrumbs } from "@/components/Breadcrumbs";
2+
import { PageTitle } from "@/components/PageTitle";
3+
14
export default function SettingsPage() {
25
return (
36
<>
4-
<h2>Settings</h2>
7+
<Breadcrumbs>Settings</Breadcrumbs>
8+
<PageTitle>Settings</PageTitle>
59
</>
610
)
711
}

0 commit comments

Comments
 (0)