@commercetools-uikit/collapsible-motion
Version:
A component which allows building collapsible elements with an arbitrary height.
175 lines (165 loc) • 9.36 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var _Object$keys = require('@babel/runtime-corejs3/core-js-stable/object/keys');
var _Object$getOwnPropertySymbols = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols');
var _filterInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/filter');
var _Object$getOwnPropertyDescriptor = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor');
var _forEachInstanceProperty = require('@babel/runtime-corejs3/core-js-stable/instance/for-each');
var _Object$getOwnPropertyDescriptors = require('@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors');
var _Object$defineProperties = require('@babel/runtime-corejs3/core-js-stable/object/define-properties');
var _Object$defineProperty = require('@babel/runtime-corejs3/core-js-stable/object/define-property');
var _objectDestructuringEmpty = require('@babel/runtime-corejs3/helpers/objectDestructuringEmpty');
var _extends = require('@babel/runtime-corejs3/helpers/extends');
var _objectWithoutProperties = require('@babel/runtime-corejs3/helpers/objectWithoutProperties');
var _defineProperty = require('@babel/runtime-corejs3/helpers/defineProperty');
var _slicedToArray = require('@babel/runtime-corejs3/helpers/slicedToArray');
var react$1 = require('react');
var utils = require('@commercetools-uikit/utils');
var react = require('@emotion/react');
var isNil = require('lodash/isNil');
var hooks = require('@commercetools-uikit/hooks');
var jsxRuntime = require('@emotion/react/jsx-runtime');
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
var _Object$keys__default = /*#__PURE__*/_interopDefault(_Object$keys);
var _Object$getOwnPropertySymbols__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertySymbols);
var _filterInstanceProperty__default = /*#__PURE__*/_interopDefault(_filterInstanceProperty);
var _Object$getOwnPropertyDescriptor__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptor);
var _forEachInstanceProperty__default = /*#__PURE__*/_interopDefault(_forEachInstanceProperty);
var _Object$getOwnPropertyDescriptors__default = /*#__PURE__*/_interopDefault(_Object$getOwnPropertyDescriptors);
var _Object$defineProperties__default = /*#__PURE__*/_interopDefault(_Object$defineProperties);
var _Object$defineProperty__default = /*#__PURE__*/_interopDefault(_Object$defineProperty);
var isNil__default = /*#__PURE__*/_interopDefault(isNil);
const _excluded = ["minHeight"];
function ownKeys(e, r) { var t = _Object$keys__default["default"](e); if (_Object$getOwnPropertySymbols__default["default"]) { var o = _Object$getOwnPropertySymbols__default["default"](e); r && (o = _filterInstanceProperty__default["default"](o).call(o, function (r) { return _Object$getOwnPropertyDescriptor__default["default"](e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context, _context2; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty__default["default"](_context = ownKeys(Object(t), !0)).call(_context, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors__default["default"] ? _Object$defineProperties__default["default"](e, _Object$getOwnPropertyDescriptors__default["default"](t)) : _forEachInstanceProperty__default["default"](_context2 = ownKeys(Object(t))).call(_context2, function (r) { _Object$defineProperty__default["default"](e, r, _Object$getOwnPropertyDescriptor__default["default"](t, r)); }); } return e; }
const getMinHeight = minHeight => minHeight !== 0 ? `${minHeight}px` : minHeight;
const getVisibility = height => height === 0 ? 'hidden' : 'visible';
const createOpeningAnimation = function (height) {
let minHeight = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
return react.keyframes`
0% { height: ${getMinHeight(minHeight)}; overflow: hidden; visibility: ${getVisibility(minHeight)}; }
99% { height: ${height}px; overflow: hidden; }
100% { height: auto; overflow: visible; }
`;
};
const createClosingAnimation = function (height) {
let minHeight = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
return react.keyframes`
from { height: ${height}px; }
to { height: ${getMinHeight(minHeight)}; overflow: hidden; visibility: ${getVisibility(minHeight)}; }
`;
};
const useToggleAnimation = function (isOpen, toggle) {
let minHeight = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
const nodeRef = react$1.useRef(null);
const animationRef = react$1.useRef(null);
const prevIsOpen = hooks.usePrevious(isOpen);
react$1.useEffect(() => {
process.env.NODE_ENV !== "production" ? utils.warning(nodeRef.current, 'You need to call `registerContentNode` in order to use this component') : void 0;
},
// to match the componentDidMount behaviour
[nodeRef]);
const handleToggle = react$1.useCallback(() => {
process.env.NODE_ENV !== "production" ? utils.warning(nodeRef.current, 'You need to call `registerContentNode` in order to use this component') : void 0;
// set panel height to the height of the content,
// so we can animate between the height and 0
toggle && toggle();
}, [nodeRef, toggle]);
const containerStyles = isOpen ? {
height: 'auto'
} : {
height: getMinHeight(minHeight),
overflow: 'hidden',
visibility: getVisibility(minHeight)
};
// if state has changed
if (typeof prevIsOpen !== 'undefined' && prevIsOpen !== isOpen && nodeRef.current) {
animationRef.current = isOpen ? createOpeningAnimation(nodeRef.current.clientHeight, minHeight) : createClosingAnimation(nodeRef.current.clientHeight, minHeight);
}
return [animationRef.current, containerStyles, handleToggle, nodeRef];
};
const ControlledCollapsibleMotion = props => {
const _useToggleAnimation = useToggleAnimation(!props.isClosed, props.onToggle, props.minHeight),
_useToggleAnimation2 = _slicedToArray(_useToggleAnimation, 4),
animation = _useToggleAnimation2[0],
containerStyles = _useToggleAnimation2[1],
animationToggle = _useToggleAnimation2[2],
registerContentNode = _useToggleAnimation2[3];
return jsxRuntime.jsx(react.ClassNames, {
children: _ref => {
let css = _ref.css;
let animationStyle = {};
if (animation) {
// By calling `css`, emotion injects the required CSS into the document head.
// eslint-disable-next-line no-unused-expressions
css`
animation: ${animation} 200ms
forwards;
`;
animationStyle = {
animation: `${animation.name} 200ms forwards`
};
}
return props.children({
isOpen: !props.isClosed,
containerStyles: _objectSpread(_objectSpread({}, containerStyles), animationStyle),
toggle: animationToggle,
registerContentNode: registerContentNode
});
}
});
};
ControlledCollapsibleMotion.displayName = 'ControlledCollapsibleMotion';
const UncontrolledCollapsibleMotion = _ref2 => {
let _ref2$minHeight = _ref2.minHeight,
minHeight = _ref2$minHeight === void 0 ? 0 : _ref2$minHeight,
props = _objectWithoutProperties(_ref2, _excluded);
const _useToggleState = hooks.useToggleState(!props.isDefaultClosed),
_useToggleState2 = _slicedToArray(_useToggleState, 2),
isOpen = _useToggleState2[0],
toggle = _useToggleState2[1];
const _useToggleAnimation3 = useToggleAnimation(isOpen, toggle, minHeight),
_useToggleAnimation4 = _slicedToArray(_useToggleAnimation3, 4),
animation = _useToggleAnimation4[0],
containerStyles = _useToggleAnimation4[1],
animationToggle = _useToggleAnimation4[2],
registerContentNode = _useToggleAnimation4[3];
return jsxRuntime.jsx(react.ClassNames, {
children: _ref3 => {
let css = _ref3.css;
let animationStyle = {};
if (animation) {
// By calling `css`, emotion injects the required CSS into the document head.
// eslint-disable-next-line no-unused-expressions
css`
animation: ${animation} 200ms
forwards;
`;
animationStyle = {
animation: `${animation.name} 200ms forwards`
};
}
return props.children({
isOpen,
containerStyles: _objectSpread(_objectSpread({}, containerStyles), animationStyle),
toggle: animationToggle,
registerContentNode: registerContentNode
});
}
});
};
UncontrolledCollapsibleMotion.displayName = 'UncontrolledCollapsibleMotion';
const CollapsibleMotion = _ref4 => {
let props = _extends({}, (_objectDestructuringEmpty(_ref4), _ref4));
const isControlledComponent = !isNil__default["default"](props.isClosed);
if (isControlledComponent) {
return jsxRuntime.jsx(ControlledCollapsibleMotion, _objectSpread({}, props));
}
return jsxRuntime.jsx(UncontrolledCollapsibleMotion, _objectSpread({}, props));
};
CollapsibleMotion.displayName = 'CollapsibleMotion';
var CollapsibleMotion$1 = CollapsibleMotion;
// NOTE: This string will be replaced on build time with the package version.
var version = "20.2.3";
exports["default"] = CollapsibleMotion$1;
exports.version = version;