-
-
Notifications
You must be signed in to change notification settings - Fork 83
Expand file tree
/
Copy pathTreeNode.vue
More file actions
81 lines (77 loc) · 2.37 KB
/
Copy pathTreeNode.vue
File metadata and controls
81 lines (77 loc) · 2.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<script setup lang="ts">
import type { ModuleDest, ModuleTreeNode } from '~~/shared/types'
import { useRoute } from '#app/composables/router'
import { NuxtLink } from '#components'
const props = withDefaults(defineProps<{
node: ModuleTreeNode
icon?: string
iconOpen?: string
link?: string | boolean
linkQueryKey?: string
padding?: number
open?: boolean
}>(), {
icon: 'i-catppuccin:folder icon-catppuccin',
iconOpen: 'i-catppuccin:folder-open icon-catppuccin',
padding: 0,
linkQueryKey: 'module',
})
const emit = defineEmits<{
(e: 'select', node: ModuleDest): void
}>()
const open = defineModel<boolean>('open', { required: false, default: true })
const route = useRoute()
const location = window.location
function select(node: ModuleDest) {
if (!props.link) {
emit('select', node)
}
}
</script>
<template>
<details :open="open" @toggle="e => open = (e.target as HTMLDetailsElement)?.open">
<summary
cursor-default
select-none
text-sm
truncate
:style="{ paddingLeft: `${padding + 0.5}rem` }"
flex="~ gap-1"
px2 py1 rounded
hover="bg-active "
>
<div class="i-ph:caret-right-duotone transition op50" :class="open ? 'rotate-90' : ''" />
<div :class="open ? iconOpen || icon : icon" inline-block vertical-text-bottom />
<div font-mono>
<DisplayHighlightedPath :path="node.name || ''" />
</div>
</summary>
<template v-if="open">
<DisplayTreeNode
v-for="e of Object.entries(node.children)"
:key="e[0]" :node="e[1]" :link="link"
:padding="padding + 1"
:link-query-key="linkQueryKey"
@select="select"
/>
<template v-for="i of node.items" :key="i.full">
<component
:is="link ? NuxtLink : 'div'"
:to="link ? (typeof link === 'string' ? link : { path: route.path, query: { ...route.query, [linkQueryKey]: i.full }, hash: location.hash }) : undefined"
text-sm
ws-nowrap
flex="~ gap-1"
px2 py1 rounded
hover="bg-active"
:style="{ paddingLeft: `${padding + 2.7}rem` }"
@click="select(i)"
>
<DisplayFileIcon :filename="i.full" />
<div font-mono>
<DisplayHighlightedPath :path="i.path.split('/').pop() || ''" />
</div>
</component>
</template>
</template>
</details>
</template>