Examples
Basic
Prop | Default | Type | Description |
---|---|---|---|
items | [] | array | An array of Links wrapped around the Button component, inheriting all its props and slots. |
Preview
Code
<script setup lang="ts">
const items = ref([
{
label: 'i-radix-icons-home',
icon: true,
to: '/',
},
{
label: 'Components',
to: '/components/accordion',
},
{
label: 'Breadcrumb',
to: '/components/breadcrumb',
},
])
const items2 = ref([
{
leading: 'i-radix-icons-home',
label: 'Home',
to: '/',
},
{
label: 'Components',
leading: 'i-radix-icons-cube',
to: '/components/accordion',
},
{
label: 'Breadcrumb',
leading: 'i-radix-icons-link-2',
to: '/components/breadcrumb',
},
])
</script>
<template>
<div class="flex flex-col space-y-4">
<NBreadcrumb
:items
/>
<NSeparator />
<NBreadcrumb
:items="items2"
/>
</div>
</template>
Read more in Button component
Variant & Color
Prop | Default | Type | Description |
---|---|---|---|
breadcrumb-active | text-primary | {variant}-{color} | The active breadcrumb variant and color. |
breadcrumb-inactive | text-muted | {variant}-{color} | The inactive breadcrumb variant and color. |
You can use any variant and color provided by the Button component. Just use breadcrumb-active
and breadcrumb-inactive
as prefixes instead of btn
.
Preview
Code
or
or
<script setup lang="ts">
const items = ref([
{
label: 'i-radix-icons-home',
icon: true,
to: '/',
},
{
label: 'Components',
to: '/components/accordion',
},
{
label: 'Breadcrumb',
to: '/components/breadcrumb',
},
])
const items2 = ref([
{
leading: 'i-radix-icons-home',
label: 'Home',
to: '/',
},
{
label: 'Components',
leading: 'i-radix-icons-cube',
to: '/components/accordion',
},
{
label: 'Breadcrumb',
leading: 'i-radix-icons-link-2',
to: '/components/breadcrumb',
},
])
</script>
<template>
<div class="flex flex-col space-y-4">
<NBreadcrumb
breadcrumb-active="text-black"
:items
/>
<NSeparator label="or" />
<NBreadcrumb
breadcrumb-active="text-orange"
breadcrumb-inactive="text-red"
:items
/>
<NSeparator label="or" />
<NBreadcrumb
breadcrumb-active="solid-primary"
breadcrumb-inactive="ghost-primary"
:_breadcrumb-link="{
size: 'xs',
class: 'rounded-full btn-rectangle',
}"
:items="items2"
/>
</div>
</template>
Separator
Prop | Default | Type | Description |
---|---|---|---|
separator | i-radix-icons-chevron-right | string | The separator icon. |
Read more in Icon component
Preview
Code
<script setup lang="ts">
const items = ref([
{
label: 'i-radix-icons-home',
icon: true,
to: '/',
},
{
label: 'Components',
to: '/components/accordion',
},
{
label: 'Breadcrumb',
to: '/components/breadcrumb',
},
])
const items2 = ref([
{
leading: 'i-radix-icons-home',
label: 'Home',
to: '/',
},
{
label: 'Components',
leading: 'i-radix-icons-cube',
to: '/components/accordion',
},
{
label: 'Breadcrumb',
leading: 'i-radix-icons-link-2',
to: '/components/breadcrumb',
},
])
</script>
<template>
<div class="flex flex-col space-y-4">
<NBreadcrumb
:items
separator="i-lucide-slash"
/>
<NSeparator />
<NBreadcrumb
:items="items2"
separator="i-radix-icons-border-dashed"
/>
</div>
</template>
Size
Adjust the breadcrumb size without limits. Use breakpoints
(e.g., sm:sm
, xs:lg
) for responsive sizes or states
(e.g., hover:lg
, focus:3xl
) for state-based sizes.
Prop | Default | Type | Description |
---|---|---|---|
size | sm | string | Adjusts the overall size of the breadcrumb component. |
_breadcrumbLink.size | sm | string | Customizes the size of each breadcrumb link. |
_breadcrumbSeparator.size | sm | string | Modifies the size of the breadcrumb separator. |
Preview
Code
or
<script setup lang="ts">
const items = ref([
{
label: 'i-radix-icons-home',
icon: true,
to: '/',
},
{
label: 'Components',
to: '/components/accordion',
},
{
label: 'Breadcrumb',
to: '/components/breadcrumb',
},
])
const items2 = ref([
{
leading: 'i-radix-icons-home',
label: 'Home',
to: '/',
},
{
label: 'Components',
leading: 'i-radix-icons-cube',
to: '/components/accordion',
},
{
label: 'Breadcrumb',
leading: 'i-radix-icons-link-2',
to: '/components/breadcrumb',
},
])
</script>
<template>
<div class="flex flex-col space-y-4">
<NBreadcrumb
:items
size="lg"
/>
<NSeparator label="or" />
<NBreadcrumb
:items="items2"
separator="i-lucide-slash"
:_breadcrumb-link="{
size: 'xs',
}"
:_breadcrumb-separator="{
size: 'lg',
}"
/>
</div>
</template>
Slots
Name | Props | Description |
---|---|---|
default | item | The breadcrumb item |
separator | item | The separator |
root | items | The root breadcrumb |
list | item | The list of items |
Preview
Code
<script setup lang="ts">
const items = ref([
{ label: 'Components', to: '/components/accordion' },
{ label: 'Alert', to: '/components/alert' },
{ label: 'Breadcrumb', to: '/components/breadcrumb' },
])
const colors = ['#ffd45e', '#45ad2d', '#3b54c4', '#b156db', '#a6a2a3', '#ff7a97', '#a1612a'] as const
function getRandomColor() {
const index = Math.floor(Math.random() * colors.length)
return colors[index]
}
</script>
<template>
<NBreadcrumb :items>
<template #separator>
<NSeparator orientation="vertical" class="h-10" />
</template>
<template #default="{ item }">
<div class="flex items-center gap2">
<div
:style="{ backgroundColor: getRandomColor() }"
class="h-2 w-2 rounded-full"
/>
{{ item.label }}
</div>
</template>
</NBreadcrumb>
</template>
Presets
shortcuts/breadcrumb.ts
type BreadcrumbPrefix = 'breadcrumb'
export const staticBreadcrumb: Record<`${BreadcrumbPrefix}-${string}` | BreadcrumbPrefix, string> = {
// config
'breadcrumb': '',
'breadcrumb-active': 'breadcrumb-active-text-primary',
'breadcrumb-inactive': 'breadcrumb-inactive-text-muted',
'breadcrumb-separator-icon': 'i-radix-icons-chevron-right',
'breadcrumb-elipsis-icon': 'i-radix-icons-dots-horizontal',
// components
'breadcrumb-root': '',
'breadcrumb-list': 'flex flex-wrap items-center break-words text-muted',
'breadcrumb-link': 'transition-colors font-normal',
'breadcrumb-item': 'inline-flex items-center gap-1.5',
// TODO
'breadcrumb-ellipsis': 'flex items-center justify-center',
}
export const dynamicBreadcrumb = [
// states
[
/^breadcrumb-active-([^-]+)-([^-]+)$/,
([, variant = 'text', color = 'primary']) =>
`data-[state=active]:btn-${variant}-${color}`,
],
[
/^breadcrumb-inactive-([^-]+)-([^-]+)$/,
([, variant = 'text', color = 'muted']) =>
`data-[state=inactive]:btn-${variant}-${color}`,
],
]
export const breadcrumb = [
...dynamicBreadcrumb,
staticBreadcrumb,
]
Props
types/breadcrumb.ts
import type { HTMLAttributes } from 'vue'
import type { NButtonProps } from './button'
interface BaseExtensions { class?: HTMLAttributes['class'] }
export interface NBreadcrumbProps extends BaseExtensions, Pick<NBreadcrumbLinkProps, 'breadcrumbActive' | 'breadcrumbInactive'> {
/**
* List of items to display in the breadcrumb.
*
* @example
* items: [{ label: 'Home', to: '/' }, { label: 'About', to: '/about' }]
*/
items: Partial<NButtonProps>[]
separator?: NBreadcrumbSeparatorProps['icon']
ellipsis?: NBreadcrumbEllipsisProps['icon']
/**
* Allows you to change the size of the input.
*
* @default sm
*
* @example
* size="sm" | size="2cm" | size="2rem" | size="2px"
*/
size?: string
// maxItems?: number
// sub-components
_breadcrumbSeparator?: Partial<NBreadcrumbSeparatorProps>
_breadcrumbItem?: Partial<NBreadcrumbItemProps>
_breadcrumbRoot?: Partial<NBreadcrumbRootProps>
_breadcrumbList?: Partial<NBreadcrumbListProps>
_breadcrumbLink?: Partial<NBreadcrumbLinkProps>
_breadcrumbEllipsis?: Partial<NBreadcrumbEllipsisProps>
/**
* `UnaUI` preset configuration
*
* @see https://github.com/una-ui/una-ui/blob/main/packages/preset/src/_shortcuts/breadcrumb.ts
*/
una?: NBreadcrumbUnaProps
}
export interface NBreadcrumbRootProps extends BaseExtensions {
una?: Pick<NBreadcrumbUnaProps, 'breadcrumbRoot'>
}
export interface NBreadcrumbItemProps extends BaseExtensions {
/**
* `UnaUI` preset configuration
*
* @see https://github.com/una-ui/una-ui/blob/main/packages/preset/src/_shortcuts/breadcrumb.ts
*/
una?: Pick<NBreadcrumbUnaProps, 'breadcrumbItem'>
}
export interface NBreadcrumbSeparatorProps extends BaseExtensions {
/**
* Custom separator icon.
*/
icon?: string
/**
* Allows you to change the size of the input.
*
* @default sm
*
* @example
* size="sm" | size="2cm" | size="2rem" | size="2px"
*/
size?: string
/**
* `UnaUI` preset configuration
*
* @see https://github.com/una-ui/una-ui/blob/main/packages/preset/src/_shortcuts/breadcrumb.ts
*/
una?: Pick<NBreadcrumbUnaProps, 'breadcrumbSeparator' | 'breadcrumbSeparatorIcon'>
}
export interface NBreadcrumbListProps extends BaseExtensions {
/**
* `UnaUI` preset configuration
*
* @see https://github.com/una-ui/una-ui/blob/main/packages/preset/src/_shortcuts/breadcrumb.ts
*/
una?: Pick<NBreadcrumbUnaProps, 'breadcrumbList'>
}
export interface NBreadcrumbLinkProps extends BaseExtensions, NButtonProps {
active?: boolean
breadcrumbActive?: string
breadcrumbInactive?: string
}
export interface NBreadcrumbEllipsisProps extends BaseExtensions {
/**
* Custom separator icon.
*/
icon?: string
/**
* /**
* Allows you to change the size of the input.
*
* @default sm
*
* @example
* size="sm" | size="2cm" | size="2rem" | size="2px"
*/
size?: string
/**
* `UnaUI` preset configuration
*
* @see https://github.com/una-ui/una-ui/blob/main/packages/preset/src/_shortcuts/breadcrumb.ts
*/
una?: Pick<NBreadcrumbUnaProps, 'breadcrumbEllipsis' | 'breadcrumbEllipsisIcon'>
}
interface NBreadcrumbUnaProps {
breadcrumb?: HTMLAttributes['class']
breadcrumbRoot?: HTMLAttributes['class']
breadcrumbItem?: HTMLAttributes['class']
breadcrumbEllipsis?: HTMLAttributes
breadcrumbEllipsisIcon?: HTMLAttributes['class']
breadcrumbList?: HTMLAttributes['class']
breadcrumbSeparator?: HTMLAttributes['class']
breadcrumbSeparatorIcon?: HTMLAttributes['class']
}
Components
Breadcrumb.vue
BreadcrumbRoot.vue
BreadcrumbList.vue
BreadcrumbLink.vue
BreadcrumbItem.vue
BreadcrumbSeparator.vue
BreadcrumbEllipsis.vue
<script lang="ts" setup>
import type { NBreadcrumbProps } from '../../../types'
import { cn } from '../../../utils'
import BreadcrumbItem from './BreadcrumbItem.vue'
import BreadcrumbLink from './BreadcrumbLink.vue'
import BreadcrumbList from './BreadcrumbList.vue'
import BreadcrumbRoot from './BreadcrumbRoot.vue'
import BreadcrumbSeparator from './BreadcrumbSeparator.vue'
const props = defineProps<NBreadcrumbProps>()
</script>
<template>
<BreadcrumbRoot
:class="cn(
'breadcrumb',
props.class,
props.una?.breadcrumb,
)"
:una
:size
v-bind="_breadcrumbRoot"
>
<slot name="root" :items="items">
<BreadcrumbList
:una
:size
v-bind="_breadcrumbList"
>
<template
v-for="(item, i) in props.items"
:key="i"
>
<slot name="list" :item="item">
<BreadcrumbItem
:una
:size
v-bind="_breadcrumbItem"
>
<slot name="item" :item="item">
<BreadcrumbLink
:active="i === items.length - 1"
:breadcrumb-active="props.breadcrumbActive"
:breadcrumb-inactive="props.breadcrumbInactive"
:size
v-bind="{
...item,
..._breadcrumbLink,
}"
>
<slot :item="item" />
</BreadcrumbLink>
</slot>
</BreadcrumbItem>
<BreadcrumbSeparator
v-if="i < props.items!.length - 1"
:icon="props.separator"
:size
:una
v-bind="_breadcrumbSeparator"
>
<slot name="separator" />
</BreadcrumbSeparator>
</slot>
</template>
</BreadcrumbList>
</slot>
</BreadcrumbRoot>
</template>
<script lang="ts" setup>
import type { NBreadcrumbRootProps } from '../../../types'
import { cn } from '../../../utils'
const props = defineProps<NBreadcrumbRootProps>()
</script>
<template>
<nav
aria-label="breadcrumb"
:class="cn(
props.class,
props.una?.breadcrumbRoot,
)"
>
<slot />
</nav>
</template>
<script lang="ts" setup>
import type { NBreadcrumbListProps } from '../../../types'
import { cn } from '../../../utils'
const props = defineProps<NBreadcrumbListProps>()
</script>
<template>
<ol
:class="cn(
'breadcrumb-list',
props.class,
props.una?.breadcrumbList,
)"
>
<slot />
</ol>
</template>
<script lang="ts" setup>
import type { NBreadcrumbLinkProps } from '../../../types'
import { computed } from 'vue'
import { cn } from '../../../utils'
import Button from '../../elements/Button.vue'
const props = withDefaults(defineProps<NBreadcrumbLinkProps>(), {
active: false,
breadcrumbActive: '~',
breadcrumbInactive: '~',
size: 'sm',
})
const activeAttrs = computed(() => {
if (!props.active) {
return {
'data-state': 'inactive',
}
}
return {
'aria-disabled': true,
'tabindex': -1,
'data-state': 'active',
'aria-current': 'page',
}
})
</script>
<template>
<Button
v-bind="{ ...props, ...activeAttrs }"
:class="cn(
'breadcrumb-link',
{ 'cursor-text': active },
)"
:to="disabled ? undefined : props.to"
>
<slot />
</Button>
</template>
<script lang="ts" setup>
import type { NBreadcrumbItemProps } from '../../../types'
import { cn } from '../../../utils'
const props = defineProps<NBreadcrumbItemProps>()
</script>
<template>
<li
:class="cn(
'breadcrumb-item',
props.class,
props.una?.breadcrumbItem,
)"
>
<slot />
</li>
</template>
<script lang="ts" setup>
import type { NBreadcrumbSeparatorProps } from '../../../types'
import { cn } from '../../../utils'
import Icon from '../../elements/Icon.vue'
const props = withDefaults(defineProps<NBreadcrumbSeparatorProps>(), {
icon: 'breadcrumb-separator-icon',
size: 'sm',
})
</script>
<template>
<li
role="presentation"
aria-hidden="true"
:class="cn(
'',
props.class,
props.una?.breadcrumbSeparator,
)"
:size
>
<slot>
<Icon
:name="icon"
:class="props.una?.breadcrumbSeparatorIcon"
/>
</slot>
</li>
</template>
<script lang="ts" setup>
import type { NBreadcrumbEllipsisProps } from '../../../types'
import { cn } from '../../../utils'
const props = withDefaults(defineProps<NBreadcrumbEllipsisProps>(), {
icon: 'breadcrumb-ellipsis-icon',
size: 'sm',
square: 9,
})
</script>
<template>
<span
role="presentation"
aria-hidden="true"
:class="cn(
'breadcrumb-ellipsis',
props.class,
props.una?.breadcrumbEllipsis,
)"
:size
>
<slot>
<NIcon
:name="icon"
:class="props.una?.breadcrumbEllipsisIcon"
aria-hidden="true"
/>
</slot>
<span class="sr-only">More</span>
</span>
</template>