From 2e0214dd684f630cc70cc214e110ab1f7c14b66e Mon Sep 17 00:00:00 2001 From: Ty Mick Date: Mon, 9 Mar 2020 19:24:56 -0500 Subject: [PATCH] Add option for different types of dimensions Hi, @ZeeCoder! Came across your project looking for a hook that would keep track of changes to element `offsetWidth`/`offsetHeight`. I love your implementation of the `ResizeObserver` API, and I ended up finding the API can track offset, client, and scroll dimensions as well via `ResizeObserverEntry.target`. What would you think of adding one more option called something like `type`, leaving `"content"` as default but adding the option for `"offset"`, `"client"`, and `"scroll"` as well? This edit's been tracking `offsetWidth` and `offsetHeight` perfectly for me so far. --- src/index.js | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/index.js b/src/index.js index fc3304c..c890d05 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,6 @@ import { useEffect, useState, useRef, useMemo } from "react"; -export default function({ ref, onResize } = {}) { +export default function({ ref, onResize, type } = {}) { // `defaultRef` Has to be non-conditionally declared here whether or not it'll // be used as that's how hooks work. // @see https://reactjs.org/docs/hooks-rules.html#explanation @@ -40,9 +40,31 @@ export default function({ ref, onResize } = {}) { const entry = entries[0]; - // `Math.round` is in line with how CSS resolves sub-pixel values - const newWidth = Math.round(entry.contentRect.width); - const newHeight = Math.round(entry.contentRect.height); + let newWidth, newHeight; + switch (type) { + case "scroll": + // Actual size of content and padding, including content hidden by + // element-level scroll bars + newWidth = entry.target.scrollWidth; + newHeight = entry.target.scrollHeight; + break; + case "client": + // Displayed size of content and padding + newWidth = entry.target.clientWidth; + newHeight = entry.target.clientHeight; + break; + case "offset": + // Displayed size of content, padding, and border + newWidth = entry.target.offsetWidth; + newHeight = entry.target.offsetHeight; + break; + case "content": + default: + // Displayed size of content only + // `Math.round` is in line with how CSS resolves sub-pixel values + newWidth = Math.round(entry.contentRect.width); + newHeight = Math.round(entry.contentRect.height); + } if ( previous.current.width !== newWidth || previous.current.height !== newHeight