react-use-rect
Advanced tools
Comparing version
@@ -1,16 +0,2 @@ | ||
export interface Rect { | ||
bottom: number; | ||
height: number; | ||
left: number; | ||
right: number; | ||
top: number; | ||
width: number; | ||
x: number; | ||
y: number; | ||
} | ||
export interface Options { | ||
resize?: boolean; | ||
scroll?: boolean; | ||
transitionEnd?: boolean; | ||
} | ||
export declare function useRect({ resize, scroll, transitionEnd }?: Options): [(targetElement: Element | null) => void, Rect]; | ||
export * from './types'; | ||
export * from './useRect'; |
@@ -5,45 +5,21 @@ 'use strict'; | ||
var react = require('react'); | ||
var resizeObserver = require('@juggle/resize-observer'); | ||
var react = require('react'); | ||
function _unsupportedIterableToArray(o, minLen) { | ||
if (!o) return; | ||
if (typeof o === "string") return _arrayLikeToArray(o, minLen); | ||
var n = Object.prototype.toString.call(o).slice(8, -1); | ||
if (n === "Object" && o.constructor) n = o.constructor.name; | ||
if (n === "Map" || n === "Set") return Array.from(o); | ||
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); | ||
} | ||
function _extends() { | ||
_extends = Object.assign || function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
function _arrayLikeToArray(arr, len) { | ||
if (len == null || len > arr.length) len = arr.length; | ||
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; | ||
return arr2; | ||
} | ||
function _createForOfIteratorHelperLoose(o, allowArrayLike) { | ||
var it; | ||
if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { | ||
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { | ||
if (it) o = it; | ||
var i = 0; | ||
return function () { | ||
if (i >= o.length) return { | ||
done: true | ||
}; | ||
return { | ||
done: false, | ||
value: o[i++] | ||
}; | ||
}; | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); | ||
} | ||
return target; | ||
}; | ||
it = o[Symbol.iterator](); | ||
return it.next.bind(it); | ||
return _extends.apply(this, arguments); | ||
} | ||
@@ -61,118 +37,119 @@ | ||
}; | ||
var DEFAULT_OPTIONS = { | ||
scroll: false, | ||
transitionEnd: false | ||
}; | ||
var RECT_KEYS = ['bottom', 'height', 'left', 'right', 'top', 'width', 'x', 'y']; | ||
function areRectsNotEqual(rectA, rectB) { | ||
return rectA !== rectB && RECT_KEYS.some(function (key) { | ||
return rectA[key] !== rectB[key]; | ||
}); | ||
} | ||
function areRectsDifferent(rectA, rectB) { | ||
for (var _iterator = _createForOfIteratorHelperLoose(RECT_KEYS), _step; !(_step = _iterator()).done;) { | ||
var key = _step.value; | ||
var useIsomorphicLayoutEffect = typeof window === 'undefined' ? react.useEffect : react.useLayoutEffect; | ||
if (rectA[key] !== rectB[key]) { | ||
return true; | ||
} | ||
} | ||
function getElementRect(element) { | ||
var _element$getBoundingC = element.getBoundingClientRect(), | ||
bottom = _element$getBoundingC.bottom, | ||
height = _element$getBoundingC.height, | ||
left = _element$getBoundingC.left, | ||
right = _element$getBoundingC.right, | ||
top = _element$getBoundingC.top, | ||
width = _element$getBoundingC.width, | ||
x = _element$getBoundingC.x, | ||
y = _element$getBoundingC.y; | ||
return false; | ||
return { | ||
bottom: bottom, | ||
height: height, | ||
left: left, | ||
right: right, | ||
top: top, | ||
width: width, | ||
x: x, | ||
y: y | ||
}; | ||
} | ||
var useIsomorphicLayoutEffect = typeof window === 'undefined' ? react.useEffect : react.useLayoutEffect; | ||
var LISTENER_CONFIG = { | ||
capture: true, | ||
passive: true | ||
}; | ||
function listenTo(eventType, listener) { | ||
window.addEventListener(eventType, listener, LISTENER_CONFIG); | ||
return function () { | ||
window.removeEventListener(eventType, listener, LISTENER_CONFIG); | ||
}; | ||
} | ||
function useRerender() { | ||
var _useState = react.useState({}), | ||
rerender = _useState[1]; | ||
function useRect(options) { | ||
if (options === void 0) { | ||
options = {}; | ||
} | ||
return react.useCallback(function () { | ||
return rerender({}); | ||
}, []); | ||
} | ||
var _DEFAULT_OPTIONS$opti = _extends({}, DEFAULT_OPTIONS, options), | ||
scroll = _DEFAULT_OPTIONS$opti.scroll, | ||
transitionEnd = _DEFAULT_OPTIONS$opti.transitionEnd; | ||
function useRect(_temp) { | ||
var _ref = _temp === void 0 ? {} : _temp, | ||
_ref$resize = _ref.resize, | ||
resize = _ref$resize === void 0 ? true : _ref$resize, | ||
_ref$scroll = _ref.scroll, | ||
scroll = _ref$scroll === void 0 ? true : _ref$scroll, | ||
_ref$transitionEnd = _ref.transitionEnd, | ||
transitionEnd = _ref$transitionEnd === void 0 ? true : _ref$transitionEnd; | ||
var _useState = react.useState(DEFAULT_RECT), | ||
rect = _useState[0], | ||
setRect = _useState[1]; | ||
var resizeObserverRef = react.useRef(); | ||
var targetElementRef = react.useRef(); | ||
var rectRef = react.useRef(DEFAULT_RECT); | ||
var rerender = useRerender(); | ||
var updateRect = react.useCallback(function () { | ||
if (!targetElementRef.current) { | ||
if (rectRef.current !== DEFAULT_RECT) { | ||
rectRef.current = DEFAULT_RECT; | ||
rerender(); | ||
} | ||
var _useState2 = react.useState(null), | ||
element = _useState2[0], | ||
setElement = _useState2[1]; | ||
var update = react.useCallback(function () { | ||
if (!element) { | ||
setRect(DEFAULT_RECT); | ||
return; | ||
} | ||
var clientRect = targetElementRef.current.getBoundingClientRect(); | ||
var nextRect = { | ||
bottom: clientRect.bottom, | ||
height: clientRect.height, | ||
left: clientRect.left, | ||
right: clientRect.right, | ||
top: clientRect.top, | ||
width: clientRect.width, | ||
x: clientRect.x, | ||
y: clientRect.y | ||
}; | ||
var nextRect = getElementRect(element); | ||
if (areRectsDifferent(rectRef.current, nextRect)) { | ||
rectRef.current = nextRect; | ||
rerender(); | ||
if (areRectsNotEqual(rect, nextRect)) { | ||
setRect(nextRect); | ||
} | ||
}, [rerender]); | ||
var targetElementCallbackRef = react.useCallback(function (targetElement) { | ||
targetElementRef.current = targetElement !== null && targetElement !== void 0 ? targetElement : undefined; | ||
if (resizeObserverRef.current) { | ||
resizeObserverRef.current.disconnect(); | ||
resizeObserverRef.current = undefined; | ||
}, [element, rect]); | ||
useIsomorphicLayoutEffect(update); | ||
var updateRef = react.useRef(update); | ||
updateRef.current = update; | ||
react.useEffect(function () { | ||
return listenTo('resize', function () { | ||
return updateRef.current(); | ||
}); | ||
}); | ||
react.useEffect(function () { | ||
if (!scroll) { | ||
return; | ||
} | ||
if (targetElementRef.current) { | ||
resizeObserverRef.current = new resizeObserver.ResizeObserver(updateRect); | ||
resizeObserverRef.current.observe(targetElementRef.current); | ||
return listenTo('scroll', function () { | ||
return updateRef.current(); | ||
}); | ||
}, [scroll]); | ||
react.useEffect(function () { | ||
if (!transitionEnd) { | ||
return; | ||
} | ||
}, [updateRect]); | ||
useIsomorphicLayoutEffect(function () { | ||
var globalEventListener = function globalEventListener() { | ||
return updateRect(); | ||
}; | ||
var globalEventConfig = { | ||
capture: true, | ||
passive: true | ||
}; | ||
if (resize) { | ||
window.addEventListener('resize', globalEventListener, globalEventConfig); | ||
return listenTo('transitionend', function () { | ||
return updateRef.current(); | ||
}); | ||
}, [transitionEnd]); | ||
react.useEffect(function () { | ||
if (!element) { | ||
return; | ||
} | ||
if (scroll) { | ||
window.addEventListener('scroll', globalEventListener, globalEventConfig); | ||
} | ||
if (transitionEnd) { | ||
window.addEventListener('transitionend', globalEventListener, globalEventConfig); | ||
} | ||
var observer = new resizeObserver.ResizeObserver(function () { | ||
return updateRef.current(); | ||
}); | ||
observer.observe(element); | ||
return function () { | ||
if (resize) { | ||
window.removeEventListener('resize', globalEventListener, globalEventConfig); | ||
} | ||
if (scroll) { | ||
window.removeEventListener('scroll', globalEventListener, globalEventConfig); | ||
} | ||
if (transitionEnd) { | ||
window.removeEventListener('transitionend', globalEventListener, globalEventConfig); | ||
} | ||
return observer.disconnect(); | ||
}; | ||
}, [resize, scroll, transitionEnd, updateRect]); | ||
useIsomorphicLayoutEffect(updateRect); | ||
return [targetElementCallbackRef, rectRef.current]; | ||
}, [element]); | ||
return [rect, setElement]; | ||
} | ||
@@ -179,0 +156,0 @@ |
@@ -1,2 +0,2 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@juggle/resize-observer"),t=require("react");function r(e,t){(null==t||t>e.length)&&(t=e.length);for(var r=0,n=new Array(t);r<t;r++)n[r]=e[r];return n}var n={bottom:0,height:0,left:0,right:0,top:0,width:0,x:0,y:0},o=["bottom","height","left","right","top","width","x","y"],i="undefined"==typeof window?t.useEffect:t.useLayoutEffect;exports.useRect=function(u){var a=void 0===u?{}:u,c=a.resize,s=void 0===c||c,d=a.scroll,l=void 0===d||d,f=a.transitionEnd,v=void 0===f||f,b=t.useRef(),h=t.useRef(),w=t.useRef(n),y=function(){var e=t.useState({})[1];return t.useCallback((function(){return e({})}),[])}(),g=t.useCallback((function(){if(h.current){var e=h.current.getBoundingClientRect(),t={bottom:e.bottom,height:e.height,left:e.left,right:e.right,top:e.top,width:e.width,x:e.x,y:e.y};(function(e,t){for(var n,i=function(e,t){var n;if("undefined"==typeof Symbol||null==e[Symbol.iterator]){if(Array.isArray(e)||(n=function(e,t){if(e){if("string"==typeof e)return r(e,void 0);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(e,void 0):void 0}}(e))){n&&(e=n);var o=0;return function(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}return(n=e[Symbol.iterator]()).next.bind(n)}(o);!(n=i()).done;){var u=n.value;if(e[u]!==t[u])return!0}return!1})(w.current,t)&&(w.current=t,y())}else w.current!==n&&(w.current=n,y())}),[y]),m=t.useCallback((function(t){h.current=null!=t?t:void 0,b.current&&(b.current.disconnect(),b.current=void 0),h.current&&(b.current=new e.ResizeObserver(g),b.current.observe(h.current))}),[g]);return i((function(){var e=function(){return g()},t={capture:!0,passive:!0};return s&&window.addEventListener("resize",e,t),l&&window.addEventListener("scroll",e,t),v&&window.addEventListener("transitionend",e,t),function(){s&&window.removeEventListener("resize",e,t),l&&window.removeEventListener("scroll",e,t),v&&window.removeEventListener("transitionend",e,t)}}),[s,l,v,g]),i(g),[m,w.current]}; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t=require("react"),e=require("@juggle/resize-observer");function r(){return(r=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(t[n]=r[n])}return t}).apply(this,arguments)}var n={bottom:0,height:0,left:0,right:0,top:0,width:0,x:0,y:0},i={scroll:!1,transitionEnd:!1},u=["bottom","height","left","right","top","width","x","y"],o="undefined"==typeof window?t.useEffect:t.useLayoutEffect,c={capture:!0,passive:!0};function f(t,e){return window.addEventListener(t,e,c),function(){window.removeEventListener(t,e,c)}}exports.useRect=function(c){void 0===c&&(c={});var s=r({},i,c),a=s.scroll,l=s.transitionEnd,d=t.useState(n),h=d[0],v=d[1],p=t.useState(null),g=p[0],w=p[1],b=t.useCallback((function(){if(g){var t,e,r=function(t){var e=t.getBoundingClientRect();return{bottom:e.bottom,height:e.height,left:e.left,right:e.right,top:e.top,width:e.width,x:e.x,y:e.y}}(g);(t=h)!==(e=r)&&u.some((function(r){return t[r]!==e[r]}))&&v(r)}else v(n)}),[g,h]);o(b);var y=t.useRef(b);return y.current=b,t.useEffect((function(){return f("resize",(function(){return y.current()}))})),t.useEffect((function(){if(a)return f("scroll",(function(){return y.current()}))}),[a]),t.useEffect((function(){if(l)return f("transitionend",(function(){return y.current()}))}),[l]),t.useEffect((function(){if(g){var t=new e.ResizeObserver((function(){return y.current()}));return t.observe(g),function(){return t.disconnect()}}}),[g]),[h,w]}; | ||
//# sourceMappingURL=react-use-rect.cjs.production.min.js.map |
@@ -0,44 +1,20 @@ | ||
import { useEffect, useLayoutEffect, useState, useCallback, useRef } from 'react'; | ||
import { ResizeObserver } from '@juggle/resize-observer'; | ||
import { useRef, useCallback, useEffect, useLayoutEffect, useState } from 'react'; | ||
function _unsupportedIterableToArray(o, minLen) { | ||
if (!o) return; | ||
if (typeof o === "string") return _arrayLikeToArray(o, minLen); | ||
var n = Object.prototype.toString.call(o).slice(8, -1); | ||
if (n === "Object" && o.constructor) n = o.constructor.name; | ||
if (n === "Map" || n === "Set") return Array.from(o); | ||
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); | ||
} | ||
function _extends() { | ||
_extends = Object.assign || function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
function _arrayLikeToArray(arr, len) { | ||
if (len == null || len > arr.length) len = arr.length; | ||
for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; | ||
return arr2; | ||
} | ||
function _createForOfIteratorHelperLoose(o, allowArrayLike) { | ||
var it; | ||
if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { | ||
if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { | ||
if (it) o = it; | ||
var i = 0; | ||
return function () { | ||
if (i >= o.length) return { | ||
done: true | ||
}; | ||
return { | ||
done: false, | ||
value: o[i++] | ||
}; | ||
}; | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); | ||
} | ||
return target; | ||
}; | ||
it = o[Symbol.iterator](); | ||
return it.next.bind(it); | ||
return _extends.apply(this, arguments); | ||
} | ||
@@ -56,118 +32,119 @@ | ||
}; | ||
var DEFAULT_OPTIONS = { | ||
scroll: false, | ||
transitionEnd: false | ||
}; | ||
var RECT_KEYS = ['bottom', 'height', 'left', 'right', 'top', 'width', 'x', 'y']; | ||
function areRectsNotEqual(rectA, rectB) { | ||
return rectA !== rectB && RECT_KEYS.some(function (key) { | ||
return rectA[key] !== rectB[key]; | ||
}); | ||
} | ||
function areRectsDifferent(rectA, rectB) { | ||
for (var _iterator = _createForOfIteratorHelperLoose(RECT_KEYS), _step; !(_step = _iterator()).done;) { | ||
var key = _step.value; | ||
var useIsomorphicLayoutEffect = typeof window === 'undefined' ? useEffect : useLayoutEffect; | ||
if (rectA[key] !== rectB[key]) { | ||
return true; | ||
} | ||
} | ||
function getElementRect(element) { | ||
var _element$getBoundingC = element.getBoundingClientRect(), | ||
bottom = _element$getBoundingC.bottom, | ||
height = _element$getBoundingC.height, | ||
left = _element$getBoundingC.left, | ||
right = _element$getBoundingC.right, | ||
top = _element$getBoundingC.top, | ||
width = _element$getBoundingC.width, | ||
x = _element$getBoundingC.x, | ||
y = _element$getBoundingC.y; | ||
return false; | ||
return { | ||
bottom: bottom, | ||
height: height, | ||
left: left, | ||
right: right, | ||
top: top, | ||
width: width, | ||
x: x, | ||
y: y | ||
}; | ||
} | ||
var useIsomorphicLayoutEffect = typeof window === 'undefined' ? useEffect : useLayoutEffect; | ||
var LISTENER_CONFIG = { | ||
capture: true, | ||
passive: true | ||
}; | ||
function listenTo(eventType, listener) { | ||
window.addEventListener(eventType, listener, LISTENER_CONFIG); | ||
return function () { | ||
window.removeEventListener(eventType, listener, LISTENER_CONFIG); | ||
}; | ||
} | ||
function useRerender() { | ||
var _useState = useState({}), | ||
rerender = _useState[1]; | ||
function useRect(options) { | ||
if (options === void 0) { | ||
options = {}; | ||
} | ||
return useCallback(function () { | ||
return rerender({}); | ||
}, []); | ||
} | ||
var _DEFAULT_OPTIONS$opti = _extends({}, DEFAULT_OPTIONS, options), | ||
scroll = _DEFAULT_OPTIONS$opti.scroll, | ||
transitionEnd = _DEFAULT_OPTIONS$opti.transitionEnd; | ||
function useRect(_temp) { | ||
var _ref = _temp === void 0 ? {} : _temp, | ||
_ref$resize = _ref.resize, | ||
resize = _ref$resize === void 0 ? true : _ref$resize, | ||
_ref$scroll = _ref.scroll, | ||
scroll = _ref$scroll === void 0 ? true : _ref$scroll, | ||
_ref$transitionEnd = _ref.transitionEnd, | ||
transitionEnd = _ref$transitionEnd === void 0 ? true : _ref$transitionEnd; | ||
var _useState = useState(DEFAULT_RECT), | ||
rect = _useState[0], | ||
setRect = _useState[1]; | ||
var resizeObserverRef = useRef(); | ||
var targetElementRef = useRef(); | ||
var rectRef = useRef(DEFAULT_RECT); | ||
var rerender = useRerender(); | ||
var updateRect = useCallback(function () { | ||
if (!targetElementRef.current) { | ||
if (rectRef.current !== DEFAULT_RECT) { | ||
rectRef.current = DEFAULT_RECT; | ||
rerender(); | ||
} | ||
var _useState2 = useState(null), | ||
element = _useState2[0], | ||
setElement = _useState2[1]; | ||
var update = useCallback(function () { | ||
if (!element) { | ||
setRect(DEFAULT_RECT); | ||
return; | ||
} | ||
var clientRect = targetElementRef.current.getBoundingClientRect(); | ||
var nextRect = { | ||
bottom: clientRect.bottom, | ||
height: clientRect.height, | ||
left: clientRect.left, | ||
right: clientRect.right, | ||
top: clientRect.top, | ||
width: clientRect.width, | ||
x: clientRect.x, | ||
y: clientRect.y | ||
}; | ||
var nextRect = getElementRect(element); | ||
if (areRectsDifferent(rectRef.current, nextRect)) { | ||
rectRef.current = nextRect; | ||
rerender(); | ||
if (areRectsNotEqual(rect, nextRect)) { | ||
setRect(nextRect); | ||
} | ||
}, [rerender]); | ||
var targetElementCallbackRef = useCallback(function (targetElement) { | ||
targetElementRef.current = targetElement !== null && targetElement !== void 0 ? targetElement : undefined; | ||
if (resizeObserverRef.current) { | ||
resizeObserverRef.current.disconnect(); | ||
resizeObserverRef.current = undefined; | ||
}, [element, rect]); | ||
useIsomorphicLayoutEffect(update); | ||
var updateRef = useRef(update); | ||
updateRef.current = update; | ||
useEffect(function () { | ||
return listenTo('resize', function () { | ||
return updateRef.current(); | ||
}); | ||
}); | ||
useEffect(function () { | ||
if (!scroll) { | ||
return; | ||
} | ||
if (targetElementRef.current) { | ||
resizeObserverRef.current = new ResizeObserver(updateRect); | ||
resizeObserverRef.current.observe(targetElementRef.current); | ||
return listenTo('scroll', function () { | ||
return updateRef.current(); | ||
}); | ||
}, [scroll]); | ||
useEffect(function () { | ||
if (!transitionEnd) { | ||
return; | ||
} | ||
}, [updateRect]); | ||
useIsomorphicLayoutEffect(function () { | ||
var globalEventListener = function globalEventListener() { | ||
return updateRect(); | ||
}; | ||
var globalEventConfig = { | ||
capture: true, | ||
passive: true | ||
}; | ||
if (resize) { | ||
window.addEventListener('resize', globalEventListener, globalEventConfig); | ||
return listenTo('transitionend', function () { | ||
return updateRef.current(); | ||
}); | ||
}, [transitionEnd]); | ||
useEffect(function () { | ||
if (!element) { | ||
return; | ||
} | ||
if (scroll) { | ||
window.addEventListener('scroll', globalEventListener, globalEventConfig); | ||
} | ||
if (transitionEnd) { | ||
window.addEventListener('transitionend', globalEventListener, globalEventConfig); | ||
} | ||
var observer = new ResizeObserver(function () { | ||
return updateRef.current(); | ||
}); | ||
observer.observe(element); | ||
return function () { | ||
if (resize) { | ||
window.removeEventListener('resize', globalEventListener, globalEventConfig); | ||
} | ||
if (scroll) { | ||
window.removeEventListener('scroll', globalEventListener, globalEventConfig); | ||
} | ||
if (transitionEnd) { | ||
window.removeEventListener('transitionend', globalEventListener, globalEventConfig); | ||
} | ||
return observer.disconnect(); | ||
}; | ||
}, [resize, scroll, transitionEnd, updateRect]); | ||
useIsomorphicLayoutEffect(updateRect); | ||
return [targetElementCallbackRef, rectRef.current]; | ||
}, [element]); | ||
return [rect, setElement]; | ||
} | ||
@@ -174,0 +151,0 @@ |
{ | ||
"name": "react-use-rect", | ||
"version": "0.1.0-alpha.6", | ||
"description": "React hook that measures target element boundaries", | ||
"version": "1.0.0", | ||
"description": "Hook that measures element boundaries", | ||
"license": "MIT", | ||
@@ -13,3 +13,6 @@ "author": "Vladimir Ivanenko <d521bb85@gmail.com>", | ||
"test:watch": "tsdx test --watch", | ||
"test:cov": "tsdx test --coverage", | ||
"test:e2e-fixture": "npm run build && parcel test/fixture/index.html --out-dir test/fixture/.dist --cache-dir test/fixture/.cache --port 8080", | ||
"build": "npm run clean && tsdx build", | ||
"watch": "tsdx watch", | ||
"prepublishOnly": "npm run build" | ||
@@ -42,32 +45,33 @@ }, | ||
"peerDependencies": { | ||
"react": "^16.13.1" | ||
"react": "^17.0.1" | ||
}, | ||
"dependencies": { | ||
"@juggle/resize-observer": "^3.2.0", | ||
"tslib": "^2.0.1" | ||
"tslib": "^2.0.3" | ||
}, | ||
"devDependencies": { | ||
"@testing-library/react": "^11.0.4", | ||
"@types/react": "^16.9.49", | ||
"@types/react-dom": "^16.9.8", | ||
"@typescript-eslint/eslint-plugin": "^4.1.1", | ||
"@typescript-eslint/parser": "^4.1.1", | ||
"eslint": "^7.9.0", | ||
"eslint-config-prettier": "^6.11.0", | ||
"eslint-config-react-app": "^5.2.1", | ||
"eslint-plugin-import": "^2.22.0", | ||
"eslint-plugin-prettier": "^3.1.4", | ||
"eslint-plugin-react": "^7.20.6", | ||
"eslint-plugin-react-hooks": "^4.1.2", | ||
"husky": "^4.3.0", | ||
"jest": "^26.4.2", | ||
"jest-puppeteer": "^4.4.0", | ||
"lint-staged": "^10.4.0", | ||
"prettier": "^2.1.2", | ||
"puppeteer": "^5.3.0", | ||
"react": "^16.13.1", | ||
"react-dom": "^16.13.1", | ||
"@testing-library/react": "^11.2.2", | ||
"@types/react": "^17.0.0", | ||
"@types/react-dom": "^17.0.0", | ||
"@typescript-eslint/eslint-plugin": "^4.10.0", | ||
"@typescript-eslint/parser": "^4.10.0", | ||
"eslint": "^7.16.0", | ||
"eslint-config-prettier": "^7.1.0", | ||
"eslint-config-react-app": "^6.0.0", | ||
"eslint-plugin-import": "^2.22.1", | ||
"eslint-plugin-prettier": "^3.3.0", | ||
"eslint-plugin-react": "^7.21.5", | ||
"eslint-plugin-react-hooks": "^4.2.0", | ||
"husky": "^4.3.6", | ||
"jest": "^26.6.3", | ||
"lint-staged": "^10.5.3", | ||
"parcel-bundler": "^1.12.4", | ||
"prettier": "^2.2.1", | ||
"react": "^16.14.0", | ||
"react-dom": "^17.0.1", | ||
"rimraf": "^3.0.2", | ||
"tsdx": "^0.13.3" | ||
"styled-components": "^5.2.1", | ||
"styled-normalize": "^8.0.7", | ||
"tsdx": "^0.14.1" | ||
} | ||
} |
181
src/index.ts
@@ -1,179 +0,2 @@ | ||
import { ResizeObserver } from '@juggle/resize-observer'; | ||
import { | ||
useRef, | ||
useState, | ||
useCallback, | ||
useEffect, | ||
useLayoutEffect | ||
} from 'react'; | ||
export interface Rect { | ||
bottom: number; | ||
height: number; | ||
left: number; | ||
right: number; | ||
top: number; | ||
width: number; | ||
x: number; | ||
y: number; | ||
} | ||
const DEFAULT_RECT: Rect = { | ||
bottom: 0, | ||
height: 0, | ||
left: 0, | ||
right: 0, | ||
top: 0, | ||
width: 0, | ||
x: 0, | ||
y: 0 | ||
}; | ||
const RECT_KEYS: (keyof Rect)[] = [ | ||
'bottom', | ||
'height', | ||
'left', | ||
'right', | ||
'top', | ||
'width', | ||
'x', | ||
'y' | ||
]; | ||
function areRectsDifferent(rectA: Rect, rectB: Rect) { | ||
for (const key of RECT_KEYS) { | ||
if (rectA[key] !== rectB[key]) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
const useIsomorphicLayoutEffect = | ||
typeof window === 'undefined' ? useEffect : useLayoutEffect; | ||
function useRerender() { | ||
const [, rerender] = useState({}); | ||
return useCallback(() => rerender({}), []); | ||
} | ||
export interface Options { | ||
resize?: boolean; | ||
scroll?: boolean; | ||
transitionEnd?: boolean; | ||
} | ||
export function useRect({ | ||
resize = true, | ||
scroll = true, | ||
transitionEnd = true | ||
}: Options = {}) { | ||
const resizeObserverRef = useRef<ResizeObserver>(); | ||
const targetElementRef = useRef<Element>(); | ||
const rectRef = useRef(DEFAULT_RECT); | ||
const rerender = useRerender(); | ||
const updateRect = useCallback(() => { | ||
if (!targetElementRef.current) { | ||
if (rectRef.current !== DEFAULT_RECT) { | ||
rectRef.current = DEFAULT_RECT; | ||
rerender(); | ||
} | ||
return; | ||
} | ||
const clientRect = targetElementRef.current.getBoundingClientRect(); | ||
const nextRect = { | ||
bottom: clientRect.bottom, | ||
height: clientRect.height, | ||
left: clientRect.left, | ||
right: clientRect.right, | ||
top: clientRect.top, | ||
width: clientRect.width, | ||
x: clientRect.x, | ||
y: clientRect.y | ||
}; | ||
if (areRectsDifferent(rectRef.current, nextRect)) { | ||
rectRef.current = nextRect; | ||
rerender(); | ||
} | ||
}, [rerender]); | ||
const targetElementCallbackRef = useCallback( | ||
(targetElement: Element | null) => { | ||
targetElementRef.current = targetElement ?? undefined; | ||
if (resizeObserverRef.current) { | ||
resizeObserverRef.current.disconnect(); | ||
resizeObserverRef.current = undefined; | ||
} | ||
if (targetElementRef.current) { | ||
resizeObserverRef.current = new ResizeObserver(updateRect); | ||
resizeObserverRef.current.observe(targetElementRef.current); | ||
} | ||
}, | ||
[updateRect] | ||
); | ||
useIsomorphicLayoutEffect(() => { | ||
const globalEventListener = () => updateRect(); | ||
const globalEventConfig = { | ||
capture: true, | ||
passive: true | ||
}; | ||
if (resize) { | ||
window.addEventListener('resize', globalEventListener, globalEventConfig); | ||
} | ||
if (scroll) { | ||
window.addEventListener('scroll', globalEventListener, globalEventConfig); | ||
} | ||
if (transitionEnd) { | ||
window.addEventListener( | ||
'transitionend', | ||
globalEventListener, | ||
globalEventConfig | ||
); | ||
} | ||
return () => { | ||
if (resize) { | ||
window.removeEventListener( | ||
'resize', | ||
globalEventListener, | ||
globalEventConfig | ||
); | ||
} | ||
if (scroll) { | ||
window.removeEventListener( | ||
'scroll', | ||
globalEventListener, | ||
globalEventConfig | ||
); | ||
} | ||
if (transitionEnd) { | ||
window.removeEventListener( | ||
'transitionend', | ||
globalEventListener, | ||
globalEventConfig | ||
); | ||
} | ||
}; | ||
}, [resize, scroll, transitionEnd, updateRect]); | ||
useIsomorphicLayoutEffect(updateRect); | ||
return [targetElementCallbackRef, rectRef.current] as [ | ||
(targetElement: Element | null) => void, | ||
Rect | ||
]; | ||
} | ||
export * from './types'; | ||
export * from './useRect'; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
28
133.33%1
-50%35983
-15.34%23
4.55%448
-6.08%44
-10.2%1
Infinity%+ Added
- Removed
- Removed
- Removed
Updated