From 7f0af435e14e2e1121f855d5762a3659ef0b51e6 Mon Sep 17 00:00:00 2001 From: its-monotype Date: Thu, 7 Mar 2024 19:42:39 +0100 Subject: [PATCH 01/29] feat(breadcrumb): add breadcrumb component (#133) * feat(breadcrumb): add breadcrumb component * refactor(breadcrumb): improve variable name and simplify object key passing * refactor(breadcrumb): remove unnecessary color transition * chore(breadcrumb): wip * chore: build registry * feat: update breadcrumb component * fix(breadcrumb): update code highlight * chore(www): remove menu --------- Co-authored-by: shadcn --- apps/www/__registry__/index.tsx | 98 +++++++++ .../content/docs/components/breadcrumb.mdx | 190 ++++++++++++++++++ apps/www/lib/utils.ts | 1 + apps/www/public/registry/index.json | 10 + .../registry/styles/default/breadcrumb.json | 13 ++ .../public/registry/styles/default/toast.json | 4 +- .../registry/styles/new-york/breadcrumb.json | 13 ++ .../registry/styles/new-york/toast.json | 4 +- .../default/example/breadcrumb-demo.tsx | 49 +++++ .../default/example/breadcrumb-dropdown.tsx | 50 +++++ .../default/example/breadcrumb-ellipsis.tsx | 39 ++++ .../default/example/breadcrumb-link.tsx | 34 ++++ .../default/example/breadcrumb-responsive.tsx | 133 ++++++++++++ .../default/example/breadcrumb-separator.tsx | 34 ++++ apps/www/registry/default/ui/breadcrumb.tsx | 115 +++++++++++ .../new-york/example/breadcrumb-demo.tsx | 49 +++++ .../new-york/example/breadcrumb-dropdown.tsx | 50 +++++ .../new-york/example/breadcrumb-ellipsis.tsx | 39 ++++ .../new-york/example/breadcrumb-link.tsx | 34 ++++ .../example/breadcrumb-responsive.tsx | 135 +++++++++++++ .../new-york/example/breadcrumb-separator.tsx | 34 ++++ apps/www/registry/new-york/ui/breadcrumb.tsx | 115 +++++++++++ apps/www/registry/registry.ts | 42 ++++ 23 files changed, 1281 insertions(+), 4 deletions(-) create mode 100644 apps/www/content/docs/components/breadcrumb.mdx create mode 100644 apps/www/public/registry/styles/default/breadcrumb.json create mode 100644 apps/www/public/registry/styles/new-york/breadcrumb.json create mode 100644 apps/www/registry/default/example/breadcrumb-demo.tsx create mode 100644 apps/www/registry/default/example/breadcrumb-dropdown.tsx create mode 100644 apps/www/registry/default/example/breadcrumb-ellipsis.tsx create mode 100644 apps/www/registry/default/example/breadcrumb-link.tsx create mode 100644 apps/www/registry/default/example/breadcrumb-responsive.tsx create mode 100644 apps/www/registry/default/example/breadcrumb-separator.tsx create mode 100644 apps/www/registry/default/ui/breadcrumb.tsx create mode 100644 apps/www/registry/new-york/example/breadcrumb-demo.tsx create mode 100644 apps/www/registry/new-york/example/breadcrumb-dropdown.tsx create mode 100644 apps/www/registry/new-york/example/breadcrumb-ellipsis.tsx create mode 100644 apps/www/registry/new-york/example/breadcrumb-link.tsx create mode 100644 apps/www/registry/new-york/example/breadcrumb-responsive.tsx create mode 100644 apps/www/registry/new-york/example/breadcrumb-separator.tsx create mode 100644 apps/www/registry/new-york/ui/breadcrumb.tsx diff --git a/apps/www/__registry__/index.tsx b/apps/www/__registry__/index.tsx index d05995ba644..0d1ea0d7f05 100644 --- a/apps/www/__registry__/index.tsx +++ b/apps/www/__registry__/index.tsx @@ -47,6 +47,13 @@ export const Index: Record = { component: React.lazy(() => import("@/registry/default/ui/badge")), files: ["registry/default/ui/badge.tsx"], }, + "breadcrumb": { + name: "breadcrumb", + type: "components:ui", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/default/ui/breadcrumb")), + files: ["registry/default/ui/breadcrumb.tsx"], + }, "button": { name: "button", type: "components:ui", @@ -376,6 +383,48 @@ export const Index: Record = { component: React.lazy(() => import("@/registry/default/example/badge-secondary")), files: ["registry/default/example/badge-secondary.tsx"], }, + "breadcrumb-demo": { + name: "breadcrumb-demo", + type: "components:example", + registryDependencies: ["breadcrumb"], + component: React.lazy(() => import("@/registry/default/example/breadcrumb-demo")), + files: ["registry/default/example/breadcrumb-demo.tsx"], + }, + "breadcrumb-separator": { + name: "breadcrumb-separator", + type: "components:example", + registryDependencies: ["breadcrumb"], + component: React.lazy(() => import("@/registry/default/example/breadcrumb-separator")), + files: ["registry/default/example/breadcrumb-separator.tsx"], + }, + "breadcrumb-dropdown": { + name: "breadcrumb-dropdown", + type: "components:example", + registryDependencies: ["breadcrumb"], + component: React.lazy(() => import("@/registry/default/example/breadcrumb-dropdown")), + files: ["registry/default/example/breadcrumb-dropdown.tsx"], + }, + "breadcrumb-ellipsis": { + name: "breadcrumb-ellipsis", + type: "components:example", + registryDependencies: ["breadcrumb"], + component: React.lazy(() => import("@/registry/default/example/breadcrumb-ellipsis")), + files: ["registry/default/example/breadcrumb-ellipsis"], + }, + "breadcrumb-responsive": { + name: "breadcrumb-responsive", + type: "components:example", + registryDependencies: ["breadcrumb"], + component: React.lazy(() => import("@/registry/default/example/breadcrumb-responsive")), + files: ["registry/default/example/breadcrumb-responsive"], + }, + "breadcrumb-link": { + name: "breadcrumb-link", + type: "components:example", + registryDependencies: ["breadcrumb"], + component: React.lazy(() => import("@/registry/default/example/breadcrumb-link")), + files: ["registry/default/example/breadcrumb-link"], + }, "button-demo": { name: "button-demo", type: "components:example", @@ -1273,6 +1322,13 @@ export const Index: Record = { component: React.lazy(() => import("@/registry/new-york/ui/badge")), files: ["registry/new-york/ui/badge.tsx"], }, + "breadcrumb": { + name: "breadcrumb", + type: "components:ui", + registryDependencies: undefined, + component: React.lazy(() => import("@/registry/new-york/ui/breadcrumb")), + files: ["registry/new-york/ui/breadcrumb.tsx"], + }, "button": { name: "button", type: "components:ui", @@ -1602,6 +1658,48 @@ export const Index: Record = { component: React.lazy(() => import("@/registry/new-york/example/badge-secondary")), files: ["registry/new-york/example/badge-secondary.tsx"], }, + "breadcrumb-demo": { + name: "breadcrumb-demo", + type: "components:example", + registryDependencies: ["breadcrumb"], + component: React.lazy(() => import("@/registry/new-york/example/breadcrumb-demo")), + files: ["registry/new-york/example/breadcrumb-demo.tsx"], + }, + "breadcrumb-separator": { + name: "breadcrumb-separator", + type: "components:example", + registryDependencies: ["breadcrumb"], + component: React.lazy(() => import("@/registry/new-york/example/breadcrumb-separator")), + files: ["registry/new-york/example/breadcrumb-separator.tsx"], + }, + "breadcrumb-dropdown": { + name: "breadcrumb-dropdown", + type: "components:example", + registryDependencies: ["breadcrumb"], + component: React.lazy(() => import("@/registry/new-york/example/breadcrumb-dropdown")), + files: ["registry/new-york/example/breadcrumb-dropdown.tsx"], + }, + "breadcrumb-ellipsis": { + name: "breadcrumb-ellipsis", + type: "components:example", + registryDependencies: ["breadcrumb"], + component: React.lazy(() => import("@/registry/new-york/example/breadcrumb-ellipsis")), + files: ["registry/new-york/example/breadcrumb-ellipsis"], + }, + "breadcrumb-responsive": { + name: "breadcrumb-responsive", + type: "components:example", + registryDependencies: ["breadcrumb"], + component: React.lazy(() => import("@/registry/new-york/example/breadcrumb-responsive")), + files: ["registry/new-york/example/breadcrumb-responsive"], + }, + "breadcrumb-link": { + name: "breadcrumb-link", + type: "components:example", + registryDependencies: ["breadcrumb"], + component: React.lazy(() => import("@/registry/new-york/example/breadcrumb-link")), + files: ["registry/new-york/example/breadcrumb-link"], + }, "button-demo": { name: "button-demo", type: "components:example", diff --git a/apps/www/content/docs/components/breadcrumb.mdx b/apps/www/content/docs/components/breadcrumb.mdx new file mode 100644 index 00000000000..2218280c620 --- /dev/null +++ b/apps/www/content/docs/components/breadcrumb.mdx @@ -0,0 +1,190 @@ +--- +title: Breadcrumb +description: Displays the path to the current resource using a hierarchy of links. +component: true +--- + + + +## Installation + + + + + CLI + Manual + + + +```bash +npx shadcn-ui@latest add breadcrumb +``` + + + + + + + +Copy and paste the following code into your project. + + + +Update the import paths to match your project setup. + + + + + + + +## Usage + +```tsx +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbLink, + BreadcrumbList, + BreadcrumbPage, + BreadcrumbSeparator, +} from "@/components/ui/breadcrumb" +``` + +```tsx + + + + Home + + + + Components + + + + Breadcrumb + + + +``` + +## Examples + +### Custom separator + +Use a custom component as `children` for `` to create a custom separator. + + + +```tsx showLineNumbers {1,10-12} +import { Slash } from "lucide-react" + +... + + + + + Home + + + + + + Components + + + +``` + +--- + +### Dropdown + +You can compose `` with a `` to create a dropdown in the breadcrumb. + + + +```tsx showLineNumbers {1-6,11-21} +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu" + +... + + + + + Components + + + + Documentation + Themes + GitHub + + + +``` + +--- + +### Collapsed + +We provide a `` component to show a collapsed state when the breadcrumb is too long. + + + +```tsx showLineNumbers {1,9} +import { BreadcrumbEllipsis } from "@/components/ui/breadcrumb" + +... + + + + {/* ... */} + + + + {/* ... */} + + +``` + +--- + +### Link component + +To use a custom link component from your routing library, you can use the `asChild` prop on ``. + + + +```tsx showLineNumbers {1,8-10} +import { Link } from "next/link" + +... + + + + + + Home + + + {/* ... */} + + +``` + +--- + +### Responsive + +Here's an example of a responsive breadcrumb that composes `` with ``, ``, and ``. + +It displays a dropdown on desktop and a drawer on mobile. + + diff --git a/apps/www/lib/utils.ts b/apps/www/lib/utils.ts index 3a8eda3d062..15548471f2b 100644 --- a/apps/www/lib/utils.ts +++ b/apps/www/lib/utils.ts @@ -1,3 +1,4 @@ +import * as React from "react" import { clsx, type ClassValue } from "clsx" import { twMerge } from "tailwind-merge" diff --git a/apps/www/public/registry/index.json b/apps/www/public/registry/index.json index 4e61980c71d..8464d10c14a 100644 --- a/apps/www/public/registry/index.json +++ b/apps/www/public/registry/index.json @@ -56,6 +56,16 @@ ], "type": "components:ui" }, + { + "name": "breadcrumb", + "dependencies": [ + "@radix-ui/react-slot" + ], + "files": [ + "ui/breadcrumb.tsx" + ], + "type": "components:ui" + }, { "name": "button", "dependencies": [ diff --git a/apps/www/public/registry/styles/default/breadcrumb.json b/apps/www/public/registry/styles/default/breadcrumb.json new file mode 100644 index 00000000000..441bf64231f --- /dev/null +++ b/apps/www/public/registry/styles/default/breadcrumb.json @@ -0,0 +1,13 @@ +{ + "name": "breadcrumb", + "dependencies": [ + "@radix-ui/react-slot" + ], + "files": [ + { + "name": "breadcrumb.tsx", + "content": "import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { ChevronRight, MoreHorizontal } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst Breadcrumb = React.forwardRef<\n HTMLElement,\n React.ComponentPropsWithoutRef<\"nav\"> & {\n separator?: React.ReactNode\n }\n>(({ ...props }, ref) =>