ptitlutins/app/components/molecules/Breadcrumb.vue
2026-06-15 23:34:49 +02:00

96 lines
2 KiB
Vue

<script setup lang="ts">
import type { Node } from "~/types"
const props = defineProps<{
chain: Node[]
}>()
const { linkTo } = useNodeNav()
// Crumb i navigates to the node at depth i: the voyage root (i=0) clears the
// path, deeper crumbs keep the ids up to that depth.
const crumbTo = (i: number) =>
linkTo(i === 0 ? [] : props.chain.slice(1, i + 1).map((c) => c.id))
</script>
<template>
<nav class="breadcrumb">
<template v-for="(n, i) in chain" :key="n.id">
<Icon
v-if="i > 0"
name="carbon:chevron-right"
size="0.85rem"
class="breadcrumb__sep"
/>
<span
v-if="i === chain.length - 1"
class="breadcrumb__crumb breadcrumb__crumb--current"
aria-current="page"
>
<Icon
v-if="i === 0"
name="carbon:campsite"
size="0.95rem"
class="breadcrumb__root-icon"
/>
{{ n.event.title }}
</span>
<NuxtLink
v-else
:to="crumbTo(i)"
class="breadcrumb__crumb breadcrumb__crumb--link drill"
>
<Icon
v-if="i === 0"
name="carbon:campsite"
size="0.95rem"
class="breadcrumb__root-icon"
/>
{{ n.event.title }}
</NuxtLink>
</template>
</nav>
</template>
<style scoped>
.breadcrumb {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 2px;
padding: 0 2px;
}
.breadcrumb__sep {
color: var(--neutral-40);
}
.breadcrumb__crumb {
display: inline-flex;
align-items: center;
gap: 5px;
padding: 3px 6px;
border-radius: var(--radius-sm);
max-width: 190px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-family: var(--font-body);
font-size: 0.8rem;
text-decoration: none;
}
.breadcrumb__crumb--link {
font-weight: var(--weight-semibold);
color: var(--text-muted);
}
.breadcrumb__crumb--current {
font-weight: var(--weight-bold);
color: var(--color-4);
}
.breadcrumb__root-icon {
color: var(--color-5);
}
</style>