/
index.ts
62 lines (53 loc) · 1.86 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import type { Ref } from 'vue-demi'
import { ref } from 'vue-demi'
import type { MaybeRefOrGetter, Pausable } from '@vueuse/shared'
import { toValue, useIntervalFn } from '@vueuse/shared'
import { useRafFn } from '../useRafFn'
import type { ConfigurableDocument } from '../_configurable'
import { defaultDocument } from '../_configurable'
import { useSupported } from '../useSupported'
export interface UseElementByPointOptions<Multiple extends boolean = false> extends ConfigurableDocument {
x: MaybeRefOrGetter<number>
y: MaybeRefOrGetter<number>
multiple?: MaybeRefOrGetter<Multiple>
immediate?: boolean
interval?: 'requestAnimationFrame' | number
}
export interface UseElementByPointReturn<Multiple extends boolean = false> extends Pausable {
isSupported: Ref<boolean>
element: Ref<Multiple extends true ? HTMLElement[] : HTMLElement | null>
}
/**
* Reactive element by point.
*
* @see https://vueuse.org/useElementByPoint
* @param options - UseElementByPointOptions
*/
export function useElementByPoint<M extends boolean = false>(options: UseElementByPointOptions<M>): UseElementByPointReturn<M> {
const {
x, y,
document = defaultDocument,
multiple,
interval = 'requestAnimationFrame',
immediate = true,
} = options
const isSupported = useSupported(() => {
if (toValue(multiple))
return document && 'elementsFromPoint' in document
return document && 'elementFromPoint' in document
})
const element = ref<any>(null)
const cb = () => {
element.value = toValue(multiple)
? document?.elementsFromPoint(toValue(x), toValue(y)) ?? []
: document?.elementFromPoint(toValue(x), toValue(y)) ?? null
}
const controls: Pausable = interval === 'requestAnimationFrame'
? useRafFn(cb, { immediate })
: useIntervalFn(cb, interval, { immediate })
return {
isSupported,
element,
...controls,
}
}