jointrashposs/components/docs/AsideNav.vue

101 lines
3.4 KiB
Vue
Raw Normal View History

2023-07-16 13:18:07 +02:00
<template>
2023-09-23 20:02:04 +02:00
<ul class="toc-links text-sm" :class="[
`depth-${depth}`,
depth === 1 ? 'mb-4' : 'mb-2',
]">
2023-07-16 13:18:07 +02:00
<li
2023-09-23 20:02:04 +02:00
v-for="link in realLinks ?? []"
2023-07-16 13:18:07 +02:00
:key="link.text"
2023-09-23 20:02:04 +02:00
:class="[
depth === 2 && 'border-l-2 flex flex-col',
path.includes(link._path) ? 'border-accent-500' : 'border-gray-300 dark:border-gray-600',
2023-09-23 20:02:04 +02:00
]"
2023-07-16 13:18:07 +02:00
>
<GNuxtLink
:to="link._path"
2023-09-29 13:30:13 +02:00
@click.passive="isAsideNavOpen = false"
2023-09-23 20:02:04 +02:00
:class="[
'block hover:text-accent-600',
depth === 1 && 'text-base',
depth === 2 ? 'px-2 py-1' : 'py-1',
isSamePath(path, link._path) && 'text-accent-600 font-bold',
]"
2023-07-16 13:18:07 +02:00
>
2023-09-23 20:02:04 +02:00
<div class="flex">
<button
v-if="link.children && link.children.filter((v) => !isSamePath(v._path, link._path)).length > 0"
class="block px-1 mr-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700"
@click.prevent.stop="() => {
console.log('State:', path.includes(link._path));
manualOpen[link._path] = !(manualOpen[link._path] ?? path.includes(link._path));
}"
>
2023-09-23 20:02:04 +02:00
<ArrowIco
:class="[
'transition-transform',
((path.includes(link._path) && (manualOpen[link._path] !== false)) || manualOpen[link._path]) && 'rotate-90'
2023-09-23 20:02:04 +02:00
]"
/>
</button>
2023-09-23 20:02:04 +02:00
<div>{{ link.title }}</div>
</div>
</GNuxtLink>
2023-07-16 13:18:07 +02:00
<AsideNav
2023-09-23 20:02:04 +02:00
v-if="link.children && link.children.filter((v) => !isSamePath(v._path, link._path)).length > 0"
v-show="(path.includes(link._path) && (manualOpen[link._path] !== false)) || manualOpen[link._path]"
2023-09-23 20:02:04 +02:00
:links="[link]"
:depth="depth + 1"
2023-07-16 13:18:07 +02:00
/>
</li>
</ul>
</template>
<script setup lang="ts">
import type { NavItem } from '@nuxt/content/dist/runtime/types'
2023-09-23 20:02:04 +02:00
import { findDeepObject } from '@/assets/js/misc';
import { isSamePath } from 'ufo';
import ArrowIco from "bi/chevron-right.svg";
2023-07-16 13:18:07 +02:00
2023-09-29 13:30:13 +02:00
const isAsideNavOpen = useState<boolean>('miHub_docs_asideNav_openState', () => false);
const manualOpen = useState<Record<string, boolean>>('miHub-docs-aside-manual-collapse', () => ({}));
onUnmounted(() => {
manualOpen.value = {};
});
2023-09-23 20:02:04 +02:00
const props = withDefaults(defineProps<{
links: NavItem[];
depth?: number;
}>(), {
depth: 1,
2023-07-16 13:18:07 +02:00
});
const { locale } = useI18n();
2023-09-23 20:16:27 +02:00
const router = useRouter();
const route = useRoute();
const path = ref(route.path);
watch(() => route.path, (to) => {
path.value = to;
}, {
immediate: true,
2023-09-23 20:16:27 +02:00
});
2023-07-16 13:18:07 +02:00
2023-09-23 20:02:04 +02:00
const realLinks = findDeepObject(props.links[0], (v) => {
if (props.depth === 1) {
return isSamePath(`/${locale.value}/docs/`, v._path);
} else {
return v._path.includes(props.links[0]._path);
2023-07-16 13:18:07 +02:00
}
2023-09-23 20:02:04 +02:00
})?.children?.filter((v) => !isSamePath(v._path, props.links[0]._path));
const emit = defineEmits(['move', 'child-click']);
2023-07-16 13:18:07 +02:00
</script>
<style scoped>
2023-09-23 20:02:04 +02:00
.toc-links:not(.depth-1) {
@apply ml-6;
2023-07-16 13:18:07 +02:00
}
</style>