feat: add new shared component tree view (prototype)
This commit is contained in:
parent
c8072d10ed
commit
4cd0fdc085
1 changed files with 98 additions and 0 deletions
98
src/components/shared/TreeView.vue
Normal file
98
src/components/shared/TreeView.vue
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
<script setup lang="ts">
|
||||
import { Icon } from '@iconify/vue';
|
||||
type Node = {
|
||||
[key: string]: any;
|
||||
selected?: boolean;
|
||||
children?: Node[];
|
||||
};
|
||||
|
||||
type Props = {
|
||||
level?: number;
|
||||
keyTitle?: string;
|
||||
keySubtitle?: string;
|
||||
decoration?: {
|
||||
level?: number;
|
||||
bg?: string;
|
||||
fg?: string;
|
||||
icon?: string;
|
||||
}[];
|
||||
};
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const currentStyle = props.decoration?.find((v) => {
|
||||
return v.level === (props.level || 0);
|
||||
});
|
||||
|
||||
const nodes = defineModel<Node[]>('nodes', { required: true });
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="tree-container">
|
||||
<div v-for="node in nodes" class="tree-item">
|
||||
<slot
|
||||
v-if="$slots['item']"
|
||||
name="item"
|
||||
:data="{ node, onclick: () => (node.selected = !node.selected) }"
|
||||
/>
|
||||
<template v-else>
|
||||
<label class="row items-center">
|
||||
<input
|
||||
class="item__checkbox"
|
||||
type="checkbox"
|
||||
v-model="node.selected"
|
||||
/>
|
||||
<Icon
|
||||
v-if="currentStyle?.icon"
|
||||
:icon="currentStyle.icon"
|
||||
class="item__icon"
|
||||
/>
|
||||
<div class="column">
|
||||
<span class="item__title">
|
||||
{{ node[keyTitle || 'title'] || 'No Title' }}
|
||||
</span>
|
||||
<span class="item__subtitle">
|
||||
{{ node[keySubtitle || 'subtitle'] || 'No Subtitle' }}
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
</template>
|
||||
<div class="q-pl-xl">
|
||||
<TreeView
|
||||
v-if="node.children"
|
||||
v-model:nodes="node.children"
|
||||
:level="(level || 0) + 1"
|
||||
:decoration
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="css">
|
||||
.tree-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
|
||||
& .tree-item {
|
||||
& .item__checkbox {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
& .item__icon {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
& .item__title {
|
||||
font-weight: 600;
|
||||
color: var(--brand-1);
|
||||
}
|
||||
|
||||
& .item__subtitle {
|
||||
font-size: 80%;
|
||||
color: hsla(var(--text-mute-2));
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
Add table
Add a link
Reference in a new issue