UNPKG

@chayns-components/core

Version:

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

183 lines (180 loc) • 8.48 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _truncation = require("../../types/truncation"); var _debounce = require("../../utils/debounce"); var _truncation2 = require("../../utils/truncation"); var _Truncation = require("./Truncation.styles"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? _react.useLayoutEffect : _react.useEffect; const Truncation = ({ collapsedHeight = 150, clampPosition = _truncation.ClampPosition.Right, isOpen, moreLabel = 'Mehr', lessLabel = 'Weniger', onChange, children }) => { const [internalIsOpen, setInternalIsOpen] = (0, _react.useState)(false); const [showClamp, setShowClamp] = (0, _react.useState)(true); const [newCollapsedHeight, setNewCollapsedHeight] = (0, _react.useState)(collapsedHeight); const [originalHeight, setOriginalHeight] = (0, _react.useState)(0); const [shouldShowCollapsedElement, setShouldShowCollapsedElement] = (0, _react.useState)(true); const [hasSizeChanged, setHasSizeChanged] = (0, _react.useState)(false); const [initialRender, setInitialRender] = (0, _react.useState)(true); const [shouldSkipChangeCheck, setShouldSkipChangeCheck] = (0, _react.useState)(false); const [originalSmallHeight, setOriginalSmallHeight] = (0, _react.useState)(0); const [originalBigHeight, setOriginalBigHeight] = (0, _react.useState)(0); (0, _react.useEffect)(() => { setInitialRender(false); }, []); const parentRef = (0, _react.useRef)(null); const pseudoChildrenRef = (0, _react.useRef)(null); const childrenRef = (0, _react.useRef)(null); const originalChildrenRef = (0, _react.useRef)(null); const hasCollapsed = (0, _react.useRef)(false); const isAnimating = (0, _react.useRef)(false); const hasSizeRecentlyChanged = (0, _react.useRef)(false); const canResetSizeChanged = (0, _react.useRef)(true); (0, _react.useEffect)(() => { if (typeof isOpen === 'boolean') { setInternalIsOpen(isOpen); setShowClamp(!isOpen); } }, [isOpen]); // Changes the state of the truncation const handleClampClick = (0, _react.useCallback)(event => { setInternalIsOpen(current => { if (typeof onChange === 'function') { onChange(event, !current); } return !current; }); }, [onChange]); (0, _react.useEffect)(() => { if (children) { setShouldSkipChangeCheck(true); window.setTimeout(() => { setShouldSkipChangeCheck(false); }, 200); } }, [children]); const handleAnimationEnd = (0, _react.useCallback)(() => { hasCollapsed.current = true; isAnimating.current = false; if (canResetSizeChanged.current) { setHasSizeChanged(false); canResetSizeChanged.current = false; } window.setTimeout(() => { hasSizeRecentlyChanged.current = false; }, 10); setShouldShowCollapsedElement(!internalIsOpen); window.setTimeout(() => { hasCollapsed.current = false; }, 30); }, [internalIsOpen]); (0, _react.useEffect)(() => { if (!pseudoChildrenRef.current) { return; } setOriginalHeight(pseudoChildrenRef.current.offsetHeight); setOriginalBigHeight(pseudoChildrenRef.current.offsetHeight); (0, _truncation2.truncateElement)(pseudoChildrenRef.current, collapsedHeight); setNewCollapsedHeight(pseudoChildrenRef.current.offsetHeight); setOriginalSmallHeight(pseudoChildrenRef.current.offsetHeight); }, [collapsedHeight, pseudoChildrenRef, children]); // Checks if the clamp should be shown (0, _react.useEffect)(() => { if (pseudoChildrenRef.current && (!hasSizeChanged || shouldSkipChangeCheck) && !initialRender) { setShowClamp(originalHeight > newCollapsedHeight); } }, [shouldSkipChangeCheck, collapsedHeight, hasSizeChanged, initialRender, newCollapsedHeight, originalHeight, children]); (0, _react.useEffect)(() => { if (childrenRef.current && pseudoChildrenRef.current && originalChildrenRef.current) { var _parentRef$current; while (childrenRef.current.firstChild) { childrenRef.current.removeChild(childrenRef.current.firstChild); } childrenRef.current.appendChild(shouldShowCollapsedElement && !internalIsOpen ? pseudoChildrenRef.current : originalChildrenRef.current); (_parentRef$current = parentRef.current) === null || _parentRef$current === void 0 || _parentRef$current.appendChild(shouldShowCollapsedElement && !internalIsOpen ? originalChildrenRef.current : pseudoChildrenRef.current); childrenRef.current.children[0].style.visibility = 'visible'; } }, [children, internalIsOpen, shouldShowCollapsedElement]); useIsomorphicLayoutEffect(() => { if (originalChildrenRef.current) { const resizeObserver = new ResizeObserver(entries => { if (entries && entries[0]) { const observedHeight = entries[0].contentRect.height; setOriginalHeight(observedHeight < originalBigHeight ? originalBigHeight : observedHeight); if (!hasCollapsed.current && !isAnimating.current && !hasSizeRecentlyChanged.current) { void (0, _debounce.debounce)(() => { canResetSizeChanged.current = true; }, 250)(); setHasSizeChanged(true); hasSizeRecentlyChanged.current = true; } } }); resizeObserver.observe(originalChildrenRef.current); return () => { resizeObserver.disconnect(); }; } return () => {}; }, [originalBigHeight, children]); useIsomorphicLayoutEffect(() => { if (pseudoChildrenRef.current) { const resizeObserver = new ResizeObserver(entries => { if (entries && entries[0]) { const observedHeight = entries[0].contentRect.height; setNewCollapsedHeight(observedHeight < originalSmallHeight ? originalSmallHeight : observedHeight); if (!hasCollapsed.current && !isAnimating.current && !hasSizeRecentlyChanged.current) { void (0, _debounce.debounce)(() => { canResetSizeChanged.current = true; }, 250)(); setHasSizeChanged(true); hasSizeRecentlyChanged.current = true; } } }); resizeObserver.observe(pseudoChildrenRef.current); return () => { resizeObserver.disconnect(); }; } return () => {}; }, [originalSmallHeight, children]); return (0, _react.useMemo)(() => /*#__PURE__*/_react.default.createElement(_Truncation.StyledTruncation, { className: "beta-chayns-truncation", ref: parentRef }, /*#__PURE__*/_react.default.createElement(_Truncation.StyledTruncationPseudoContent, { ref: pseudoChildrenRef }, children), /*#__PURE__*/_react.default.createElement(_Truncation.StyledTruncationPseudoContent, { ref: originalChildrenRef }, children), /*#__PURE__*/_react.default.createElement(_Truncation.StyledMotionTruncationContent, { animate: { height: internalIsOpen ? originalHeight : newCollapsedHeight }, initial: false, transition: { type: 'tween', duration: hasSizeChanged ? 0 : 0.2 }, onAnimationComplete: handleAnimationEnd, onAnimationStart: () => { isAnimating.current = true; }, ref: childrenRef }), showClamp && /*#__PURE__*/_react.default.createElement(_Truncation.StyledTruncationClampWrapper, { $position: clampPosition }, /*#__PURE__*/_react.default.createElement(_Truncation.StyledTruncationClamp, { onClick: handleClampClick }, internalIsOpen ? lessLabel : moreLabel))), [children, clampPosition, handleAnimationEnd, handleClampClick, hasSizeChanged, internalIsOpen, lessLabel, moreLabel, newCollapsedHeight, originalHeight, showClamp]); }; var _default = exports.default = Truncation; //# sourceMappingURL=Truncation.js.map