@chayns-components/core
Version:
A set of beautiful React components for developing your own applications with chayns.
107 lines (105 loc) • 3.01 kB
JavaScript
import useResizeObserver from '@react-hook/resize-observer';
import React, { cloneElement, useEffect, useLayoutEffect, useRef, useState } from 'react';
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
class ResizeObserverPolyFill {
// eslint-disable-next-line class-methods-use-this
observe = () => {};
// eslint-disable-next-line class-methods-use-this
unobserve = () => {};
}
const options = typeof window === 'undefined' ? {
polyfill: ResizeObserverPolyFill
} : undefined;
export const useElementSize = function (ref) {
let {
shouldUseChildElement = false
} = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
const [size, setSize] = useState();
const element = (shouldUseChildElement ? ref.current?.firstElementChild : ref.current) ?? null;
useIsomorphicLayoutEffect(() => {
if (element) {
setSize(element.getBoundingClientRect());
} else {
setSize(undefined);
}
}, [element]);
// TODO: Replace with ssr-compatible implementation
useResizeObserver(element, entry => setSize(entry.contentRect), options);
return size;
};
export const useMeasuredClone = _ref => {
let {
content
} = _ref;
const ref = useRef(null);
const [size, setSize] = useState({
width: 0,
height: 0
});
const preventEvents = {
onClick: e => e.stopPropagation(),
onMouseDown: e => e.stopPropagation(),
onMouseUp: e => e.stopPropagation(),
onKeyDown: e => e.stopPropagation(),
onKeyUp: e => e.stopPropagation(),
onFocus: e => e.stopPropagation(),
onBlur: e => e.stopPropagation()
};
const clonedElement = /*#__PURE__*/cloneElement(content, {
...preventEvents,
'data-measured-clone': true
});
useEffect(() => {
const measure = () => {
if (!ref.current) return;
const {
offsetWidth: width,
offsetHeight: height
} = ref.current;
setSize({
width,
height
});
};
measure();
const observer = new ResizeObserver(measure);
if (ref.current) observer.observe(ref.current);
return () => observer.disconnect();
}, []);
const measuredElement = /*#__PURE__*/React.createElement("div", {
"data-measured-clone": "true",
ref: ref,
style: {
position: 'absolute',
opacity: 0,
pointerEvents: 'none',
zIndex: -1,
height: 'auto',
width: 'auto',
visibility: 'hidden'
}
}, clonedElement);
return {
measuredElement,
width: size.width,
height: size.height
};
};
export const useIsMeasuredClone = () => {
const ref = useRef(null);
const [isClone, setIsClone] = useState(false);
useEffect(() => {
if (!ref.current) return;
let el = ref.current;
while (el) {
if (el.hasAttribute('data-measured-clone')) {
setIsClone(true);
return;
}
el = el.parentElement;
}
setIsClone(false);
}, []);
return [isClone, ref];
};
//# sourceMappingURL=element.js.map