mirror of
https://github.com/directus/directus.git
synced 2026-01-29 21:28:02 -05:00
add modeling of active items in v-list
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="v-list-group" v-click-outside="{handler: onClickOutside, events: ['pointerup']}">
|
||||
<div class="v-list-group">
|
||||
<v-list-item :active="active" class="activator" :to="to" :exact="exact" @click="onClick" :disabled="disabled">
|
||||
<slot name="activator" :active="groupActive" />
|
||||
|
||||
@@ -15,10 +15,14 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, nextTick, toRefs, watch } from '@vue/composition-api';
|
||||
import { defineComponent, nextTick, toRefs, watch, PropType, ref } from '@vue/composition-api';
|
||||
import { useGroupableParent, useGroupable } from '@/composables/groupable';
|
||||
|
||||
export default defineComponent({
|
||||
model: {
|
||||
prop: 'activeItems',
|
||||
event: 'input'
|
||||
},
|
||||
props: {
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
@@ -28,6 +32,10 @@ export default defineComponent({
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
activeItems: {
|
||||
type: Array as PropType<(number | string)[]>,
|
||||
default: null
|
||||
},
|
||||
active: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
@@ -51,13 +59,11 @@ export default defineComponent({
|
||||
value: {
|
||||
type: [String, Number],
|
||||
default: undefined,
|
||||
},
|
||||
accordion: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
setup(props, { listeners, emit, root }) {
|
||||
setup(props, { listeners, emit }) {
|
||||
const {activeItems, multiple} = toRefs(props)
|
||||
|
||||
const { active: groupActive, toggle, activate, deactivate } = useGroupable({
|
||||
group: props.scope,
|
||||
value: props.value,
|
||||
@@ -65,14 +71,21 @@ export default defineComponent({
|
||||
|
||||
if (props.disableGroupableParent !== true) {
|
||||
useGroupableParent(
|
||||
{},
|
||||
{
|
||||
multiple: toRefs(props).multiple,
|
||||
selection: activeItems,
|
||||
onSelectionChange: (newSelection) => {
|
||||
emit('input', newSelection)
|
||||
}
|
||||
},
|
||||
{
|
||||
multiple
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
||||
return { groupActive, toggle, onClick, onClickOutside };
|
||||
return { groupActive, toggle, onClick };
|
||||
|
||||
function onClick(event: MouseEvent) {
|
||||
if (props.to) return null;
|
||||
@@ -81,10 +94,6 @@ export default defineComponent({
|
||||
event.stopPropagation();
|
||||
toggle();
|
||||
}
|
||||
|
||||
function onClickOutside() {
|
||||
if(props.accordion) deactivate()
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -18,7 +18,15 @@ import { defineComponent, PropType, ref, toRefs } from '@vue/composition-api';
|
||||
import { useGroupableParent } from '@/composables/groupable';
|
||||
|
||||
export default defineComponent({
|
||||
model: {
|
||||
prop: 'activeItems',
|
||||
event: 'input'
|
||||
},
|
||||
props: {
|
||||
activeItems: {
|
||||
type: Array as PropType<(number | string)[]>,
|
||||
default: () => []
|
||||
},
|
||||
dense: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
@@ -36,12 +44,18 @@ export default defineComponent({
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
setup(props, {emit}) {
|
||||
const {activeItems, multiple} = toRefs(props)
|
||||
useGroupableParent(
|
||||
{},
|
||||
{
|
||||
selection: activeItems,
|
||||
onSelectionChange: (newSelection) => {
|
||||
emit('input', newSelection)
|
||||
}
|
||||
},
|
||||
{
|
||||
mandatory: ref(false),
|
||||
multiple: toRefs(props).multiple,
|
||||
multiple
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-list-item v-if="section.children === undefined" :to="section.to" :dense="dense">
|
||||
<v-list-item v-if="section.children === undefined" :to="section.to" :dense="dense" :value="itemValue">
|
||||
<v-list-item-icon v-if="section.icon !== undefined"><v-icon :name="section.icon" /></v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ section.name }}</v-list-item-title>
|
||||
@@ -14,7 +14,7 @@
|
||||
dense
|
||||
/>
|
||||
</div>
|
||||
<v-list-group v-else accordion>
|
||||
<v-list-group v-else :multiple="false" v-model="rootSelection" :value="itemValue">
|
||||
<template #activator>
|
||||
<v-list-item-icon v-if="section.icon !== undefined"><v-icon :name="section.icon" /></v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
@@ -22,16 +22,17 @@
|
||||
</v-list-item-content>
|
||||
</template>
|
||||
<navigation-list-item
|
||||
v-for="(childSection, index) in section.children"
|
||||
v-for="(child, index) in section.children"
|
||||
:key="index"
|
||||
:section="childSection"
|
||||
:section="child"
|
||||
v-model="childSelection"
|
||||
dense
|
||||
/>
|
||||
</v-list-group>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, PropType } from '@vue/composition-api';
|
||||
import { defineComponent, PropType, computed } from '@vue/composition-api';
|
||||
import { Section } from './sections';
|
||||
|
||||
export default defineComponent({
|
||||
@@ -45,7 +46,38 @@ export default defineComponent({
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
value: {
|
||||
type: Array as PropType<string[]>,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
setup(props, {emit}) {
|
||||
const rootSelection = computed({
|
||||
get() {
|
||||
if(props.value.length === 0) return []
|
||||
return [props.value[0]]
|
||||
},
|
||||
set(newVal: string[]) {
|
||||
emit('input', newVal);
|
||||
}
|
||||
})
|
||||
|
||||
const childSelection = computed({
|
||||
get() {
|
||||
if(props.value.length < 2) return []
|
||||
return props.value.slice(1)
|
||||
},
|
||||
set(newVal: string[]) {
|
||||
emit('input', [props.value[0], ...newVal])
|
||||
}
|
||||
})
|
||||
|
||||
const itemValue = computed(() => {
|
||||
return props.section.to.split('/').pop()
|
||||
})
|
||||
|
||||
return {rootSelection, childSelection, itemValue}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,18 +1,51 @@
|
||||
<template>
|
||||
<v-list nav>
|
||||
<navigation-item v-for="item in sections" :key="item.to" :section="item"></navigation-item>
|
||||
<v-list nav :multiple="false" v-model="rootSelection">
|
||||
<navigation-item v-for="item in sections" :key="item.to" :section="item" v-model="childSelection"></navigation-item>
|
||||
</v-list>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from '@vue/composition-api';
|
||||
import { computed, defineComponent, PropType, ref, watch } from '@vue/composition-api';
|
||||
import NavigationItem from './navigation-item.vue';
|
||||
import sections from './sections';
|
||||
import sections, {Section} from './sections';
|
||||
|
||||
export default defineComponent({
|
||||
components: { NavigationItem },
|
||||
setup() {
|
||||
return { sections };
|
||||
props: {
|
||||
section: {
|
||||
type: Object as PropType<Section>,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const active = ref<string[]>(props.section.to.replace('/docs/','').split('/'))
|
||||
|
||||
watch(props.section, (newSection) => {
|
||||
if(newSection !== null)
|
||||
active.value = newSection.to.replace('/docs/','').split('/')
|
||||
})
|
||||
|
||||
const rootSelection = computed({
|
||||
get() {
|
||||
if(active.value.length === 0) return []
|
||||
return [active.value[0]]
|
||||
},
|
||||
set(newVal: string[]) {
|
||||
active.value = newVal
|
||||
}
|
||||
})
|
||||
|
||||
const childSelection = computed({
|
||||
get() {
|
||||
if(active.value.length < 2) return []
|
||||
return active.value.slice(1)
|
||||
},
|
||||
set(newVal: string[]) {
|
||||
active.value = [active.value[0], ...newVal]
|
||||
}
|
||||
})
|
||||
|
||||
return { sections, active, childSelection, rootSelection };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</template>
|
||||
|
||||
<template #navigation>
|
||||
<docs-navigation />
|
||||
<docs-navigation :section="section" />
|
||||
</template>
|
||||
|
||||
<div v-if="notFound" class="not-found">
|
||||
|
||||
Reference in New Issue
Block a user