Skip to content

Commit af49d1b

Browse files
authored
Merge pull request #58 from KavanBhavsar35/breadcrumb
feat: added breadcrumb component
2 parents 351c1f5 + a61ee86 commit af49d1b

File tree

11 files changed

+341
-0
lines changed

11 files changed

+341
-0
lines changed

components/retroui/Breadcrumb.tsx

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

components/retroui/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ export * from "./Toggle";
2222
export * from "./ToggleGroup";
2323
export * from "./Sonner";
2424
export * from "./Tooltip";
25+
export * from "./Breadcrumb";

config/components.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,10 @@ export const componentConfig: {
108108
name: "tooltip",
109109
filePath: "components/retroui/Tooltip.tsx",
110110
},
111+
breadcrumb: {
112+
name: "breadcrumb",
113+
filePath: "components/retroui/Breadcrumb.tsx",
114+
}
111115
},
112116
examples: {
113117
"accordion-style-default": {
@@ -469,5 +473,33 @@ export const componentConfig: {
469473
() => import("@/preview/components/toggle-group-style-solid"),
470474
),
471475
},
476+
"breadcrumb-style-default": {
477+
name: "breadcrumb-style-default",
478+
filePath: "preview/components/breadcrumb-style-default.tsx",
479+
preview: lazy(
480+
() => import("@/preview/components/breadcrumb-style-default"),
481+
),
482+
},
483+
"breadcrumb-custom-separator": {
484+
name: "breadcrumb-custom-separator",
485+
filePath: "preview/components/breadcrumb-custom-separator.tsx",
486+
preview: lazy(
487+
() => import("@/preview/components/breadcrumb-custom-separator"),
488+
),
489+
},
490+
"breadcrumb-style-collapsed": {
491+
name: "breadcrumb-style-collapsed",
492+
filePath: "preview/components/breadcrumb-style-collapsed.tsx",
493+
preview: lazy(
494+
() => import("@/preview/components/breadcrumb-style-collapsed"),
495+
),
496+
},
497+
"breadcrumb-link-component": {
498+
name: "breadcrumb-link-component",
499+
filePath: "preview/components/breadcrumb-link-component.tsx",
500+
preview: lazy(
501+
() => import("@/preview/components/breadcrumb-link-component"),
502+
),
503+
},
472504
},
473505
};

config/navigation.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export const navConfig: INavigationConfig = {
2828
{ title: "Alert", href: `${componentsRoute}/alert` },
2929
{ title: "Avatar", href: `${componentsRoute}/avatar` },
3030
{ title: "Badge", href: `${componentsRoute}/badge` },
31+
{ title: "Breadcrumb", href: `${componentsRoute}/breadcrumb` },
3132
{ title: "Button", href: `${componentsRoute}/button` },
3233
{ title: "Card", href: `${componentsRoute}/card` },
3334
{ title: "Checkbox", href: `${componentsRoute}/checkbox` },
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
title: Breadcrumb
3+
description: A navigation component that shows users where they are within a hierarchy.
4+
lastUpdated: 12 May, 2025
5+
---
6+
7+
<ComponentShowcase name="breadcrumb-style-default" />
8+
<br />
9+
<br />
10+
11+
<ComponentInstall>
12+
<ComponentInstall.Cli>
13+
```sh
14+
npx shadcn@latest add "https://retroui.dev/r/breadcrumb.json"
15+
```
16+
</ComponentInstall.Cli>
17+
<ComponentInstall.Manual>
18+
#### 1. Install dependencies:
19+
20+
```sh
21+
npm install lucide-react class-variance-authority
22+
````
23+
24+
<br />
25+
26+
#### 2. Copy the code 👇 into your project:
27+
28+
<ComponentSource name="breadcrumb" />
29+
30+
</ComponentInstall.Manual>
31+
</ComponentInstall>
32+
33+
<br />
34+
<br />
35+
36+
## Examples
37+
38+
### Default
39+
40+
<hr />
41+
<br />
42+
<ComponentShowcase name="breadcrumb-style-default" />
43+
<br />
44+
<br />
45+
46+
### Custom Separator
47+
48+
<hr />
49+
<br />
50+
<ComponentShowcase name="breadcrumb-custom-separator" />
51+
<br />
52+
<br />
53+
54+
### Collapsed
55+
56+
<hr />
57+
<br />
58+
<ComponentShowcase name="breadcrumb-style-collapsed" />
59+
<br />
60+
<br />
61+
62+
### Link Component
63+
64+
<hr />
65+
<br />
66+
<ComponentShowcase name="breadcrumb-link-component" />
67+
<br />
68+
<br />

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"@radix-ui/react-radio-group": "^1.2.3",
2323
"@radix-ui/react-select": "^2.1.6",
2424
"@radix-ui/react-slider": "^1.2.4",
25+
"@radix-ui/react-slot": "^1.2.2",
2526
"@radix-ui/react-switch": "^1.1.3",
2627
"@radix-ui/react-toggle": "^1.1.6",
2728
"@radix-ui/react-toggle-group": "^1.1.7",

pnpm-lock.yaml

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { Breadcrumb } from "@/components/retroui/Breadcrumb";
2+
import { Slash } from "lucide-react";
3+
4+
export default function BreadcrumbCustomSeparator() {
5+
return (
6+
<Breadcrumb>
7+
<Breadcrumb.List>
8+
<Breadcrumb.Item>
9+
<Breadcrumb.Link href="/">Home</Breadcrumb.Link>
10+
</Breadcrumb.Item>
11+
<Breadcrumb.Separator>
12+
<Slash />
13+
</Breadcrumb.Separator>
14+
<Breadcrumb.Item>
15+
<Breadcrumb.Link href="/components">Components</Breadcrumb.Link>
16+
</Breadcrumb.Item>
17+
<Breadcrumb.Separator>
18+
<Slash />
19+
</Breadcrumb.Separator>
20+
<Breadcrumb.Item>
21+
<Breadcrumb.Page>Breadcrumb</Breadcrumb.Page>
22+
</Breadcrumb.Item>
23+
</Breadcrumb.List>
24+
</Breadcrumb>
25+
);
26+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import Link from "next/link"
2+
3+
import { Breadcrumb } from "@/components/retroui/Breadcrumb"
4+
5+
export default function BreadcrumbLinkComponent() {
6+
return (
7+
<Breadcrumb>
8+
<Breadcrumb.List>
9+
<Breadcrumb.Item>
10+
<Breadcrumb.Link asChild>
11+
<Link href="/">Home</Link>
12+
</Breadcrumb.Link>
13+
</Breadcrumb.Item>
14+
<Breadcrumb.Separator />
15+
<Breadcrumb.Item>
16+
<Breadcrumb.Link asChild>
17+
<Link href="/docs/components">Components</Link>
18+
</Breadcrumb.Link>
19+
</Breadcrumb.Item>
20+
<Breadcrumb.Separator />
21+
<Breadcrumb.Item>
22+
<Breadcrumb.Page>Breadcrumb</Breadcrumb.Page>
23+
</Breadcrumb.Item>
24+
</Breadcrumb.List>
25+
</Breadcrumb>
26+
)
27+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import Link from "next/link"
2+
3+
import { Breadcrumb } from "@/components/retroui/Breadcrumb";
4+
5+
export default function BreadcrumbCollapsed() {
6+
return (
7+
<Breadcrumb>
8+
<Breadcrumb.List>
9+
<Breadcrumb.Item>
10+
<Breadcrumb.Link asChild>
11+
<Link href="/">Home</Link>
12+
</Breadcrumb.Link>
13+
</Breadcrumb.Item>
14+
<Breadcrumb.Item>
15+
<Breadcrumb.Ellipsis />
16+
</Breadcrumb.Item>
17+
<Breadcrumb.Separator />
18+
<Breadcrumb.Item>
19+
<Breadcrumb.Link asChild>
20+
<Link href="/docs/components">Components</Link>
21+
</Breadcrumb.Link>
22+
</Breadcrumb.Item>
23+
<Breadcrumb.Separator />
24+
<Breadcrumb.Item>
25+
<Breadcrumb.Page>Breadcrumb</Breadcrumb.Page>
26+
</Breadcrumb.Item>
27+
</Breadcrumb.List>
28+
</Breadcrumb>
29+
)
30+
}

0 commit comments

Comments
 (0)