diff --git a/src/index.ts b/src/index.ts index 5fc60eb..15841b6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -27,14 +27,23 @@ function useDimensions({ }, []); useLayoutEffect(() => { - if (node) { - const measure = () => - window.requestAnimationFrame(() => - setDimensions(getDimensionObject(node)) - ); - measure(); - - if (liveMeasure) { + if (!node) { + return + } + + const measure = () => + window.requestAnimationFrame(() => + setDimensions(getDimensionObject(node)) + ); + measure(); + + if (liveMeasure) { + if ('ResizeObserver' in window) { + const resizeObserver = new ResizeObserver(measure) + resizeObserver.observe(node) + + return resizeObserver.disconnect + } else { window.addEventListener("resize", measure); window.addEventListener("scroll", measure); diff --git a/src/types.d.ts b/src/types.d.ts index abae2cf..98b32e0 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -18,3 +18,50 @@ export type UseDimensionsHook = [ export interface UseDimensionsArgs { liveMeasure?: boolean; } + +export interface IResizeObserver { + /** + * Adds target to the list of observed elements. + */ + observe: (target: Element) => void + + /** + * Removes target from the list of observed elements. + */ + unobserve: (target: Element) => void + + /** + * Clears both the observationTargets and activeTargets lists. + */ + disconnect: () => void + new (callback: ResizeObserverCallback): this +} + +/** + * This callback delivers ResizeObserver's notifications. It is invoked by a + * broadcast active observations algorithm. + */ +type ResizeObserverCallback = ( + entries: readonly IResizeObserverEntry[], + observer: IResizeObserver +) => void + +interface IResizeObserverEntry { + /** + * The Element whose size has changed. + */ + readonly target: Element + + /** + * Element's content rect when ResizeObserverCallback is invoked. + */ + readonly contentRect: DOMRectReadOnly + /** + * @param target The Element whose size has changed. + */ + new (target: Element): this +} + +declare global { + const ResizeObserver: IResizeObserver +}