UNPKG

@chayns-components/core

Version:

A set of beautiful React components for developing your own applications with chayns.

107 lines (105 loc) 3.01 kB
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