/
index.ts
66 lines (59 loc) · 1.69 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
63
64
65
66
import { ref, watch } from 'vue-demi'
import type { MaybeComputedElementRef } from '../unrefElement'
import type { UseResizeObserverOptions } from '../useResizeObserver'
import { useResizeObserver } from '../useResizeObserver'
import { unrefElement } from '../unrefElement'
export interface ElementSize {
width: number
height: number
}
/**
* Reactive size of an HTML element.
*
* @see https://vueuse.org/useElementSize
* @param target
* @param callback
* @param options
*/
export function useElementSize(
target: MaybeComputedElementRef,
initialSize: ElementSize = { width: 0, height: 0 },
options: UseResizeObserverOptions = {},
) {
const { box = 'content-box' } = options
const width = ref(initialSize.width)
const height = ref(initialSize.height)
useResizeObserver(
target,
([entry]) => {
const boxSize = box === 'border-box'
? entry.borderBoxSize
: box === 'content-box'
? entry.contentBoxSize
: entry.devicePixelContentBoxSize
if (boxSize) {
const formatBoxSize = Array.isArray(boxSize) ? boxSize : [boxSize]
width.value = formatBoxSize.reduce((acc, { inlineSize }) => acc + inlineSize, 0)
height.value = formatBoxSize.reduce((acc, { blockSize }) => acc + blockSize, 0)
}
else {
// fallback
width.value = entry.contentRect.width
height.value = entry.contentRect.height
}
},
options,
)
watch(
() => unrefElement(target),
(ele) => {
width.value = ele ? initialSize.width : 0
height.value = ele ? initialSize.height : 0
},
)
return {
width,
height,
}
}
export type UseElementSizeReturn = ReturnType<typeof useElementSize>