import { tryOnScopeDispose } from './tryOnScopeDispose'; import { watch } from 'vue'; import type { MaybeComputedElementRef } from './unrefElement'; import { unrefElement } from './unrefElement'; import { useSupported } from './useSupported'; import type { ConfigurableWindow } from './_configurable'; import { defaultWindow } from './_configurable'; export interface ResizeObserverSize { readonly inlineSize: number; readonly blockSize: number; } export interface ResizeObserverEntry { readonly target: Element; readonly contentRect: DOMRectReadOnly; readonly borderBoxSize?: ReadonlyArray; readonly contentBoxSize?: ReadonlyArray; readonly devicePixelContentBoxSize?: ReadonlyArray; } export type ResizeObserverCallback = ( entries: ReadonlyArray, observer: ResizeObserver, ) => void; export interface UseResizeObserverOptions extends ConfigurableWindow { /** * Sets which box model the observer will observe changes to. Possible values * are `content-box` (the default), `border-box` and `device-pixel-content-box`. * * @default 'content-box' */ box?: ResizeObserverBoxOptions; } declare class ResizeObserver { constructor(callback: ResizeObserverCallback); disconnect(): void; observe(target: Element, options?: UseResizeObserverOptions): void; unobserve(target: Element): void; } /** * Reports changes to the dimensions of an Element's content or the border-box * * @see https://vueuse.org/useResizeObserver * @param target * @param callback * @param options */ export function useResizeObserver( target: MaybeComputedElementRef, callback: ResizeObserverCallback, options: UseResizeObserverOptions = {}, ) { const { window = defaultWindow, ...observerOptions } = options; let observer: ResizeObserver | undefined; const isSupported = useSupported(() => window && 'ResizeObserver' in window); const cleanup = () => { if (observer) { observer.disconnect(); observer = undefined; } }; const stopWatch = watch( () => unrefElement(target), el => { cleanup(); if (isSupported.value && window && el) { observer = new ResizeObserver(callback); observer!.observe(el, observerOptions); } }, { immediate: true, flush: 'post' }, ); const stop = () => { cleanup(); stopWatch(); }; tryOnScopeDispose(stop); return { isSupported, stop, }; } export type UseResizeObserverReturn = ReturnType;