Files
dougal-software/lib/www/client/source/src/components/context-menu.vue
D. Berge 0be5dba2b9 Return also labels from <dougal-context-menu/>.
Keeping in mind that the input model is a tree and labels
may be at any level in the tree, not just in the leaves.
2022-02-27 19:56:21 +01:00

114 lines
2.5 KiB
Vue

<template>
<v-menu
:value="value"
@input="(e) => $emit('input', e)"
:position-x="absolute && x || undefined"
:position-y="absolute && y || undefined"
:absolute="absolute"
:close-on-content-click="submenu"
offset-y offset-x
>
<slot v-for="(_, name) in $slots" :name="name" :slot="name"></slot>
<template v-for="(_, name) in $scopedSlots" :slot="name" slot-scope="slotData">
<slot :name="name" v-bind="slotData"></slot>
</template>
<v-list>
<template
v-for="(item, index) in items"
>
<dougal-context-menu v-if="item.items"
:value="showSubmenu"
:items="item.items"
:labels="labels.concat(item.labels||[])"
@input="selected"
submenu>
<template v-slot:activator="{ on, attrs }">
<v-list-item v-on="on" v-bind="attrs">
<v-list-item-title>
{{ item.text }}
</v-list-item-title>
<v-list-item-action class="justify-end">
<v-icon>mdi-chevron-right</v-icon>
</v-list-item-action>
</v-list-item>
</template>
</dougal-context-menu>
<v-list-item v-else
:key="index"
@click="$emit('input', item)"
>
<v-list-item-title>
{{ item.text }}
</v-list-item-title>
</v-list-item>
</template>
</v-list>
</v-menu>
</template>
<script>
export default {
name: "DougalContextMenu",
props: {
value: { type: [ MouseEvent, Object, Boolean ] },
labels: { type: [ Array ], default: () => [] },
absolute: { type: Boolean, default: false },
submenu: { type: Boolean, default: false },
items: { type: Array, default: () => [] }
},
data () {
return {
x: 0,
y: 0,
showSubmenu: false
}
},
watch: {
value (val) {
if (val.type) {
this.showMenu(val);
}
this.show = val;
},
show (val) {
if (val != this.value) {
//this.$emit('input', val);
}
}
},
methods: {
showMenu (e) {
e.preventDefault()
this.show = false
this.x = e.clientX
this.y = e.clientY
this.$nextTick(() => {
this.show = true
})
},
selected (item) {
this.show = false;
if (typeof item === 'object' && item !== null) {
const labels = this.labels.concat(item.labels??[]);
this.$emit('input', {...item, labels});
} else {
this.$emit('input', item);
}
}
}
}
</script>