polaris-glints
Version:
Glints forked polaris react
120 lines (103 loc) • 3.78 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var css = require('../../utilities/css.js');
var Collapsible$1 = require('./Collapsible.scss.js');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
function Collapsible({
id,
expandOnPrint,
open,
transition = true,
preventMeasuringOnChildrenUpdate: _preventMeasuringOnChildrenUpdate,
children,
onAnimationEnd
}) {
const [height, setHeight] = React.useState(0);
const [isOpen, setIsOpen] = React.useState(open);
const [animationState, setAnimationState] = React.useState('idle');
const collapsibleContainer = React.useRef(null);
const isFullyOpen = animationState === 'idle' && open && isOpen;
const isFullyClosed = animationState === 'idle' && !open && !isOpen;
const content = expandOnPrint || !isFullyClosed ? children : null;
const wrapperClassName = css.classNames(Collapsible$1["default"].Collapsible, isFullyClosed && Collapsible$1["default"].isFullyClosed, expandOnPrint && Collapsible$1["default"].expandOnPrint);
const transitionDisabled = isTransitionDisabled(transition);
const transitionStyles = typeof transition === 'object' && {
transitionDuration: transition.duration,
transitionTimingFunction: transition.timingFunction
};
const collapsibleStyles = { ...transitionStyles,
...{
maxHeight: isFullyOpen ? 'none' : `${height}px`,
overflow: isFullyOpen ? 'visible' : 'hidden'
}
};
const handleCompleteAnimation = React.useCallback(({
target
}) => {
if (target === collapsibleContainer.current) {
setAnimationState('idle');
setIsOpen(open);
onAnimationEnd && onAnimationEnd();
}
}, [onAnimationEnd, open]);
const startAnimation = React.useCallback(() => {
if (transitionDisabled) {
setIsOpen(open);
setAnimationState('idle');
if (open && collapsibleContainer.current) {
setHeight(collapsibleContainer.current.scrollHeight);
} else {
setHeight(0);
}
} else {
setAnimationState('measuring');
}
}, [open, transitionDisabled]);
React.useEffect(() => {
if (open !== isOpen) {
startAnimation();
} // startAnimation should only be fired if the open state changes.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [open, isOpen]);
React.useEffect(() => {
if (!open || !collapsibleContainer.current) return; // If collapsible defaults to open, set an initial height
setHeight(collapsibleContainer.current.scrollHeight); // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
React.useEffect(() => {
if (!collapsibleContainer.current) return;
switch (animationState) {
case 'idle':
break;
case 'measuring':
setHeight(collapsibleContainer.current.scrollHeight);
setAnimationState('animating');
break;
case 'animating':
setHeight(open ? collapsibleContainer.current.scrollHeight : 0);
}
}, [animationState, open, isOpen]);
return /*#__PURE__*/React__default["default"].createElement("div", {
id: id,
style: collapsibleStyles,
ref: collapsibleContainer,
className: wrapperClassName,
onTransitionEnd: handleCompleteAnimation,
"aria-hidden": !open
}, content);
}
const zeroDurationRegex = /^0(ms|s)$/;
function isTransitionDisabled(transitionProp) {
if (typeof transitionProp === 'boolean') {
return !transitionProp;
}
const {
duration
} = transitionProp;
if (duration && zeroDurationRegex.test(duration.trim())) {
return true;
}
return false;
}
exports.Collapsible = Collapsible;