UNPKG

@material-ui/core

Version:

React components that implement Google's Material Design.

286 lines (232 loc) 8.55 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.setTranslateValue = setTranslateValue; exports.default = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _reactDom = _interopRequireDefault(require("react-dom")); var _debounce = _interopRequireDefault(require("../utils/debounce")); var _reactTransitionGroup = require("react-transition-group"); var _utils = require("@material-ui/utils"); var _reactHelpers = require("../utils/reactHelpers"); var _useTheme = _interopRequireDefault(require("../styles/useTheme")); var _transitions = require("../styles/transitions"); var _utils2 = require("../transitions/utils"); // Translate the node so he can't be seen on the screen. // Later, we gonna translate back the node to his original location // with `none`.` function getTranslateValue(direction, node) { var rect = node.getBoundingClientRect(); var transform; if (node.fakeTransform) { transform = node.fakeTransform; } else { var computedStyle = window.getComputedStyle(node); transform = computedStyle.getPropertyValue('-webkit-transform') || computedStyle.getPropertyValue('transform'); } var offsetX = 0; var offsetY = 0; if (transform && transform !== 'none' && typeof transform === 'string') { var transformValues = transform.split('(')[1].split(')')[0].split(','); offsetX = parseInt(transformValues[4], 10); offsetY = parseInt(transformValues[5], 10); } if (direction === 'left') { return "translateX(".concat(window.innerWidth, "px) translateX(-").concat(rect.left - offsetX, "px)"); } if (direction === 'right') { return "translateX(-".concat(rect.left + rect.width - offsetX, "px)"); } if (direction === 'up') { return "translateY(".concat(window.innerHeight, "px) translateY(-").concat(rect.top - offsetY, "px)"); } // direction === 'down' return "translateY(-".concat(rect.top + rect.height - offsetY, "px)"); } function setTranslateValue(direction, node) { var transform = getTranslateValue(direction, node); if (transform) { node.style.webkitTransform = transform; node.style.transform = transform; } } var defaultTimeout = { enter: _transitions.duration.enteringScreen, exit: _transitions.duration.leavingScreen }; /** * The Slide transition is used by the [Drawer](/components/drawers/) component. * It uses [react-transition-group](https://github.com/reactjs/react-transition-group) internally. */ var Slide = _react.default.forwardRef(function Slide(props, ref) { var children = props.children, _props$direction = props.direction, direction = _props$direction === void 0 ? 'down' : _props$direction, inProp = props.in, onEnter = props.onEnter, onEntering = props.onEntering, onExit = props.onExit, onExited = props.onExited, style = props.style, _props$timeout = props.timeout, timeout = _props$timeout === void 0 ? defaultTimeout : _props$timeout, other = (0, _objectWithoutProperties2.default)(props, ["children", "direction", "in", "onEnter", "onEntering", "onExit", "onExited", "style", "timeout"]); var theme = (0, _useTheme.default)(); var childrenRef = _react.default.useRef(null); /** * used in cloneElement(children, { ref: handleRef }) */ var handleOwnRef = _react.default.useCallback(function (instance) { // #StrictMode ready childrenRef.current = _reactDom.default.findDOMNode(instance); }, []); var handleRefIntermediary = (0, _reactHelpers.useForkRef)(children.ref, handleOwnRef); var handleRef = (0, _reactHelpers.useForkRef)(handleRefIntermediary, ref); var handleEnter = function handleEnter() { var node = childrenRef.current; setTranslateValue(direction, node); (0, _utils2.reflow)(node); if (onEnter) { onEnter(node); } }; var handleEntering = function handleEntering() { var node = childrenRef.current; var transitionProps = (0, _utils2.getTransitionProps)({ timeout: timeout, style: style }, { mode: 'enter' }); node.style.webkitTransition = theme.transitions.create('-webkit-transform', (0, _extends2.default)({}, transitionProps, { easing: theme.transitions.easing.easeOut })); node.style.transition = theme.transitions.create('transform', (0, _extends2.default)({}, transitionProps, { easing: theme.transitions.easing.easeOut })); node.style.webkitTransform = 'none'; node.style.transform = 'none'; if (onEntering) { onEntering(node); } }; var handleExit = function handleExit() { var node = childrenRef.current; var transitionProps = (0, _utils2.getTransitionProps)({ timeout: timeout, style: style }, { mode: 'exit' }); node.style.webkitTransition = theme.transitions.create('-webkit-transform', (0, _extends2.default)({}, transitionProps, { easing: theme.transitions.easing.sharp })); node.style.transition = theme.transitions.create('transform', (0, _extends2.default)({}, transitionProps, { easing: theme.transitions.easing.sharp })); setTranslateValue(direction, node); if (onExit) { onExit(node); } }; var handleExited = function handleExited() { var node = childrenRef.current; // No need for transitions when the component is hidden node.style.webkitTransition = ''; node.style.transition = ''; if (onExited) { onExited(node); } }; var updatePosition = _react.default.useCallback(function () { if (childrenRef.current) { setTranslateValue(direction, childrenRef.current); } }, [direction]); _react.default.useEffect(function () { // Skip configuration where the position is screen size invariant. if (!inProp && direction !== 'down' && direction !== 'right') { var handleResize = (0, _debounce.default)(function () { if (childrenRef.current) { setTranslateValue(direction, childrenRef.current); } }); window.addEventListener('resize', handleResize); return function () { handleResize.clear(); window.removeEventListener('resize', handleResize); }; } return undefined; }, [direction, inProp]); _react.default.useEffect(function () { if (!inProp) { // We need to update the position of the drawer when the direction change and // when it's hidden. updatePosition(); } }, [inProp, updatePosition]); return _react.default.createElement(_reactTransitionGroup.Transition, (0, _extends2.default)({ onEnter: handleEnter, onEntering: handleEntering, onExit: handleExit, onExited: handleExited, appear: true, in: inProp, timeout: timeout }, other), function (state, childProps) { return _react.default.cloneElement(children, (0, _extends2.default)({ ref: handleRef, style: (0, _extends2.default)({ visibility: state === 'exited' && !inProp ? 'hidden' : undefined }, style, {}, children.props.style) }, childProps)); }); }); process.env.NODE_ENV !== "production" ? Slide.propTypes = { /** * A single child content element. */ children: _utils.elementAcceptingRef, /** * Direction the child node will enter from. */ direction: _propTypes.default.oneOf(['left', 'right', 'up', 'down']), /** * If `true`, show the component; triggers the enter or exit animation. */ in: _propTypes.default.bool, /** * @ignore */ onEnter: _propTypes.default.func, /** * @ignore */ onEntering: _propTypes.default.func, /** * @ignore */ onExit: _propTypes.default.func, /** * @ignore */ onExited: _propTypes.default.func, /** * @ignore */ style: _propTypes.default.object, /** * The duration for the transition, in milliseconds. * You may specify a single timeout for all transitions, or individually with an object. */ timeout: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.shape({ enter: _propTypes.default.number, exit: _propTypes.default.number })]) } : void 0; var _default = Slide; exports.default = _default;