PluginProbe
The Innovative Form Builder – IvyForms / 1.1
The Innovative Form Builder – IvyForms v1.1
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 / table / composables / useContextMenuClickOutside.ts

useContextMenuClickOutside.ts in The Innovative Form Builder – IvyForms 1.1, at frontend/src/views/_components/table/composables/useContextMenuClickOutside.ts

51 lines 1.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { onBeforeUnmount, onMounted, type Ref } from 'vue'
2
3 export interface UseContextMenuClickOutsideOptions {
4 selector?: string
5 ignore?: Ref<unknown>[]
6 }
7
8 const DEFAULT_SELECTOR = '.ivyforms-context-menu, .ivyforms-popper-context-menu'
9
10 function resolveElement(value: unknown): HTMLElement | null {
11 if (!value) return null
12 if (value instanceof HTMLElement) return value
13 if (typeof value === 'object' && value !== null && '$el' in value) {
14 const el = (value as { $el: unknown }).$el
15 return el instanceof HTMLElement ? el : null
16 }
17 return null
18 }
19
20 export function useContextMenuClickOutside(
21 close: () => void,
22 options: UseContextMenuClickOutsideOptions = {},
23 ) {
24 const { selector = DEFAULT_SELECTOR, ignore = [] } = options
25
26 const handler = (event: MouseEvent) => {
27 const target = event.target
28 if (!(target instanceof Node)) return
29
30 const menus = document.querySelectorAll(selector)
31 for (const menu of menus) {
32 if (menu.contains(target)) return
33 }
34
35 for (const ref of ignore) {
36 const el = resolveElement(ref.value)
37 if (el?.contains(target)) return
38 }
39
40 close()
41 }
42
43 onMounted(() => {
44 document.addEventListener('mousedown', handler)
45 })
46
47 onBeforeUnmount(() => {
48 document.removeEventListener('mousedown', handler)
49 })
50 }
51