50 lines
1.9 KiB
Vue
50 lines
1.9 KiB
Vue
<template>
|
|
<TreeRoot v-slot="{ flattenItems }" class="list-none select-none text-light-100 dark:text-dark-100 p-2 xl:text-base text-sm" :items="model" :get-key="(item) => item.link ?? item.label">
|
|
<TreeItem v-for="item in flattenItems" v-slot="{ isExpanded }" :key="item._id" :style="{ 'padding-left': `${item.level - 0.5}em` }" v-bind="item.bind" class="flex items-center px-2 outline-none relative cursor-pointer">
|
|
<NuxtLink :href="item.value.link && !item.hasChildren ? { name: 'explore-path', params: { path: item.value.link } } : undefined" no-prefetch class="flex flex-1 items-center border-light-35 dark:border-dark-35 hover:border-accent-blue" :class="{ 'border-s': !item.hasChildren, 'font-medium': item.hasChildren }" active-class="text-accent-blue border-s-2 !border-accent-blue">
|
|
<Icon v-if="item.hasChildren" icon="radix-icons:chevron-right" :class="{ 'rotate-90': isExpanded }" class="h-4 w-4 transition-transform absolute" :style="{ 'left': `${item.level - 1}em` }" />
|
|
<div class="pl-3 py-1 flex-1 truncate" :data-tag="item.value.tag">
|
|
{{ item.value.label }}
|
|
</div>
|
|
</NuxtLink>
|
|
</TreeItem>
|
|
</TreeRoot>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { Icon } from '@iconify/vue/dist/iconify.js';
|
|
|
|
interface TreeItem
|
|
{
|
|
label: string
|
|
link?: string
|
|
tag?: string
|
|
children?: TreeItem[]
|
|
}
|
|
const model = defineModel<TreeItem[]>();
|
|
</script>
|
|
|
|
<style>
|
|
[data-tag="canvas"]:after,
|
|
[data-tag="private"]:after
|
|
{
|
|
@apply text-sm;
|
|
@apply font-normal;
|
|
@apply float-end;
|
|
@apply border ;
|
|
@apply border-light-35 ;
|
|
@apply dark:border-dark-35;
|
|
@apply px-1;
|
|
@apply bg-light-20;
|
|
@apply dark:bg-dark-20;
|
|
font-variant: small-caps;
|
|
}
|
|
[data-tag="canvas"]:after
|
|
{
|
|
content: 'Canvas'
|
|
}
|
|
[data-tag="private"]:after
|
|
{
|
|
content: 'Privé'
|
|
}
|
|
</style> |