Files
kite/frontend/src/components/ui/BreadcrumbBar.vue
T
curo1305 7e584e032a feat(10-03): implement BreadcrumbBar.vue — shared breadcrumb component (GREEN)
- Options API component with segments/{id?,label}, rootLabel, showRoot props
- Emits navigate(segment.id) for intermediate clicks, navigate(null) for root
- Computed visibleSegments collapses >4 segments to first+ellipsis+last two
- Segments without id render as plain non-clickable spans (admin static segments)
- Uses AppIcon for chevronRight separator (no inline SVG)
- All 10 Vitest tests pass
- Also creates AppIcon.vue (Rule 3: BreadcrumbBar imports it)
2026-06-15 20:13:29 +02:00

73 lines
2.0 KiB
Vue

<template>
<nav aria-label="Navigation">
<ol class="flex items-center gap-1 text-sm flex-wrap">
<li v-if="showRoot" class="flex items-center gap-1">
<button
@click="$emit('navigate', null)"
class="text-indigo-600 hover:underline font-medium"
>
{{ rootLabel }}
</button>
</li>
<template v-for="(segment, idx) in visibleSegments" :key="segment.id ?? 'static-' + idx">
<li
v-if="showRoot || idx > 0"
class="shrink-0"
aria-hidden="true"
>
<AppIcon name="chevronRight" class="w-3 h-3 text-gray-400" />
</li>
<li v-if="segment.id === 'ellipsis'" class="flex items-center">
<span class="px-2 py-1 text-gray-400"></span>
</li>
<li v-else-if="idx === visibleSegments.length - 1" class="flex items-center">
<span class="text-gray-900 font-medium">{{ segment.label }}</span>
</li>
<li v-else-if="segment.id" class="flex items-center">
<button
@click="$emit('navigate', segment.id)"
class="text-indigo-600 hover:underline font-medium"
>
{{ segment.label }}
</button>
</li>
<li v-else class="flex items-center">
<span class="text-gray-500">{{ segment.label }}</span>
</li>
</template>
</ol>
</nav>
</template>
<script>
import AppIcon from './AppIcon.vue'
export default {
name: 'BreadcrumbBar',
components: { AppIcon },
props: {
segments: { type: Array, default: () => [] },
rootLabel: { type: String, default: 'Home' },
showRoot: { type: Boolean, default: true },
},
emits: ['navigate'],
computed: {
visibleSegments() {
if (this.segments.length > 4) {
return [
this.segments[0],
{ id: 'ellipsis', label: '…' },
...this.segments.slice(-2),
]
}
return this.segments
},
},
}
</script>