UNPKG

wix-style-react

Version:
165 lines (161 loc) • 6.95 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = useCollapse; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _react = require("react"); var _utils = require("./utils"); var _excluded = ["duration", "easing", "collapseStyles", "expandStyles", "onExpandStart", "onExpandEnd", "onCollapseStart", "onCollapseEnd", "isExpanded", "defaultExpanded", "hasDisabledAnimation"], _excluded2 = ["style", "onTransitionEnd", "refKey"]; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var easeInOut = 'cubic-bezier(0.4, 0, 0.2, 1)'; function useCollapse() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, { duration, easing = easeInOut, collapseStyles = {}, expandStyles = {}, onExpandStart = _utils.noop, onExpandEnd = _utils.noop, onCollapseStart = _utils.noop, onCollapseEnd = _utils.noop, isExpanded: configIsExpanded, defaultExpanded = false, hasDisabledAnimation = false } = _ref, initialConfig = (0, _objectWithoutProperties2.default)(_ref, _excluded); var [isExpanded, setExpanded] = (0, _utils.useControlledState)(configIsExpanded, defaultExpanded); var uniqueId = (0, _utils.useUniqueId)(); var el = (0, _react.useRef)(null); var collapsedHeight = "".concat(initialConfig.collapsedHeight || 0, "px"); var collapsedStyles = { display: collapsedHeight === '0px' ? 'none' : 'block', height: collapsedHeight, overflow: 'hidden' }; var [exitAnimationEnded, setExitAnimationEnded] = (0, _react.useState)(!configIsExpanded); var [styles, setStylesRaw] = (0, _react.useState)(isExpanded ? {} : collapsedStyles); var setStyles = newStyles => { // We rely on reading information from layout // at arbitrary times, so ensure all style changes // happen before we might attempt to read them. setStylesRaw(newStyles); }; var mergeStyles = newStyles => { setStyles(oldStyles => _objectSpread(_objectSpread({}, oldStyles), newStyles)); }; function getTransitionStyles(height) { if (hasDisabledAnimation) { return {}; } var _duration = duration || (0, _utils.getAutoHeightDuration)(height); return { transition: "height ".concat(_duration, "ms ").concat(easing) }; } (0, _utils.useEffectAfterMount)(() => { var animationFrameTimer; var innerAnimationFrameTimer; if (isExpanded) { setExitAnimationEnded(false); animationFrameTimer = window.requestAnimationFrame(() => { onExpandStart(); mergeStyles(_objectSpread(_objectSpread({}, expandStyles), {}, { willChange: 'height', display: 'block', overflow: 'hidden' })); innerAnimationFrameTimer = window.requestAnimationFrame(() => { var height = (0, _utils.getElementHeight)(el); mergeStyles(_objectSpread(_objectSpread({}, getTransitionStyles(height)), {}, { height })); }); }); } else { animationFrameTimer = window.requestAnimationFrame(() => { onCollapseStart(); var height = (0, _utils.getElementHeight)(el); mergeStyles(_objectSpread(_objectSpread(_objectSpread({}, collapseStyles), getTransitionStyles(height)), {}, { willChange: 'height', height })); innerAnimationFrameTimer = window.requestAnimationFrame(() => { mergeStyles({ height: collapsedHeight, overflow: 'hidden' }); }); }); } return () => { window.cancelAnimationFrame(animationFrameTimer); window.cancelAnimationFrame(innerAnimationFrameTimer); }; }, [isExpanded, collapsedHeight]); var handleTransitionEnd = e => { // Sometimes onTransitionEnd is triggered by another transition, // such as a nested collapse panel transitioning. But we only // want to handle this if this component's element is transitioning if (e.target !== el.current || e.propertyName !== 'height') { return; } // The height comparisons below are a final check before // completing the transition // Sometimes this callback is run even though we've already begun // transitioning the other direction // The conditions give us the opportunity to bail out, // which will prevent the collapsed content from flashing on the screen if (isExpanded) { var height = (0, _utils.getElementHeight)(el); // If the height at the end of the transition // matches the height we're animating to, if (height === styles.height) { setStyles({}); } else { // If the heights don't match, this could be due the height // of the content changing mid-transition mergeStyles({ height }); } onExpandEnd(); // If the height we should be animating to matches the collapsed height, // it's safe to apply the collapsed overrides } else if (styles.height === collapsedHeight) { setStyles(collapsedStyles); setExitAnimationEnded(true); onCollapseEnd(); } }; function getCollapseProps() { var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, { style = {}, onTransitionEnd = _utils.noop, refKey = 'ref' } = _ref2, rest = (0, _objectWithoutProperties2.default)(_ref2, _excluded2); var theirRef = rest[refKey]; return _objectSpread(_objectSpread({ id: "react-collapsed-panel-".concat(uniqueId), 'aria-hidden': !isExpanded }, rest), {}, { [refKey]: (0, _utils.mergeRefs)(el, theirRef), onTransitionEnd: (0, _utils.callAll)(handleTransitionEnd, onTransitionEnd), style: _objectSpread(_objectSpread({ boxSizing: 'border-box' }, style), styles) }); } return { getCollapseProps, isExpanded, setExpanded, exitAnimationEnded: process.env.NODE_ENV === 'test' ? !isExpanded : exitAnimationEnded }; } //# sourceMappingURL=useCollapse.js.map