@composy/breadcrumb-vue

LDesign breadcrumb Vue 3 adapter
Install
npm install @composy/breadcrumb-vue
Latest Version:0.0.2
Vue:3
License:MIT
Last Updated:Oct 12, 2026
Links: npm
Maintainer: swimly

@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

@composy/menu-vue

LDesign 菜单系统 - Vue 3 适配器

0
@composy/cache-vue

Vue 3 适配层(基于 core 的轻量封装)/ Vue 3 adapter built on top of @composy/cac...

0
@composy/barcode-vue

条形码 Vue3 组件和组合式 API

0
vue3-use-route-query

A typed Vue 3 composable for synchronizing reactive values with Vue Router query...

3,031 2

Version History

Version Released Vue License
0.0.2 3.5.32 MIT
0.0.1 ^3.5.32 MIT