@chakra-xui/transition
Version:
Common transition components for Chakra xui
137 lines (121 loc) • 4.11 kB
JavaScript
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import { useUpdateEffect } from "@chakra-xui/hooks";
import { cx, warn, __DEV__ } from "@chakra-xui/utils";
import { AnimatePresence, motion } from "framer-motion";
import * as React from "react";
import { EASINGS } from "./__utils";
var hasHeightValue = value => value != null && parseInt(value.toString(), 10) > 0;
var variants = {
exit: props => _extends({}, props.animateOpacity && {
opacity: hasHeightValue(props.startingHeight) ? 1 : 0
}, {
height: props.startingHeight,
transition: {
height: {
duration: 0.2,
ease: EASINGS.ease
},
opacity: {
duration: 0.3,
ease: EASINGS.ease
}
}
}),
enter: props => _extends({}, props.animateOpacity && {
opacity: 1
}, {
height: props.endingHeight,
transition: {
height: {
duration: 0.3,
ease: EASINGS.ease
},
opacity: {
duration: 0.4,
ease: EASINGS.ease
}
}
})
};
export var Collapse = /*#__PURE__*/React.forwardRef((props, ref) => {
var {
in: isOpen,
unmountOnExit,
animateOpacity = true,
startingHeight = 0,
endingHeight = "auto",
style,
className,
onAnimationComplete: _onAnimationComplete
} = props,
rest = _objectWithoutPropertiesLoose(props, ["in", "unmountOnExit", "animateOpacity", "startingHeight", "endingHeight", "style", "className", "onAnimationComplete"]);
var fromZeroHeight = startingHeight === 0;
var [open, setOpen] = React.useState(!!isOpen);
var getInitialHidden = () => {
// If it is open by default, no need to apply `aria-hidden`
if (isOpen) return false; // If startingHeight > 0, then content is partially visible
if (hasHeightValue(startingHeight)) return false; // Else, the content is hidden
return true;
};
var [display, setDisplay] = React.useState(() => {
if (!fromZeroHeight) return "block";
var hidden = getInitialHidden();
return hidden ? "none" : "block";
});
useUpdateEffect(() => {
setDisplay("block");
setOpen(!!isOpen);
}, [isOpen]);
/**
* Warn 🚨: `startingHeight` and `unmountOnExit` are mutually exclusive
*
* If you specify a starting height, the collapsed needs to be mounted
* for the height to take effect.
*/
if (startingHeight > 0 && unmountOnExit) {
warn("startingHeight and unmountOnExit are mutually exclusive. You can't use them together");
}
var custom = {
startingHeight,
endingHeight,
animateOpacity
};
var ownProps = _extends({
ref,
onAnimationComplete: () => {
if (!open && fromZeroHeight) {
setDisplay("none");
}
_onAnimationComplete == null ? void 0 : _onAnimationComplete();
},
className: cx("chakra-collapse", className)
}, rest, {
variants,
style: _extends({
overflow: "hidden"
}, style),
custom
});
if (unmountOnExit) {
return /*#__PURE__*/React.createElement(AnimatePresence, {
initial: false,
custom: custom
}, isOpen && /*#__PURE__*/React.createElement(motion.div, _extends({}, ownProps, {
initial: "exit",
animate: "enter",
exit: "exit"
})));
}
return /*#__PURE__*/React.createElement(motion.div, _extends({}, ownProps, {
style: _extends({}, ownProps.style, {
display
}),
initial: false,
animate: open ? "enter" : "exit"
}));
});
if (__DEV__) {
Collapse.displayName = "Collapse";
}
//# sourceMappingURL=collapse.js.map