@composy/breadcrumb-vue
@composy/breadcrumb-vue
Vue 3 adapter for @composy/breadcrumb-core.
It provides the Breadcrumb component, item/dropdown/separator subcomponents, route helpers,
composables, and the tokenized CSS layer.
Install
pnpm add @composy/breadcrumb-vue
Basic Usage
<script setup lang="ts">
import { Breadcrumb } from '@composy/breadcrumb-vue'
import '@composy/breadcrumb-vue/style.css'
const items = [
{ key: 'workspace', label: 'Workspace', path: '/workspace' },
{ key: 'projects', label: 'Projects', path: '/workspace/projects' },
{ key: 'atlas', label: 'Atlas Program', path: '/workspace/projects/atlas' },
]
</script>
<template>
<Breadcrumb :items="items" separator="chevron" />
</template>
Compatibility style imports are also available:
import '@composy/breadcrumb-vue/index.css'
import '@composy/breadcrumb-vue/styles/index.css'
String icon names use the official tdesign-icons-vue-next sprite API (for example, home, user,
or calendar). You can also pass a Vue component object as a custom icon. Executable URL schemes
are not rendered as links, disabled dropdown entries are not navigable, and _blank links receive
rel="noopener noreferrer".
Component API
Breadcrumb props:
| Prop | Type | Default |
|---|---|---|
items |
BreadcrumbItem[] |
[] |
separator |
'slash' | 'arrow' | 'dot' | 'chevron' | string |
'/' |
size |
'small' | 'medium' | 'large' |
'medium' |
density |
'default' | 'compact' | 'comfortable' |
'default' |
maxItems |
number |
0 |
itemsBeforeCollapse |
number |
1 |
itemsAfterCollapse |
number |
2 |
collapseMode |
'ellipsis' | 'dropdown' | 'none' |
'ellipsis' |
showHome |
boolean |
true |
homeItem |
Partial<BreadcrumbItem> |
undefined |
lastItemClickable |
boolean |
false |
ariaLabel |
string |
'Breadcrumb' |
fullWidth |
boolean |
false |
truncate |
boolean |
false |
maxLabelWidth |
number | string |
180 |
expandLabel |
string |
'Expand hidden breadcrumb items' |
collapsedDropdownLabel |
string |
'Open hidden breadcrumb items' |
moreLabel |
string |
'More' |
Events:
| Event | Payload |
|---|---|
click |
(item, index, event) |
dropdownSelect |
(parentItem, selectedItem, event) |
expandChange |
(expanded) |
Exposed methods:
getItems()expand()collapse()getManager()refresh()
Collapse Dropdown
<template>
<Breadcrumb
:items="items"
collapse-mode="dropdown"
:max-items="4"
:items-before-collapse="1"
:items-after-collapse="2"
collapsed-dropdown-label="Open hidden levels"
more-label="More"
/>
</template>
Dropdown children support group and divider:
const items = [
{
key: 'projects',
label: 'Projects',
path: '/projects',
children: [
{ key: 'active', label: 'Active', path: '/projects?state=active', group: 'Status' },
{ key: 'archived', label: 'Archived', path: '/projects?state=archived', divider: true },
],
},
]
Route Composable
<script setup lang="ts">
import { Breadcrumb, useBreadcrumbRoute } from '@composy/breadcrumb-vue'
import { useRoute } from 'vue-router'
import '@composy/breadcrumb-vue/style.css'
const route = useRoute()
const { items, refresh, clearCache, replaceLast } = useBreadcrumbRoute({
route,
includeHome: true,
homeItem: { key: 'home', label: 'Home', path: '/' },
labelMap: {
'/workspace/projects': 'Projects Hub',
},
excludePatterns: [/\/internal/],
includeQuery: false,
})
</script>
<template>
<Breadcrumb :items="items" collapse-mode="ellipsis" :max-items="4" />
</template>
Async route labels and stale-request safety
useBreadcrumbRoute accepts an asynchronous transform and labelResolver. Resolver calls
receive the current route, the provisional item, and an AbortSignal. When the route changes,
the previous request is aborted and its result is ignored, so a slow response cannot overwrite the
new breadcrumb chain. The composable also exposes pending and error and accepts onError for
application-level reporting:
const { items, pending, error, refresh } = useBreadcrumbRoute({
route,
labelResolver: async (matched, { item, signal }) => {
const response = await fetch(
`/api/routes/label?path=${encodeURIComponent(matched.path)}`,
{ signal }
)
const data = (await response.json()) as { label?: string }
return data.label || item.label
},
onError: (cause, failedRoute) => {
console.error('Breadcrumb resolution failed', failedRoute.fullPath, cause)
},
})
refresh() returns a Promise and invalidates the current route cache entry. Use it after route
metadata or permission state changes without changing the URL.
Route metadata:
meta: {
title: 'Release Train',
hiddenInBreadcrumb: false,
breadcrumb: {
label: 'Release Train',
icon: 'calendar',
},
breadcrumbRedirect: '/workspace/releases',
}
Manager Composable
import { useBreadcrumb } from '@composy/breadcrumb-vue'
const breadcrumb = useBreadcrumb({
items: [{ key: 'workspace', label: 'Workspace', path: '/workspace' }],
showHome: false,
enableHistory: true,
})
breadcrumb.addItem({
key: 'atlas',
label: 'Atlas Program',
path: '/workspace/atlas',
})
breadcrumb.undo()
breadcrumb.redo()
Styling Contract
Public classes use ldesign-breadcrumb:
ldesign-breadcrumb
ldesign-breadcrumb__list
ldesign-breadcrumb__item-wrapper
ldesign-breadcrumb__item
ldesign-breadcrumb__item-link
ldesign-breadcrumb__separator
ldesign-breadcrumb__dropdown
ldesign-breadcrumb--small
ldesign-breadcrumb--medium
ldesign-breadcrumb--large
ldesign-breadcrumb--dense
ldesign-breadcrumb--comfortable
Component CSS variables use --ldesign-breadcrumb-*. Defaults are backed by upstream --ld-*
tokens from packages/color and packages/size.
.workspace-breadcrumb {
--ldesign-breadcrumb-link-hover-color: var(--ld-primary-hover);
--ldesign-breadcrumb-hover-surface-color: color-mix(
in srgb,
var(--ld-primary-default) 10%,
var(--ld-transparent)
);
--ldesign-breadcrumb-item-height: var(--ld-px-34);
--ldesign-breadcrumb-label-max-width: var(--ld-px-280);
}
Style helper exports are re-exported from the Vue package:
import {
BREADCRUMB_CLASS_PREFIX,
breadcrumbClassNames,
createBreadcrumbCssVariables,
} from '@composy/breadcrumb-vue'
Exports
import type { BreadcrumbItem as BreadcrumbItemData } from '@composy/breadcrumb-vue'
import { Breadcrumb, LBreadcrumb } from '@composy/breadcrumb-vue'
import { BreadcrumbItem } from '@composy/breadcrumb-vue/components'
import { useBreadcrumb, useBreadcrumbRoute } from '@composy/breadcrumb-vue/composables'
Build outputs:
dist/
es/
esm/
lib/
The build also syncs CSS to:
dist/style.css
es/style.css
esm/style.css
lib/style.css
es/styles/index.css
esm/styles/index.css
lib/styles/index.css
Development
This package uses @composy/builder with Rolldown from .ldesign/builder.config.ts. Canonical
ESM/CJS TypeScript configs live under .ldesign/; package-root tsconfig*.json files remain
compatibility shims.
pnpm --dir libraries/breadcrumb/packages/vue run type-check
pnpm --dir libraries/breadcrumb/packages/vue run build
At workspace level:
pnpm --dir libraries/breadcrumb run type-check
pnpm --dir libraries/breadcrumb run build
License
MIT
Related Packages
A typed Vue 3 composable for synchronizing reactive values with Vue Router query...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 0.0.2 | 3.5.32 | MIT | |
| 0.0.1 | ^3.5.32 | MIT |