mirror of
https://github.com/YunoHost/yunohost-admin.git
synced 2024-09-03 20:06:15 +02:00
112 lines
3.1 KiB
Vue
112 lines
3.1 KiB
Vue
<template>
|
|
<BListGroup :flush="flush" :style="{ '--depth': tree.depth }">
|
|
<template v-for="(node, i) in tree.children">
|
|
<BListGroupItem
|
|
:key="node.id"
|
|
class="list-group-item-action" :class="getClasses(node, i)"
|
|
@click="$router.push(node.data.to)"
|
|
>
|
|
<slot name="default" v-bind="node" />
|
|
|
|
<BButton
|
|
v-if="node.children"
|
|
size="xs" variant="outline-secondary"
|
|
:aria-expanded="node.data.opened ? 'true' : 'false'" :aria-controls="'collapse-' + node.id"
|
|
:class="node.data.opened ? 'not-collapsed' : 'collapsed'" class="ml-2"
|
|
@click.stop="node.data.opened = !node.data.opened"
|
|
>
|
|
<span class="sr-only">{{ toggleText }}</span>
|
|
<YIcon iname="chevron-right" />
|
|
</BButton>
|
|
</BListGroupItem>
|
|
|
|
<BCollapse
|
|
v-if="node.children" :key="'collapse-' + node.id"
|
|
v-model="node.data.opened" :id="'collapse-' + node.id"
|
|
>
|
|
<RecursiveListGroup
|
|
:tree="node"
|
|
:last="last !== undefined ? last : i === tree.children.length - 1" flush
|
|
>
|
|
<!-- PASS THE DEFAULT SLOT WITH SCOPE TO NEXT NESTED COMPONENT -->
|
|
<template slot="default" slot-scope="scope">
|
|
<slot name="default" v-bind="scope" />
|
|
</template>
|
|
</RecursiveListGroup>
|
|
</BCollapse>
|
|
</template>
|
|
</BListGroup>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
name: 'RecursiveListGroup',
|
|
|
|
props: {
|
|
tree: { type: Object, required: true },
|
|
flush: { type: Boolean, default: false },
|
|
last: { type: Boolean, default: undefined },
|
|
toggleText: { type: String, default: null }
|
|
},
|
|
|
|
methods: {
|
|
getClasses (node, i) {
|
|
const children = node.height > 0
|
|
const opened = children && node.data.opened
|
|
const last = this.last !== false && (!children || !opened) && i === this.tree.children.length - 1
|
|
return { collapsible: children, uncollapsible: !children, opened, last }
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.list-group {
|
|
.collapse {
|
|
&:not(.show) + .list-group-item {
|
|
border-end-start-radius: $border-radius;
|
|
}
|
|
&.show + .list-group-item {
|
|
border-start-start-radius: $border-radius;
|
|
}
|
|
|
|
+ .list-group-item {
|
|
border-block-start-width: 1px !important;
|
|
}
|
|
}
|
|
|
|
&-item {
|
|
&-action {
|
|
cursor: pointer;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
width: unset;
|
|
}
|
|
|
|
&.collapsible.opened {
|
|
border-end-start-radius: $border-radius;
|
|
}
|
|
&.collapsible:not(.opened, .last) {
|
|
border-block-end-width: 0;
|
|
}
|
|
|
|
&.last {
|
|
border-block-end-width: $list-group-border-width;
|
|
border-end-start-radius: $border-radius;
|
|
}
|
|
}
|
|
|
|
&-flush .list-group-item {
|
|
margin-inline-start: calc(1rem * var(--depth));
|
|
border-inline-end: $list-group-border-width solid $list-group-border-color;
|
|
border-inline-start: $list-group-border-width solid $list-group-border-color;
|
|
text-decoration: none;
|
|
background-color: $list-group-hover-bg;
|
|
|
|
@include hover-focus() {
|
|
background-color: darken($list-group-hover-bg, 3%);
|
|
}
|
|
}
|
|
}
|
|
</style>
|