feat: breadcrumb component (#405)
* feat: adding breadcrumb component, resolves #395 * fix: revert kbd component in main layout * feat: add slot for `BreadcrumbEllipsis` icons too build registry, bump radix-vue * refactor: using primitive instead of computed * chore: update --------- Co-authored-by: Sadegh Barati <sadeghbaratiwork@gmail.com>
This commit is contained in:
parent
454ecf0df7
commit
4d08adc81e
|
|
@ -158,6 +158,12 @@ export const docsConfig: DocsConfig = {
|
|||
href: '/docs/components/badge',
|
||||
items: [],
|
||||
},
|
||||
{
|
||||
title: 'Breadcrumb',
|
||||
href: '/docs/components/breadcrumb',
|
||||
items: [],
|
||||
label: 'New',
|
||||
},
|
||||
{
|
||||
title: 'Button',
|
||||
href: '/docs/components/button',
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
import { useMagicKeys, useToggle } from '@vueuse/core'
|
||||
import { onMounted, ref, watch } from 'vue'
|
||||
import { Content, useData, useRoute, useRouter } from 'vitepress'
|
||||
import { SearchIcon } from 'lucide-vue-next'
|
||||
import { type NavItem, docsConfig } from '../config/docs'
|
||||
import Logo from '../components/Logo.vue'
|
||||
import MobileNav from '../components/MobileNav.vue'
|
||||
|
|
@ -119,11 +118,11 @@ watch(() => $route.path, (n) => {
|
|||
class="relative h-8 w-full justify-start rounded-[0.5rem] bg-background text-sm font-normal text-muted-foreground shadow-none sm:pr-12 md:w-40 lg:w-64"
|
||||
@click="isOpen = true"
|
||||
>
|
||||
<span className="hidden lg:inline-flex">Search documentation...</span>
|
||||
<span className="inline-flex lg:hidden">Search...</span>
|
||||
<kbd className="pointer-events-none absolute right-[0.3rem] top-[0.3rem] hidden h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex">
|
||||
<span className="text-xs">⌘</span>K
|
||||
</kbd>
|
||||
<span class="hidden lg:inline-flex">Search documentation...</span>
|
||||
<span class="inline-flex lg:hidden">Search...</span>
|
||||
<Kbd class="pointer-events-none absolute right-[0.3rem] top-[0.3rem] hidden h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex">
|
||||
<span class="text-xs">⌘</span>K
|
||||
</Kbd>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -73,6 +73,48 @@ export const Index = {
|
|||
component: () => import("../src/lib/registry/default/example/BadgeSecondaryDemo.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/default/example/BadgeSecondaryDemo.vue"],
|
||||
},
|
||||
"BreadcrumbDemo": {
|
||||
name: "BreadcrumbDemo",
|
||||
type: "components:example",
|
||||
registryDependencies: ["breadcrumb","dropdown-menu"],
|
||||
component: () => import("../src/lib/registry/default/example/BreadcrumbDemo.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/default/example/BreadcrumbDemo.vue"],
|
||||
},
|
||||
"BreadcrumbDropdown": {
|
||||
name: "BreadcrumbDropdown",
|
||||
type: "components:example",
|
||||
registryDependencies: ["breadcrumb","dropdown-menu"],
|
||||
component: () => import("../src/lib/registry/default/example/BreadcrumbDropdown.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/default/example/BreadcrumbDropdown.vue"],
|
||||
},
|
||||
"BreadcrumbEllipsisDemo": {
|
||||
name: "BreadcrumbEllipsisDemo",
|
||||
type: "components:example",
|
||||
registryDependencies: ["breadcrumb"],
|
||||
component: () => import("../src/lib/registry/default/example/BreadcrumbEllipsisDemo.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/default/example/BreadcrumbEllipsisDemo.vue"],
|
||||
},
|
||||
"BreadcrumbLinkDemo": {
|
||||
name: "BreadcrumbLinkDemo",
|
||||
type: "components:example",
|
||||
registryDependencies: ["breadcrumb"],
|
||||
component: () => import("../src/lib/registry/default/example/BreadcrumbLinkDemo.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/default/example/BreadcrumbLinkDemo.vue"],
|
||||
},
|
||||
"BreadcrumbResponsive": {
|
||||
name: "BreadcrumbResponsive",
|
||||
type: "components:example",
|
||||
registryDependencies: ["breadcrumb","button","drawer","dropdown-menu"],
|
||||
component: () => import("../src/lib/registry/default/example/BreadcrumbResponsive.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/default/example/BreadcrumbResponsive.vue"],
|
||||
},
|
||||
"BreadcrumbSeparatorDemo": {
|
||||
name: "BreadcrumbSeparatorDemo",
|
||||
type: "components:example",
|
||||
registryDependencies: ["breadcrumb"],
|
||||
component: () => import("../src/lib/registry/default/example/BreadcrumbSeparatorDemo.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/default/example/BreadcrumbSeparatorDemo.vue"],
|
||||
},
|
||||
"ButtonAsChildDemo": {
|
||||
name: "ButtonAsChildDemo",
|
||||
type: "components:example",
|
||||
|
|
@ -1131,6 +1173,48 @@ export const Index = {
|
|||
component: () => import("../src/lib/registry/new-york/example/BadgeSecondaryDemo.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/new-york/example/BadgeSecondaryDemo.vue"],
|
||||
},
|
||||
"BreadcrumbDemo": {
|
||||
name: "BreadcrumbDemo",
|
||||
type: "components:example",
|
||||
registryDependencies: ["breadcrumb","dropdown-menu"],
|
||||
component: () => import("../src/lib/registry/new-york/example/BreadcrumbDemo.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/new-york/example/BreadcrumbDemo.vue"],
|
||||
},
|
||||
"BreadcrumbDropdown": {
|
||||
name: "BreadcrumbDropdown",
|
||||
type: "components:example",
|
||||
registryDependencies: ["breadcrumb","dropdown-menu"],
|
||||
component: () => import("../src/lib/registry/new-york/example/BreadcrumbDropdown.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/new-york/example/BreadcrumbDropdown.vue"],
|
||||
},
|
||||
"BreadcrumbEllipsisDemo": {
|
||||
name: "BreadcrumbEllipsisDemo",
|
||||
type: "components:example",
|
||||
registryDependencies: ["breadcrumb"],
|
||||
component: () => import("../src/lib/registry/new-york/example/BreadcrumbEllipsisDemo.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/new-york/example/BreadcrumbEllipsisDemo.vue"],
|
||||
},
|
||||
"BreadcrumbLinkDemo": {
|
||||
name: "BreadcrumbLinkDemo",
|
||||
type: "components:example",
|
||||
registryDependencies: ["breadcrumb"],
|
||||
component: () => import("../src/lib/registry/new-york/example/BreadcrumbLinkDemo.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/new-york/example/BreadcrumbLinkDemo.vue"],
|
||||
},
|
||||
"BreadcrumbResponsive": {
|
||||
name: "BreadcrumbResponsive",
|
||||
type: "components:example",
|
||||
registryDependencies: ["breadcrumb","button","drawer","dropdown-menu"],
|
||||
component: () => import("../src/lib/registry/new-york/example/BreadcrumbResponsive.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/new-york/example/BreadcrumbResponsive.vue"],
|
||||
},
|
||||
"BreadcrumbSeparatorDemo": {
|
||||
name: "BreadcrumbSeparatorDemo",
|
||||
type: "components:example",
|
||||
registryDependencies: ["breadcrumb"],
|
||||
component: () => import("../src/lib/registry/new-york/example/BreadcrumbSeparatorDemo.vue").then((m) => m.default),
|
||||
files: ["../src/lib/registry/new-york/example/BreadcrumbSeparatorDemo.vue"],
|
||||
},
|
||||
"ButtonAsChildDemo": {
|
||||
name: "ButtonAsChildDemo",
|
||||
type: "components:example",
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
"embla-carousel-autoplay": "^8.0.0",
|
||||
"embla-carousel-vue": "^8.0.0",
|
||||
"lucide-vue-next": "^0.350.0",
|
||||
"radix-vue": "^1.5.0",
|
||||
"radix-vue": "^1.5.2",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"v-calendar": "^3.1.2",
|
||||
"vaul-vue": "^0.1.0",
|
||||
|
|
|
|||
205
apps/www/src/content/docs/components/breadcrumb.md
Normal file
205
apps/www/src/content/docs/components/breadcrumb.md
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
---
|
||||
title: Breadcrumb
|
||||
description: Displays the path to the current resource using a hierarchy of links.
|
||||
---
|
||||
|
||||
<ComponentPreview name="BreadcrumbDemo" class="[&_.preview]:p-2" />
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
npx shadcn-ui@latest add breadcrumb
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from '@/lib/components/ui/breadcrumb'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="/">
|
||||
Home
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="/components">
|
||||
Components
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Custom separator
|
||||
|
||||
Use a custom component as `slot` for `<BreadcrumbSeparator />` to create a custom separator.
|
||||
|
||||
<ComponentPreview name="BreadcrumbSeparatorDemo" />
|
||||
|
||||
```vue showLineNumbers {2,20-22}
|
||||
<script setup lang="ts">
|
||||
import { Slash } from 'lucide-react'
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbSeparator,
|
||||
} from '@/lib/components/ui/breadcrumb'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="/">
|
||||
Home
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator>
|
||||
<Slash />
|
||||
</BreadcrumbSeparator>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="/components">
|
||||
Components
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Dropdown
|
||||
|
||||
You can compose `<BreadcrumbItem />` with a `<DropdownMenu />` to create a dropdown in the breadcrumb.
|
||||
|
||||
<ComponentPreview name="BreadcrumbDropdown" class="[&_.preview]:p-2" />
|
||||
|
||||
```vue showLineNumbers {2-7,16-26}
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/lib/components/ui/dropdown-menu'
|
||||
|
||||
import { BreadcrumbItem } from '@/lib/components/ui/breadcrumb'
|
||||
|
||||
import ChevronDownIcon from '~icons/radix-icons/chevron-down'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BreadcrumbItem>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger class="flex items-center gap-1">
|
||||
Components
|
||||
<ChevronDownIcon />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start">
|
||||
<DropdownMenuItem>Documentation</DropdownMenuItem>
|
||||
<DropdownMenuItem>Themes</DropdownMenuItem>
|
||||
<DropdownMenuItem>GitHub</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</BreadcrumbItem>
|
||||
</template>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Collapsed
|
||||
|
||||
We provide a `<BreadcrumbEllipsis />` component to show a collapsed state when the breadcrumb is too long.
|
||||
|
||||
<ComponentPreview name="BreadcrumbEllipsisDemo" class="[&_.preview]:p-2" />
|
||||
|
||||
```vue showLineNumbers {3,15}
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbEllipsis,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbList,
|
||||
} from '@/lib/components/ui/breadcrumb'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<!-- ... -->
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbEllipsis />
|
||||
</BreadcrumbItem>
|
||||
<!-- ... -->
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Link component
|
||||
|
||||
To use a custom link component from your routing library, you can use the `asChild` prop on `<BreadcrumbLink />`.
|
||||
|
||||
<ComponentPreview name="BreadcrumbLinkDemo" />
|
||||
|
||||
```vue showLineNumbers {15-19}
|
||||
<script setup lang="ts">
|
||||
import { RouterLink } from 'vue-router'
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
} from '@/lib/components/ui/breadcrumb'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink as-child>
|
||||
<RouterLink to="/">
|
||||
Home
|
||||
</RouterLink>
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<!-- -->
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Responsive
|
||||
|
||||
Here's an example of a responsive breadcrumb that composes `<BreadcrumbItem />` with `<BreadcrumbEllipsis />`, `<DropdownMenu />`, and `<Drawer />`.
|
||||
|
||||
It displays a dropdown on desktop and a drawer on mobile.
|
||||
|
||||
<ComponentPreview name="BreadcrumbResponsive" class="[&_.preview]:p-2" />
|
||||
53
apps/www/src/lib/registry/default/example/BreadcrumbDemo.vue
Normal file
53
apps/www/src/lib/registry/default/example/BreadcrumbDemo.vue
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<script lang="ts" setup>
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbEllipsis,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from '@/lib/registry/default/ui/breadcrumb'
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/lib/registry/default/ui/dropdown-menu'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="/">
|
||||
Home
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger class="flex items-center gap-1">
|
||||
<BreadcrumbEllipsis class="h-4 w-4" />
|
||||
<span class="sr-only">Toggle menu</span>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start">
|
||||
<DropdownMenuItem>Documentation</DropdownMenuItem>
|
||||
<DropdownMenuItem>Themes</DropdownMenuItem>
|
||||
<DropdownMenuItem>GitHub</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="/docs/components/accordion.html">
|
||||
Components
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<script lang="ts" setup>
|
||||
import { ChevronDown, Slash } from 'lucide-vue-next'
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from '@/lib/registry/default/ui/breadcrumb'
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/lib/registry/default/ui/dropdown-menu'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="/">
|
||||
Home
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator>
|
||||
<Slash />
|
||||
</BreadcrumbSeparator>
|
||||
<BreadcrumbItem>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger class="flex items-center gap-1">
|
||||
Components
|
||||
<ChevronDown class="h-4 w-4" />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start">
|
||||
<DropdownMenuItem>Documentation</DropdownMenuItem>
|
||||
<DropdownMenuItem>Themes</DropdownMenuItem>
|
||||
<DropdownMenuItem>GitHub</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator>
|
||||
<Slash />
|
||||
</BreadcrumbSeparator>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<script lang="ts" setup>
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbEllipsis,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from '@/lib/registry/default/ui/breadcrumb'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink as-child>
|
||||
<a href="/">
|
||||
Home
|
||||
</a>
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbEllipsis />
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink as-child>
|
||||
<a href="/docs/components/accordion.html">
|
||||
Components
|
||||
</a>
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<script lang="ts" setup>
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from '@/lib/registry/default/ui/breadcrumb'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink>
|
||||
<a href="/">
|
||||
Home
|
||||
</a>
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink>
|
||||
<a href="/docs/components/accordion.html">
|
||||
Components
|
||||
</a>
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
<script lang="ts" setup>
|
||||
import { useMediaQuery } from '@vueuse/core'
|
||||
import { computed, ref } from 'vue'
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbEllipsis,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from '@/lib/registry/default/ui/breadcrumb'
|
||||
import { Button } from '@/lib/registry/default/ui/button'
|
||||
import {
|
||||
Drawer,
|
||||
DrawerClose,
|
||||
DrawerContent,
|
||||
DrawerDescription,
|
||||
DrawerFooter,
|
||||
DrawerHeader,
|
||||
DrawerTitle,
|
||||
DrawerTrigger,
|
||||
} from '@/lib/registry/default/ui/drawer'
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/lib/registry/default/ui/dropdown-menu'
|
||||
|
||||
const isDesktop = useMediaQuery('(min-width: 768px)')
|
||||
const isOpen = ref(false)
|
||||
const items = ref([
|
||||
{ href: '#', label: 'Home' },
|
||||
{ href: '#', label: 'Documentation' },
|
||||
{ href: '#', label: 'Building Your Application' },
|
||||
{ href: '#', label: 'Data Fetching' },
|
||||
{ label: 'Caching and Revalidating' },
|
||||
])
|
||||
|
||||
const itemsToDisplay = 3
|
||||
const firstLabel = computed(() => items.value[0]?.label)
|
||||
|
||||
const allButLastTwoItems = computed(() => items.value.slice(1, -2))
|
||||
const remainingItems = computed(() => items.value.slice(-itemsToDisplay + 1))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="{items[0].href}">
|
||||
{{ firstLabel }}
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<template v-if="items.length > itemsToDisplay">
|
||||
<BreadcrumbItem>
|
||||
<DropdownMenu v-if="isDesktop" v-model:open="isOpen">
|
||||
<DropdownMenuTrigger
|
||||
class="flex items-center gap-1"
|
||||
aria-label="Toggle menu"
|
||||
>
|
||||
<BreadcrumbEllipsis class="h-4 w-4" />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start">
|
||||
<DropdownMenuItem v-for="item of allButLastTwoItems" :key="item.label">
|
||||
<a :href="item.href || '#'">
|
||||
{{ item.label }}
|
||||
</a>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<Drawer v-else v-model:open="isOpen">
|
||||
<DrawerTrigger aria-label="Toggle Menu">
|
||||
<BreadcrumbEllipsis class="h-4 w-4" />
|
||||
</DrawerTrigger>
|
||||
<DrawerContent>
|
||||
<DrawerHeader class="text-left">
|
||||
<DrawerTitle>Navigate to</DrawerTitle>
|
||||
<DrawerDescription>
|
||||
Select a page to navigate to.
|
||||
</DrawerDescription>
|
||||
</DrawerHeader>
|
||||
<div class="grid gap-1 px-4">
|
||||
<a
|
||||
v-for="item of allButLastTwoItems"
|
||||
:key="item.label"
|
||||
:href="item.href"
|
||||
class="py-1 text-sm"
|
||||
>
|
||||
{{ item.label }}
|
||||
</a>
|
||||
</div>
|
||||
<DrawerFooter class="pt-4">
|
||||
<DrawerClose as-child>
|
||||
<Button variant="outline">
|
||||
Close
|
||||
</Button>
|
||||
</DrawerClose>
|
||||
</DrawerFooter>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
</template>
|
||||
<BreadcrumbItem v-for=" item of remainingItems" :key="item.label">
|
||||
<template v-if="item.href">
|
||||
<BreadcrumbLink
|
||||
as-child
|
||||
class="max-w-20 truncate md:max-w-none"
|
||||
>
|
||||
<a :href="item.href">
|
||||
{{ item.label }}
|
||||
</a>
|
||||
</BreadcrumbLink>
|
||||
<BreadcrumbSeparator />
|
||||
</template>
|
||||
<BreadcrumbPage v-else class="max-w-20 truncate md:max-w-none">
|
||||
{{ item.label }}
|
||||
</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<script lang="ts" setup>
|
||||
import { Slash } from 'lucide-vue-next'
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from '@/lib/registry/default/ui/breadcrumb'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="/">
|
||||
Home
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator>
|
||||
<Slash />
|
||||
</BreadcrumbSeparator>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="/docs/components/accordion.html">
|
||||
Components
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator>
|
||||
<Slash />
|
||||
</BreadcrumbSeparator>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav aria-label="breadcrumb" :class="props.class">
|
||||
<slot />
|
||||
</nav>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { MoreHorizontal } from 'lucide-vue-next'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span
|
||||
role="presentation"
|
||||
aria-hidden="true"
|
||||
:class="cn('flex h-9 w-9 items-center justify-center', props.class)"
|
||||
>
|
||||
<slot>
|
||||
<MoreHorizontal class="h-4 w-4" />
|
||||
</slot>
|
||||
<span class="sr-only">More</span>
|
||||
</span>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li
|
||||
:class="cn('inline-flex items-center gap-1.5', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</li>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { Primitive, type PrimitiveProps } from 'radix-vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = withDefaults(defineProps<PrimitiveProps & { class?: HTMLAttributes['class'] }>(), {
|
||||
as: 'a',
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Primitive
|
||||
:as="as"
|
||||
:as-child="asChild"
|
||||
:class="cn('transition-colors hover:text-foreground', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</Primitive>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ol
|
||||
:class="cn('flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</ol>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span
|
||||
role="link"
|
||||
aria-disabled="true"
|
||||
aria-current="page"
|
||||
:class="cn('font-normal text-foreground', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</span>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { ChevronRight } from 'lucide-vue-next'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li
|
||||
role="presentation"
|
||||
aria-hidden="true"
|
||||
:class="cn('[&>svg]:size-3.5', props.class)"
|
||||
>
|
||||
<slot>
|
||||
<ChevronRight />
|
||||
</slot>
|
||||
</li>
|
||||
</template>
|
||||
7
apps/www/src/lib/registry/default/ui/breadcrumb/index.ts
Normal file
7
apps/www/src/lib/registry/default/ui/breadcrumb/index.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
export { default as Breadcrumb } from './Breadcrumb.vue'
|
||||
export { default as BreadcrumbEllipsis } from './BreadcrumbEllipsis.vue'
|
||||
export { default as BreadcrumbItem } from './BreadcrumbItem.vue'
|
||||
export { default as BreadcrumbLink } from './BreadcrumbLink.vue'
|
||||
export { default as BreadcrumbList } from './BreadcrumbList.vue'
|
||||
export { default as BreadcrumbPage } from './BreadcrumbPage.vue'
|
||||
export { default as BreadcrumbSeparator } from './BreadcrumbSeparator.vue'
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
<script lang="ts" setup>
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbEllipsis,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from '@/lib/registry/new-york/ui/breadcrumb'
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/lib/registry/new-york/ui/dropdown-menu'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="/">
|
||||
Home
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger class="flex items-center gap-1">
|
||||
<BreadcrumbEllipsis class="h-4 w-4" />
|
||||
<span class="sr-only">Toggle menu</span>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start">
|
||||
<DropdownMenuItem>Documentation</DropdownMenuItem>
|
||||
<DropdownMenuItem>Themes</DropdownMenuItem>
|
||||
<DropdownMenuItem>GitHub</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="/docs/components/accordion.html">
|
||||
Components
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<script lang="ts" setup>
|
||||
import { ChevronDownIcon, SlashIcon } from '@radix-icons/vue'
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from '@/lib/registry/new-york/ui/breadcrumb'
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/lib/registry/new-york/ui/dropdown-menu'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="/">
|
||||
Home
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator>
|
||||
<SlashIcon />
|
||||
</BreadcrumbSeparator>
|
||||
<BreadcrumbItem>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger class="flex items-center gap-1">
|
||||
Components
|
||||
<ChevronDownIcon class="h-4 w-4" />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start">
|
||||
<DropdownMenuItem>Documentation</DropdownMenuItem>
|
||||
<DropdownMenuItem>Themes</DropdownMenuItem>
|
||||
<DropdownMenuItem>GitHub</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator>
|
||||
<SlashIcon />
|
||||
</BreadcrumbSeparator>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<script lang="ts" setup>
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbEllipsis,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from '@/lib/registry/new-york/ui/breadcrumb'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink as-child>
|
||||
<a href="/">
|
||||
Home
|
||||
</a>
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbEllipsis />
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink as-child>
|
||||
<a href="/docs/components/accordion.html">
|
||||
Components
|
||||
</a>
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<script lang="ts" setup>
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from '@/lib/registry/new-york/ui/breadcrumb'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink>
|
||||
<a href="/">
|
||||
Home
|
||||
</a>
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink>
|
||||
<a href="/docs/components/accordion.html">
|
||||
Components
|
||||
</a>
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
<script lang="ts" setup>
|
||||
import { useMediaQuery } from '@vueuse/core'
|
||||
import { computed, ref } from 'vue'
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbEllipsis,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from '@/lib/registry/new-york/ui/breadcrumb'
|
||||
import { Button } from '@/lib/registry/new-york/ui/button'
|
||||
import {
|
||||
Drawer,
|
||||
DrawerClose,
|
||||
DrawerContent,
|
||||
DrawerDescription,
|
||||
DrawerFooter,
|
||||
DrawerHeader,
|
||||
DrawerTitle,
|
||||
DrawerTrigger,
|
||||
} from '@/lib/registry/new-york/ui/drawer'
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/lib/registry/new-york/ui/dropdown-menu'
|
||||
|
||||
const isDesktop = useMediaQuery('(min-width: 768px)')
|
||||
const isOpen = ref(false)
|
||||
const items = ref([
|
||||
{ href: '#', label: 'Home' },
|
||||
{ href: '#', label: 'Documentation' },
|
||||
{ href: '#', label: 'Building Your Application' },
|
||||
{ href: '#', label: 'Data Fetching' },
|
||||
{ label: 'Caching and Revalidating' },
|
||||
])
|
||||
|
||||
const itemsToDisplay = 3
|
||||
const firstLabel = computed(() => items.value[0]?.label)
|
||||
|
||||
const allButLastTwoItems = computed(() => items.value.slice(1, -2))
|
||||
const remainingItems = computed(() => items.value.slice(-itemsToDisplay + 1))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="{items[0].href}">
|
||||
{{ firstLabel }}
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<template v-if="items.length > itemsToDisplay">
|
||||
<BreadcrumbItem>
|
||||
<DropdownMenu v-if="isDesktop" v-model:open="isOpen">
|
||||
<DropdownMenuTrigger
|
||||
class="flex items-center gap-1"
|
||||
aria-label="Toggle menu"
|
||||
>
|
||||
<BreadcrumbEllipsis class="h-4 w-4" />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start">
|
||||
<DropdownMenuItem v-for="item of allButLastTwoItems" :key="item.label">
|
||||
<a :href="item.href || '#'">
|
||||
{{ item.label }}
|
||||
</a>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<Drawer v-else v-model:open="isOpen">
|
||||
<DrawerTrigger aria-label="Toggle Menu">
|
||||
<BreadcrumbEllipsis class="h-4 w-4" />
|
||||
</DrawerTrigger>
|
||||
<DrawerContent>
|
||||
<DrawerHeader class="text-left">
|
||||
<DrawerTitle>Navigate to</DrawerTitle>
|
||||
<DrawerDescription>
|
||||
Select a page to navigate to.
|
||||
</DrawerDescription>
|
||||
</DrawerHeader>
|
||||
<div class="grid gap-1 px-4">
|
||||
<a
|
||||
v-for="item of allButLastTwoItems"
|
||||
:key="item.label"
|
||||
:href="item.href"
|
||||
class="py-1 text-sm"
|
||||
>
|
||||
{{ item.label }}
|
||||
</a>
|
||||
</div>
|
||||
<DrawerFooter class="pt-4">
|
||||
<DrawerClose as-child>
|
||||
<Button variant="outline">
|
||||
Close
|
||||
</Button>
|
||||
</DrawerClose>
|
||||
</DrawerFooter>
|
||||
</DrawerContent>
|
||||
</Drawer>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
</template>
|
||||
<BreadcrumbItem v-for=" item of remainingItems" :key="item.label">
|
||||
<template v-if="item.href">
|
||||
<BreadcrumbLink
|
||||
as-child
|
||||
class="max-w-20 truncate md:max-w-none"
|
||||
>
|
||||
<a :href="item.href">
|
||||
{{ item.label }}
|
||||
</a>
|
||||
</BreadcrumbLink>
|
||||
<BreadcrumbSeparator />
|
||||
</template>
|
||||
<BreadcrumbPage v-else class="max-w-20 truncate md:max-w-none">
|
||||
{{ item.label }}
|
||||
</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<script lang="ts" setup>
|
||||
import { SlashIcon } from '@radix-icons/vue'
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from '@/lib/registry/new-york/ui/breadcrumb'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="/">
|
||||
Home
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator>
|
||||
<SlashIcon />
|
||||
</BreadcrumbSeparator>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink href="/docs/components/accordion.html">
|
||||
Components
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator>
|
||||
<SlashIcon />
|
||||
</BreadcrumbSeparator>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav aria-label="breadcrumb" :class="props.class">
|
||||
<slot />
|
||||
</nav>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { DotsHorizontalIcon } from '@radix-icons/vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span
|
||||
role="presentation"
|
||||
aria-hidden="true"
|
||||
:class="cn('flex h-9 w-9 items-center justify-center', props.class)"
|
||||
>
|
||||
<slot>
|
||||
<DotsHorizontalIcon class="h-4 w-4" />
|
||||
</slot>
|
||||
<span class="sr-only">More</span>
|
||||
</span>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li
|
||||
:class="cn('inline-flex items-center gap-1.5', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</li>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { Primitive, type PrimitiveProps } from 'radix-vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = withDefaults(defineProps<PrimitiveProps & { class?: HTMLAttributes['class'] }>(), {
|
||||
as: 'a',
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Primitive
|
||||
:as="as"
|
||||
:as-child="asChild"
|
||||
:class="cn('transition-colors hover:text-foreground', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</Primitive>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ol
|
||||
:class="cn('flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</ol>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span
|
||||
role="link"
|
||||
aria-disabled="true"
|
||||
aria-current="page"
|
||||
:class="cn('font-normal text-foreground', props.class)"
|
||||
>
|
||||
<slot />
|
||||
</span>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
<script lang="ts" setup>
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { ChevronRightIcon } from '@radix-icons/vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<li
|
||||
role="presentation"
|
||||
aria-hidden="true"
|
||||
:class="cn('[&>svg]:size-3.5', props.class)"
|
||||
>
|
||||
<slot>
|
||||
<ChevronRightIcon />
|
||||
</slot>
|
||||
</li>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
export { default as Breadcrumb } from './Breadcrumb.vue'
|
||||
export { default as BreadcrumbEllipsis } from './BreadcrumbEllipsis.vue'
|
||||
export { default as BreadcrumbItem } from './BreadcrumbItem.vue'
|
||||
export { default as BreadcrumbLink } from './BreadcrumbLink.vue'
|
||||
export { default as BreadcrumbList } from './BreadcrumbList.vue'
|
||||
export { default as BreadcrumbPage } from './BreadcrumbPage.vue'
|
||||
export { default as BreadcrumbSeparator } from './BreadcrumbSeparator.vue'
|
||||
|
|
@ -85,6 +85,24 @@
|
|||
],
|
||||
"type": "components:ui"
|
||||
},
|
||||
{
|
||||
"name": "breadcrumb",
|
||||
"dependencies": [],
|
||||
"registryDependencies": [
|
||||
"utils"
|
||||
],
|
||||
"files": [
|
||||
"ui/breadcrumb/Breadcrumb.vue",
|
||||
"ui/breadcrumb/BreadcrumbEllipsis.vue",
|
||||
"ui/breadcrumb/BreadcrumbItem.vue",
|
||||
"ui/breadcrumb/BreadcrumbLink.vue",
|
||||
"ui/breadcrumb/BreadcrumbList.vue",
|
||||
"ui/breadcrumb/BreadcrumbPage.vue",
|
||||
"ui/breadcrumb/BreadcrumbSeparator.vue",
|
||||
"ui/breadcrumb/index.ts"
|
||||
],
|
||||
"type": "components:ui"
|
||||
},
|
||||
{
|
||||
"name": "button",
|
||||
"dependencies": [],
|
||||
|
|
|
|||
|
|
@ -1,20 +1,42 @@
|
|||
{
|
||||
"name": "breadcrumb",
|
||||
"dependencies": [],
|
||||
"registryDependencies": [],
|
||||
"registryDependencies": [
|
||||
"utils"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"name": "BreadCrumb.vue",
|
||||
"content": "<template>\n <ol class=\"flex items-center whitespace-nowrap min-w-0\">\n <slot />\n </ol>\n</template>\n"
|
||||
"name": "Breadcrumb.vue",
|
||||
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <nav aria-label=\"breadcrumb\" :class=\"props.class\">\n <slot />\n </nav>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "BreadCrumbItem.vue",
|
||||
"content": "<script setup lang=\"ts\">\nimport { ChevronRight } from 'lucide-vue-next'\n\ninterface BreadCrumbItemProps {\n path?: string\n lastItem?: boolean\n as?: string | object\n}\n\nconst props = withDefaults(defineProps<BreadCrumbItemProps>(), {\n as: 'span',\n})\n</script>\n\n<template>\n <li class=\"text-sm text-muted\">\n <component\n :is=\"props.as\"\n :to=\"props.path\"\n class=\"flex items-center\"\n :class=\"{\n '!font-semibold !text-foreground': $route.path === props.path,\n }\"\n >\n <slot />\n <ChevronRight\n v-if=\"!props.lastItem\"\n class=\"flex-shrink-0 h-3 w-3 text-muted mx-2\"\n />\n </component>\n </li>\n</template>\n"
|
||||
"name": "BreadcrumbEllipsis.vue",
|
||||
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { MoreHorizontal } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <span\n role=\"presentation\"\n aria-hidden=\"true\"\n :class=\"cn('flex h-9 w-9 items-center justify-center', props.class)\"\n >\n <slot>\n <MoreHorizontal class=\"h-4 w-4\" />\n </slot>\n <span class=\"sr-only\">More</span>\n </span>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "BreadcrumbItem.vue",
|
||||
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <li\n :class=\"cn('inline-flex items-center gap-1.5', props.class)\"\n >\n <slot />\n </li>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "BreadcrumbLink.vue",
|
||||
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport type { PrimitiveProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\ninterface Props extends PrimitiveProps {\n as?: string\n class?: HTMLAttributes['class']\n}\nconst props = withDefaults(defineProps<Props>(), {\n as: 'a',\n})\n</script>\n\n<template>\n <Primitive\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"cn('transition-colors hover:text-foreground', props.class)\"\n >\n <slot />\n </Primitive>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "BreadcrumbList.vue",
|
||||
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <ol\n :class=\"cn('flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5', props.class)\"\n >\n <slot />\n </ol>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "BreadcrumbPage.vue",
|
||||
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <span\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n :class=\"cn('font-normal text-foreground', props.class)\"\n >\n <slot />\n </span>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "BreadcrumbSeparator.vue",
|
||||
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { ChevronRight } from 'lucide-vue-next'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n :class=\"cn('[&>svg]:size-3.5', props.class)\"\n >\n <slot>\n <ChevronRight />\n </slot>\n </li>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "index.ts",
|
||||
"content": "export { default as BreadCrumb } from './BreadCrumb.vue'\nexport { default as BreadCrumbItem } from './BreadCrumbItem.vue'\n"
|
||||
"content": "export { default as Breadcrumb } from './Breadcrumb.vue'\nexport { default as BreadcrumbEllipsis } from './BreadcrumbEllipsis.vue'\nexport { default as BreadcrumbItem } from './BreadcrumbItem.vue'\nexport { default as BreadcrumbLink } from './BreadcrumbLink.vue'\nexport { default as BreadcrumbList } from './BreadcrumbList.vue'\nexport { default as BreadcrumbPage } from './BreadcrumbPage.vue'\nexport { default as BreadcrumbSeparator } from './BreadcrumbSeparator.vue'\n"
|
||||
}
|
||||
],
|
||||
"type": "components:ui"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
42
apps/www/src/public/registry/styles/new-york/breadcrumb.json
Normal file
42
apps/www/src/public/registry/styles/new-york/breadcrumb.json
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"name": "breadcrumb",
|
||||
"dependencies": [],
|
||||
"registryDependencies": [
|
||||
"utils"
|
||||
],
|
||||
"files": [
|
||||
{
|
||||
"name": "Breadcrumb.vue",
|
||||
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <nav aria-label=\"breadcrumb\" :class=\"props.class\">\n <slot />\n </nav>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "BreadcrumbEllipsis.vue",
|
||||
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { DotsHorizontalIcon } from '@radix-icons/vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <span\n role=\"presentation\"\n aria-hidden=\"true\"\n :class=\"cn('flex h-9 w-9 items-center justify-center', props.class)\"\n >\n <slot>\n <DotsHorizontalIcon class=\"h-4 w-4\" />\n </slot>\n <span class=\"sr-only\">More</span>\n </span>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "BreadcrumbItem.vue",
|
||||
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <li\n :class=\"cn('inline-flex items-center gap-1.5', props.class)\"\n >\n <slot />\n </li>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "BreadcrumbLink.vue",
|
||||
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport type { PrimitiveProps } from 'radix-vue'\nimport { cn } from '@/lib/utils'\n\ninterface Props extends PrimitiveProps {\n as?: string\n class?: HTMLAttributes['class']\n}\nconst props = withDefaults(defineProps<Props>(), {\n as: 'a',\n})\n</script>\n\n<template>\n <Primitive\n :as=\"as\"\n :as-child=\"asChild\"\n :class=\"cn('transition-colors hover:text-foreground', props.class)\"\n >\n <slot />\n </Primitive>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "BreadcrumbList.vue",
|
||||
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <ol\n :class=\"cn('flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5', props.class)\"\n >\n <slot />\n </ol>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "BreadcrumbPage.vue",
|
||||
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <span\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n :class=\"cn('font-normal text-foreground', props.class)\"\n >\n <slot />\n </span>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "BreadcrumbSeparator.vue",
|
||||
"content": "<script lang=\"ts\" setup>\nimport type { HTMLAttributes } from 'vue'\nimport { ChevronRightIcon } from '@radix-icons/vue'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<{\n class?: HTMLAttributes['class']\n}>()\n</script>\n\n<template>\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n :class=\"cn('[&>svg]:size-3.5', props.class)\"\n >\n <slot>\n <ChevronRightIcon />\n </slot>\n </li>\n</template>\n"
|
||||
},
|
||||
{
|
||||
"name": "index.ts",
|
||||
"content": "export { default as Breadcrumb } from './Breadcrumb.vue'\nexport { default as BreadcrumbEllipsis } from './BreadcrumbEllipsis.vue'\nexport { default as BreadcrumbItem } from './BreadcrumbItem.vue'\nexport { default as BreadcrumbLink } from './BreadcrumbLink.vue'\nexport { default as BreadcrumbList } from './BreadcrumbList.vue'\nexport { default as BreadcrumbPage } from './BreadcrumbPage.vue'\nexport { default as BreadcrumbSeparator } from './BreadcrumbSeparator.vue'\n"
|
||||
}
|
||||
],
|
||||
"type": "components:ui"
|
||||
}
|
||||
|
|
@ -90,8 +90,8 @@ importers:
|
|||
specifier: ^0.350.0
|
||||
version: 0.350.0(vue@3.4.21)
|
||||
radix-vue:
|
||||
specifier: ^1.5.0
|
||||
version: 1.5.0(vue@3.4.21)
|
||||
specifier: ^1.5.2
|
||||
version: 1.5.2(vue@3.4.21)
|
||||
tailwindcss-animate:
|
||||
specifier: ^1.0.7
|
||||
version: 1.0.7(tailwindcss@3.4.1)
|
||||
|
|
@ -11166,6 +11166,19 @@ packages:
|
|||
- vue
|
||||
dev: false
|
||||
|
||||
/radix-vue@1.5.2(vue@3.4.21):
|
||||
resolution: {integrity: sha512-XyXB6mYm7dthW56LDHG4ttR3x+XtspTi48nSq4vHoHldgGZzAEa5VXlqUCr2J21fNKrt3NIYhIIRLB6kKwWwrA==}
|
||||
dependencies:
|
||||
'@floating-ui/dom': 1.6.1
|
||||
'@floating-ui/vue': 1.0.6(vue@3.4.21)
|
||||
'@internationalized/date': 3.5.2
|
||||
fast-deep-equal: 3.1.3
|
||||
nanoid: 5.0.6
|
||||
transitivePeerDependencies:
|
||||
- '@vue/composition-api'
|
||||
- vue
|
||||
dev: false
|
||||
|
||||
/radix3@1.1.0:
|
||||
resolution: {integrity: sha512-pNsHDxbGORSvuSScqNJ+3Km6QAVqk8CfsCBIEoDgpqLrkD2f3QM4I7d1ozJJ172OmIcoUcerZaNWqtLkRXTV3A==}
|
||||
dev: true
|
||||
|
|
@ -13049,7 +13062,7 @@ packages:
|
|||
resolution: {integrity: sha512-3PYWMbN3cSdsciv3fzewskxZFnX61PYq1uNsbvizXDo/8sN4SMrWkYDqWaPdTD3GTEm6wpx7j5flRLg7A5ZXbQ==}
|
||||
dependencies:
|
||||
'@vueuse/core': 10.9.0(vue@3.4.21)
|
||||
radix-vue: 1.5.0(vue@3.4.21)
|
||||
radix-vue: 1.5.2(vue@3.4.21)
|
||||
vue: 3.4.21(typescript@5.4.2)
|
||||
transitivePeerDependencies:
|
||||
- '@vue/composition-api'
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user