66 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
			
		
		
	
	
			66 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
| import { shallowRef, watch } from 'vue';
 | |
| 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 = shallowRef(initialSize.width);
 | |
|   const height = shallowRef(initialSize.height);
 | |
| 
 | |
|   useResizeObserver(
 | |
|     target,
 | |
|     ([entry]) => {
 | |
|       const boxSize =
 | |
|         box === 'border-box'
 | |
|           ? entry.borderBoxSize
 | |
|           : box === 'content-box'
 | |
|           ? entry.contentBoxSize
 | |
|           : entry.devicePixelContentBoxSize;
 | |
| 
 | |
|       if (boxSize) {
 | |
|         width.value = boxSize.reduce((acc, { inlineSize }) => acc + inlineSize, 0);
 | |
|         height.value = boxSize.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>;
 |