PluginProbe
The Innovative Form Builder – IvyForms / 0.6
The Innovative Form Builder – IvyForms v0.6
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
ivyforms / frontend / src / views / _components / context-menu / IvyContextMenu.vue

IvyContextMenu.vue in The Innovative Form Builder – IvyForms 0.6, at frontend/src/views/_components/context-menu/IvyContextMenu.vue

101 lines 2.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <template>
2 <IvyPopover
3 :visible="isOpen"
4 popper-class="ivyforms-popper-context-menu"
5 :popper-background="'level-1-foreground'"
6 :width="205"
7 placement="bottom-start"
8 :virtual-ref="resolveContextMenuButtonRef"
9 :show-arrow="false"
10 virtual-triggering
11 >
12 <component
13 :is="contextMenuStore.contextMenuContent"
14 :actions="contextMenuStore.contextMenuProps.actions"
15 :entity-id="contextMenuStore.contextMenuProps.entityId"
16 @action-executed="handleActionExecuted"
17 @close-menu="contextMenuStore.closeContextMenu"
18 />
19 </IvyPopover>
20 </template>
21
22 <script setup lang="ts">
23 import { ref, computed, type ComponentPublicInstance } from 'vue'
24 import { storeToRefs } from 'pinia'
25 import { useContextMenuStore } from '@/stores/contextMenuStore.ts'
26 import { watch } from 'vue'
27 import { onClickOutside } from '@vueuse/core'
28 import IvyPopover from '@/views/_components/popover/IvyPopover.vue'
29
30 const contextMenuStore = useContextMenuStore()
31 const { isOpen } = storeToRefs(contextMenuStore)
32
33 const stopClickOutsideListener = ref<null | (() => void)>(null)
34
35 const handleActionExecuted = () => {
36 contextMenuStore.closeContextMenu()
37 }
38
39 const props = computed(() => contextMenuStore.contextMenuProps)
40
41 type MaybeHTMLElement = HTMLElement | (ComponentPublicInstance & { $el: HTMLElement })
42
43 watch(
44 () => props.value.contextMenuButtonRef,
45 (newRef) => {
46 if (stopClickOutsideListener.value) {
47 // Cleanup old listener
48 stopClickOutsideListener.value()
49 }
50 if (newRef instanceof HTMLElement) {
51 stopClickOutsideListener.value = onClickOutside(newRef, () =>
52 contextMenuStore.closeContextMenu(),
53 )
54 } else if (newRef && newRef.$el && newRef.$el instanceof HTMLElement) {
55 stopClickOutsideListener.value = onClickOutside(newRef.$el, () =>
56 contextMenuStore.closeContextMenu(),
57 )
58 } else {
59 stopClickOutsideListener.value = null
60 }
61 },
62 )
63
64 const resolveContextMenuButtonRef = computed(() => {
65 const ref = contextMenuStore.contextMenuProps.contextMenuButtonRef as
66 | MaybeHTMLElement
67 | null
68 | undefined
69 if (ref && '$el' in ref && ref.$el instanceof HTMLElement) {
70 return ref.$el
71 }
72 if (ref instanceof HTMLElement) {
73 return ref
74 }
75 return null
76 })
77
78 // Watch for when the context menu closes and remove the click outside listener
79 watch(isOpen, (newVal) => {
80 if (!newVal && stopClickOutsideListener.value) {
81 stopClickOutsideListener.value()
82 stopClickOutsideListener.value = null
83 }
84 })
85 </script>
86
87 <style lang="scss">
88 // Popper Context Menu
89 .ivyforms-popper-context-menu {
90 // Element Popper
91 &.el-popper.el-popover {
92 padding: 0;
93 border-radius: 2px;
94 background: var(--map-ground-level-2-foreground);
95 box-shadow:
96 0 1px 2px 0 rgba(18, 26, 38, 0.3),
97 0 1px 3px 1px rgba(18, 26, 38, 0.15);
98 }
99 }
100 </style>
101