Breadcrumb
The trail of pages leading to the current one, as links with separators.
Install
If this is the first component in the project, set up once. This writes ermine.json and copies the theme stylesheet. The installation guide covers Vue, Nuxt and Astro.
npx ermineui initpnpm dlx ermineui inityarn dlx ermineui initbunx ermineui initThen add the component:
npx ermineui add breadcrumbpnpm dlx ermineui add breadcrumbyarn dlx ermineui add breadcrumbbunx ermineui add breadcrumbThat copies 3 files into src/components/ui/breadcrumb/, 1 helper into src/lib/ermine/. Files you already have are kept.
Use
import { Breadcrumb, BreadcrumbItem } from '@/components/ui/breadcrumb'<Pagination v-model="page" :page-count="24" />
<Breadcrumb>
<BreadcrumbItem href="/projects">Projects</BreadcrumbItem>
<BreadcrumbItem :as="NuxtLink" to="/projects/storefront">Storefront</BreadcrumbItem>
<BreadcrumbItem current>Deployments</BreadcrumbItem>
</Breadcrumb>
<Slider v-model="memory" :min="128" :max="3008" :step="64" />
<ToggleGroup v-model="period" aria-label="Period"> <!-- type="multiple" takes an array -->
<ToggleGroupItem value="7d">7 days</ToggleGroupItem>
<ToggleGroupItem value="30d">30 days</ToggleGroupItem>
</ToggleGroup>In Nuxt, with the auto-import setting, the tags work in templates without the import. In Astro, use it inside a Vue island.
What gets copied
| File | Where it goes |
|---|---|
Breadcrumb.vue | src/components/ui/breadcrumb/Breadcrumb.vue |
BreadcrumbItem.vue | src/components/ui/breadcrumb/BreadcrumbItem.vue |
index.ts | src/components/ui/breadcrumb/index.ts |
primitive.ts helper | src/lib/ermine/primitive.ts |
The folders are the suggested ones. ermine.json says where yours are.
Source
This is exactly what the command copies. To install by hand, create each file below and the helpers listed above.
Breadcrumb.vue 72 lines
<script setup lang="ts">
withDefaults(
defineProps<{
/** Accessible name of the trail. */
label?: string
}>(),
{ label: 'Breadcrumb' },
)
</script>
<template>
<nav class="er-breadcrumb" :aria-label="label">
<ol><slot /></ol>
</nav>
</template>
<style>
@layer components {
.er-breadcrumb ol {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.375rem;
margin: 0;
padding: 0;
color: var(--er-muted-foreground);
font-size: 0.875rem;
list-style: none;
}
.er-breadcrumb-item {
display: inline-flex;
align-items: center;
gap: 0.375rem;
min-width: 0;
}
/* The separator is drawn in CSS, so screen readers hear a plain list of links. */
.er-breadcrumb-item + .er-breadcrumb-item::before {
content: '';
flex-shrink: 0;
width: 0.875rem;
height: 0.875rem;
background: currentColor;
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E")
center / contain no-repeat;
opacity: 0.7;
}
.er-breadcrumb-link {
border-radius: var(--er-radius-sm);
color: inherit;
text-decoration: none;
transition: color var(--er-duration);
}
a.er-breadcrumb-link:hover {
color: var(--er-foreground);
}
.er-breadcrumb-link:focus-visible {
outline: 2px solid var(--er-ring);
outline-offset: 2px;
}
.er-breadcrumb-link[aria-current='page'] {
color: var(--er-foreground);
font-weight: var(--er-weight-medium);
}
}
</style>BreadcrumbItem.vue 24 lines
<script setup lang="ts">
import type { Component } from 'vue'
import { Primitive } from '../../lib/primitive'
defineOptions({ inheritAttrs: false })
withDefaults(
defineProps<{
/** Tag or component for the link, e.g. NuxtLink. Attributes such as href or to are passed on to it. */
as?: string | Component
/** The page the reader is on now: shown as plain text, not a link. */
current?: boolean
}>(),
{ as: 'a' },
)
</script>
<template>
<li class="er-breadcrumb-item">
<span v-if="current" class="er-breadcrumb-link" aria-current="page"><slot /></span>
<Primitive v-else v-bind="$attrs" :as="as" class="er-breadcrumb-link"><slot /></Primitive>
</li>
</template>index.ts 4 lines
/** Breadcrumb — the trail of pages leading to the current one, as links with separators. */
export { default as Breadcrumb } from './Breadcrumb.vue'
export { default as BreadcrumbItem } from './BreadcrumbItem.vue'