text: "use strict";
  
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  
  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.default = exports.TouchRippleRipple = exports.TouchRippleRoot = exports.DELAY_RIPPLE = void 0;
  
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
  
  var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
  
  var React = _interopRequireWildcard(require("react"));
  
  var _propTypes = _interopRequireDefault(require("prop-types"));
  
  var _reactTransitionGroup = require("react-transition-group");
  
  var _clsx = _interopRequireDefault(require("clsx"));
  
  var _system = require("@material-ui/system");
  
  var _styled = _interopRequireDefault(require("../styles/styled"));
  
  var _useThemeProps = _interopRequireDefault(require("../styles/useThemeProps"));
  
  var _Ripple = _interopRequireDefault(require("./Ripple"));
  
  var _touchRippleClasses = _interopRequireDefault(require("./touchRippleClasses"));
  
  var _jsxRuntime = require("react/jsx-runtime");
  
  const _excluded = ["center", "classes", "className"];
  
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
  
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
  
  const DURATION = 550;
  const DELAY_RIPPLE = 80;
  exports.DELAY_RIPPLE = DELAY_RIPPLE;
  const enterKeyframe = (0, _system.keyframes)`
    0% {
      transform: scale(0);
      opacity: 0.1;
    }
  
    100% {
      transform: scale(1);
      opacity: 0.3;
    }
  `;
  const exitKeyframe = (0, _system.keyframes)`
    0% {
      opacity: 1;
    }
  
    100% {
      opacity: 0;
    }
  `;
  const pulsateKeyframe = (0, _system.keyframes)`
    0% {
      transform: scale(1);
    }
  
    50% {
      transform: scale(0.92);
    }
  
    100% {
      transform: scale(1);
    }
  `;
  const TouchRippleRoot = (0, _styled.default)('span', {
    name: 'MuiTouchRipple',
    slot: 'Root',
    skipSx: true
  })({
    overflow: 'hidden',
    pointerEvents: 'none',
    position: 'absolute',
    zIndex: 0,
    top: 0,
    right: 0,
    bottom: 0,
    left: 0,
    borderRadius: 'inherit'
  }); // This `styled()` function invokes keyframes. `styled-components` only supports keyframes
  // in string templates. Do not convert these styles in JS object as it will break.
  
  exports.TouchRippleRoot = TouchRippleRoot;
  const TouchRippleRipple = (0, _styled.default)(_Ripple.default, {
    name: 'MuiTouchRipple',
    slot: 'Ripple'
  })`
    opacity: 0;
    position: absolute;
  
    &.${_touchRippleClasses.default.rippleVisible} {
      opacity: 0.3;
      transform: scale(1);
      animation-name: ${enterKeyframe};
      animation-duration: ${DURATION}ms;
      animation-timing-function: ${({
    theme
  }) => theme.transitions.easing.easeInOut};
    }
  
    &.${_touchRippleClasses.default.ripplePulsate} {
      animation-duration: ${({
    theme
  }) => theme.transitions.duration.shorter}ms;
    }
  
    & .${_touchRippleClasses.default.child} {
      opacity: 1;
      display: block;
      width: 100%;
      height: 100%;
      border-radius: 50%;
      background-color: currentColor;
    }
  
    & .${_touchRippleClasses.default.childLeaving} {
      opacity: 0;
      animation-name: ${exitKeyframe};
      animation-duration: ${DURATION}ms;
      animation-timing-function: ${({
    theme
  }) => theme.transitions.easing.easeInOut};
    }
  
    & .${_touchRippleClasses.default.childPulsate} {
      position: absolute;
      left: 0;
      top: 0;
      animation-name: ${pulsateKeyframe};
      animation-duration: 2500ms;
      animation-timing-function: ${({
    theme
  }) => theme.transitions.easing.easeInOut};
      animation-iteration-count: infinite;
      animation-delay: 200ms;
    }
  `;
  /**
   * @ignore - internal component.
   *
   * TODO v5: Make private
   */
  
  exports.TouchRippleRipple = TouchRippleRipple;
  const TouchRipple = /*#__PURE__*/React.forwardRef(function TouchRipple(inProps, ref) {
    const props = (0, _useThemeProps.default)({
      props: inProps,
      name: 'MuiTouchRipple'
    });
    const {
      center: centerProp = false,
      classes = {},
      className
    } = props,
          other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
    const [ripples, setRipples] = React.useState([]);
    const nextKey = React.useRef(0);
    const rippleCallback = React.useRef(null);
    React.useEffect(() => {
      if (rippleCallback.current) {
        rippleCallback.current();
        rippleCallback.current = null;
      }
    }, [ripples]); // Used to filter out mouse emulated events on mobile.
  
    const ignoringMouseDown = React.useRef(false); // We use a timer in order to only show the ripples for touch "click" like events.
    // We don't want to display the ripple for touch scroll events.
  
    const startTimer = React.useRef(null); // This is the hook called once the previous timeout is ready.
  
    const startTimerCommit = React.useRef(null);
    const container = React.useRef(null);
    React.useEffect(() => {
      return () => {
        clearTimeout(startTimer.current);
      };
    }, []);
    const startCommit = React.useCallback(params => {
      const {
        pulsate,
        rippleX,
        rippleY,
        rippleSize,
        cb
      } = params;
      setRipples(oldRipples => [...oldRipples, /*#__PURE__*/(0, _jsxRuntime.jsx)(TouchRippleRipple, {
        classes: {
          ripple: (0, _clsx.default)(classes.ripple, _touchRippleClasses.default.ripple),
          rippleVisible: (0, _clsx.default)(classes.rippleVisible, _touchRippleClasses.default.rippleVisible),
          ripplePulsate: (0, _clsx.default)(classes.ripplePulsate, _touchRippleClasses.default.ripplePulsate),
          child: (0, _clsx.default)(classes.child, _touchRippleClasses.default.child),
          childLeaving: (0, _clsx.default)(classes.childLeaving, _touchRippleClasses.default.childLeaving),
          childPulsate: (0, _clsx.default)(classes.childPulsate, _touchRippleClasses.default.childPulsate)
        },
        timeout: DURATION,
        pulsate: pulsate,
        rippleX: rippleX,
        rippleY: rippleY,
        rippleSize: rippleSize
      }, nextKey.current)]);
      nextKey.current += 1;
      rippleCallback.current = cb;
    }, [classes]);
    const start = React.useCallback((event = {}, options = {}, cb) => {
      const {
        pulsate = false,
        center = centerProp || options.pulsate,
        fakeElement = false // For test purposes
  
      } = options;
  
      if (event.type === 'mousedown' && ignoringMouseDown.current) {
        ignoringMouseDown.current = false;
        return;
      }
  
      if (event.type === 'touchstart') {
        ignoringMouseDown.current = true;
      }
  
      const element = fakeElement ? null : container.current;
      const rect = element ? element.getBoundingClientRect() : {
        width: 0,
        height: 0,
        left: 0,
        top: 0
      }; // Get the size of the ripple
  
      let rippleX;
      let rippleY;
      let rippleSize;
  
      if (center || event.clientX === 0 && event.clientY === 0 || !event.clientX && !event.touches) {
        rippleX = Math.round(rect.width / 2);
        rippleY = Math.round(rect.height / 2);
      } else {
        const {
          clientX,
          clientY
        } = event.touches ? event.touches[0] : event;
        rippleX = Math.round(clientX - rect.left);
        rippleY = Math.round(clientY - rect.top);
      }
  
      if (center) {
        rippleSize = Math.sqrt((2 * rect.width ** 2 + rect.height ** 2) / 3); // For some reason the animation is broken on Mobile Chrome if the size if even.
  
        if (rippleSize % 2 === 0) {
          rippleSize += 1;
        }
      } else {
        const sizeX = Math.max(Math.abs((element ? element.clientWidth : 0) - rippleX), rippleX) * 2 + 2;
        const sizeY = Math.max(Math.abs((element ? element.clientHeight : 0) - rippleY), rippleY) * 2 + 2;
        rippleSize = Math.sqrt(sizeX ** 2 + sizeY ** 2);
      } // Touche devices
  
  
      if (event.touches) {
        // check that this isn't another touchstart due to multitouch
        // otherwise we will only clear a single timer when unmounting while two
        // are running
        if (startTimerCommit.current === null) {
          // Prepare the ripple effect.
          startTimerCommit.current = () => {
            startCommit({
              pulsate,
              rippleX,
              rippleY,
              rippleSize,
              cb
            });
          }; // Delay the execution of the ripple effect.
  
  
          startTimer.current = setTimeout(() => {
            if (startTimerCommit.current) {
              startTimerCommit.current();
              startTimerCommit.current = null;
            }
          }, DELAY_RIPPLE); // We have to make a tradeoff with this value.
        }
      } else {
        startCommit({
          pulsate,
          rippleX,
          rippleY,
          rippleSize,
          cb
        });
      }
    }, [centerProp, startCommit]);
    const pulsate = React.useCallback(() => {
      start({}, {
        pulsate: true
      });
    }, [start]);
    const stop = React.useCallback((event, cb) => {
      clearTimeout(startTimer.current); // The touch interaction occurs too quickly.
      // We still want to show ripple effect.
  
      if (event.type === 'touchend' && startTimerCommit.current) {
        startTimerCommit.current();
        startTimerCommit.current = null;
        startTimer.current = setTimeout(() => {
          stop(event, cb);
        });
        return;
      }
  
      startTimerCommit.current = null;
      setRipples(oldRipples => {
        if (oldRipples.length > 0) {
          return oldRipples.slice(1);
        }
  
        return oldRipples;
      });
      rippleCallback.current = cb;
    }, []);
    React.useImperativeHandle(ref, () => ({
      pulsate,
      start,
      stop
    }), [pulsate, start, stop]);
    return /*#__PURE__*/(0, _jsxRuntime.jsx)(TouchRippleRoot, (0, _extends2.default)({
      className: (0, _clsx.default)(classes.root, _touchRippleClasses.default.root, className),
      ref: container
    }, other, {
      children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactTransitionGroup.TransitionGroup, {
        component: null,
        exit: true,
        children: ripples
      })
    }));
  });
  process.env.NODE_ENV !== "production" ? TouchRipple.propTypes = {
    /**
     * If `true`, the ripple starts at the center of the component
     * rather than at the point of interaction.
     */
    center: _propTypes.default.bool,
  
    /**
     * Override or extend the styles applied to the component.
     * See [CSS API](#css) below for more details.
     */
    classes: _propTypes.default.object,
  
    /**
     * @ignore
     */
    className: _propTypes.default.string
  } : void 0;
  var _default = TouchRipple;
  exports.default = _default;