Examples
Basic
Prop | Default | Type | Description |
---|---|---|---|
items | [] | array | An array of Links wrapped around the Button component, inheriting all its props and slots with additional children prop. |
Preview
Code
<script setup lang="ts">
const items = [
{
label: 'i-radix-icons-home',
icon: true,
to: '/',
},
{
label: 'Components',
to: '/components/accordion',
},
{
label: 'Breadcrumb',
to: '/components/breadcrumb',
},
]
const items2 = [
{
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 = [
{
label: 'i-radix-icons-home',
icon: true,
to: '/',
},
{
label: 'Components',
to: '/components/accordion',
},
{
label: 'Breadcrumb',
to: '/components/breadcrumb',
},
]
const items2 = [
{
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="text-gray"
breadcrumb-inactive="link-primary"
:_breadcrumb-link="{
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 = [
{
label: 'i-radix-icons-home',
icon: true,
to: '/',
},
{
label: 'Components',
to: '/components/accordion',
},
{
label: 'Breadcrumb',
to: '/components/breadcrumb',
},
]
const items2 = [
{
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-heroicons-slash-20-solid"
/>
<NSeparator />
<NBreadcrumb
:items="items2"
separator="i-radix-icons-border-dashed"
/>
</div>
</template>
Ellipsis
You can adjust the breadcrumb behavior dynamically with the BreadcrumbEllipsis
. When there are children in the breadcrumb, the BreadcrumbEllipsis
will appear as an icon, and upon clicking it, a DropdownMenu
will open, allowing you to navigate to the child elements.
Prop | Default | Type | Description |
---|---|---|---|
ellipsis | i-radix-icons-dots-horizontal | string | The ellipsis icon. |
Condition | Default | Type | Description |
---|---|---|---|
children | - | aray | An array of children Links wrapped around the Button component |
For more details, please refer to the Components and Slots sections.
Read more in Icon component
Read more in Dropdown menu component
Preview
Code
<script setup lang="ts">
const items = [
{
label: 'Home',
leading: 'i-lucide-home',
to: '/',
},
{
label: 'Getting Started',
to: '/getting-started/introduction',
},
{
label: 'More',
children: [
{
label: 'Components',
items: [
{
label: 'Accordion',
leading: 'i-radix-icons-link-2',
to: '/components/accordion',
},
{
label: 'Alert',
leading: 'i-radix-icons-link-2',
to: '/components/alert',
},
],
},
{
label: 'API (disabled)',
disabled: true,
},
],
},
{
label: 'Breadcrumb',
leading: 'i-radix-icons-link-2',
to: '/components/breadcrumb',
},
]
const items2 = [
{
label: 'i-lucide-home',
icon: true,
to: '/',
},
{
label: 'Getting Started',
leading: 'i-lucide-rocket',
to: '/getting-started/introduction',
},
{
label: 'Components',
children: [
{
label: 'Accordion',
to: '/components/accordion',
},
{
label: 'Alert',
to: '/components/alert',
},
],
},
{
label: 'Breadcrumb',
leading: 'i-radix-icons-link-2',
to: '/components/breadcrumb',
},
]
</script>
<template>
<NBreadcrumb
:items="items"
/>
<NSeparator />
<NBreadcrumb
:items="items2"
ellipsis="i-octicon-ellipsis-24"
/>
</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
or
<script setup lang="ts">
const items = [
{
label: 'i-radix-icons-home',
icon: true,
to: '/',
},
{
label: 'Components',
to: '/components/accordion',
},
{
label: 'Breadcrumb',
to: '/components/breadcrumb',
},
]
const items2 = [
{
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',
},
]
const items3 = [
{
leading: 'i-radix-icons-home',
label: 'Home',
to: '/',
},
{
label: 'Components',
children: [
{
label: 'Accordion',
leading: 'i-radix-icons-link-2',
to: '/components/accordion',
},
{
label: 'Alert',
leading: 'i-radix-icons-link-2',
to: '/components/alert',
},
],
},
{
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-material-symbols-light-play-arrow"
:_breadcrumb-link="{
size: 'sm',
}"
:_breadcrumb-separator="{
size: 'xl',
}"
/>
<NSeparator label="or" />
<NBreadcrumb
:items="items3"
:_breadcrumb-link="{
size: 'md',
}"
/>
</div>
</template>
Slots
Name | Props | Description |
---|---|---|
default | item index isActive | The breadcrumb item |
separator | item | The separator |
root | items | The root breadcrumb |
list | item | The list of items |
dropdown | item | The dropdown if available ellipsis |
Preview
Code
<script setup lang="ts">
const items = [
{
label: 'Components',
to: '/components/accordion',
},
{
label: 'Alert',
to: '/components/alert',
},
{
label: 'Ellipsis',
children: [
{
label: 'Badge',
to: '/components/badge',
},
{
label: 'Avatar Components',
items: [
{
label: 'Avatar',
to: '/components/avatar',
},
{
label: 'Avatar Group',
to: '/components/avatar-group',
},
],
},
{
disabled: true,
label: 'Smth magical 📃',
},
],
},
{
label: 'Breadcrumb',
to: '/components/breadcrumb',
},
]
</script>
<template>
<NBreadcrumb
:items="items"
>
<template #dropdown="{ item }">
<NDropdownMenu
:items="item.children"
:_dropdown-menu-item="{
class: 'text-xs',
}"
:_dropdown-menu-sub-trigger="{
class: 'text-xs',
}"
>
<NBreadcrumbEllipsis />
</NDropdownMenu>
</template>
<template #default="{ item, index, isActive }">
<NBadge :badge="isActive ? 'primary' : 'soft-gray'" class="rounded-full">
{{ index + 1 }}. {{ item.label }}
</NBadge>
</template>
<template #separator>
<NSeparator label="👉" class="w-14" />
</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-ellipsis-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 px-1.5 sm:px-2.5',
'breadcrumb-item': 'inline-flex items-center gap-1.5',
'breadcrumb-separator': 'flex',
// TODO
'breadcrumb-ellipsis': 'flex items-center justify-center px-1.5 sm:px-2.5 cursor-pointer',
}
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'] }
type BreadcrumbListItem = NButtonProps & {
children?: NButtonProps[]
}
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<BreadcrumbListItem>[]
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 DropdownMenu from '../../elements/dropdown-menu/DropdownMenu.vue'
import BreadcrumbEllipsis from './BreadcrumbEllipsis.vue'
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 items"
:key="i"
>
<slot name="list" :item="item">
<BreadcrumbItem
:una
:size
v-bind="_breadcrumbItem"
>
<slot name="item" :item="item">
<BreadcrumbLink
v-if="!item.children?.length"
:active="i === items.length - 1"
:breadcrumb-active="props.breadcrumbActive"
:breadcrumb-inactive="props.breadcrumbInactive"
:size
v-bind="{
...item,
..._breadcrumbLink,
}"
>
<slot :item="item" :index="i" :is-active="i === items.length - 1" />
</BreadcrumbLink>
<template v-else>
<slot name="dropdown" :item="item">
<DropdownMenu
:size
:modal="false"
:items="item.children"
:_dropdown-menu-item="{
..._breadcrumbLink,
}"
>
<BreadcrumbEllipsis
:size
:icon="ellipsis"
v-bind="_breadcrumbEllipsis"
/>
</DropdownMenu>
</slot>
</template>
</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(
'breadcrumb-separator',
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'
import Icon from '../../elements/Icon.vue'
const props = withDefaults(defineProps<NBreadcrumbEllipsisProps>(), {
icon: 'breadcrumb-ellipsis-icon',
size: 'sm',
square: 9,
})
</script>
<template>
<div
role="presentation"
aria-hidden="true"
:class="cn(
'breadcrumb-ellipsis',
props.class,
props.una?.breadcrumbEllipsis,
)"
:size
>
<slot>
<Icon
:name="icon"
:class="props.una?.breadcrumbEllipsisIcon"
aria-hidden="true"
/>
</slot>
<span class="sr-only">More</span>
</div>
</template>