text: import _extends from "@babel/runtime/helpers/esm/extends";
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
  import * as React from 'react';
  import PropTypes from 'prop-types';
  import * as ReactDOM from 'react-dom';
  import clsx from 'clsx';
  import { elementTypeAcceptingRef, refType } from '@material-ui/utils';
  import useForkRef from '../utils/useForkRef';
  import useEventCallback from '../utils/useEventCallback';
  import withStyles from '../styles/withStyles';
  import useIsFocusVisible from '../utils/useIsFocusVisible';
  import TouchRipple from './TouchRipple';
  export const styles = {
    /* Styles applied to the root element. */
    root: {
      display: 'inline-flex',
      alignItems: 'center',
      justifyContent: 'center',
      position: 'relative',
      WebkitTapHighlightColor: 'transparent',
      backgroundColor: 'transparent',
      // Reset default value
      // We disable the focus ring for mouse, touch and keyboard users.
      outline: 0,
      border: 0,
      margin: 0,
      // Remove the margin in Safari
      borderRadius: 0,
      padding: 0,
      // Remove the padding in Firefox
      cursor: 'pointer',
      userSelect: 'none',
      verticalAlign: 'middle',
      '-moz-appearance': 'none',
      // Reset
      '-webkit-appearance': 'none',
      // Reset
      textDecoration: 'none',
      // So we take precedent over the style of a native <a /> element.
      color: 'inherit',
      '&::-moz-focus-inner': {
        borderStyle: 'none' // Remove Firefox dotted outline.
  
      },
      '&$disabled': {
        pointerEvents: 'none',
        // Disable link interactions
        cursor: 'default'
      },
      '@media print': {
        colorAdjust: 'exact'
      }
    },
  
    /* Pseudo-class applied to the root element if `disabled={true}`. */
    disabled: {},
  
    /* Pseudo-class applied to the root element if keyboard focused. */
    focusVisible: {}
  };
  /**
   * `ButtonBase` contains as few styles as possible.
   * It aims to be a simple building block for creating a button.
   * It contains a load of style reset and some focus/ripple logic.
   */
  
  const ButtonBase = React.forwardRef(function ButtonBase(props, ref) {
    const {
      action,
      buttonRef: buttonRefProp,
      centerRipple = false,
      children,
      classes,
      className,
      component = 'button',
      disabled = false,
      disableRipple = false,
      disableTouchRipple = false,
      focusRipple = false,
      focusVisibleClassName,
      onBlur,
      onClick,
      onFocus,
      onFocusVisible,
      onKeyDown,
      onKeyUp,
      onMouseDown,
      onMouseLeave,
      onMouseUp,
      onTouchEnd,
      onTouchMove,
      onTouchStart,
      onDragLeave,
      tabIndex = 0,
      TouchRippleProps,
      type = 'button'
    } = props,
          other = _objectWithoutPropertiesLoose(props, ["action", "buttonRef", "centerRipple", "children", "classes", "className", "component", "disabled", "disableRipple", "disableTouchRipple", "focusRipple", "focusVisibleClassName", "onBlur", "onClick", "onFocus", "onFocusVisible", "onKeyDown", "onKeyUp", "onMouseDown", "onMouseLeave", "onMouseUp", "onTouchEnd", "onTouchMove", "onTouchStart", "onDragLeave", "tabIndex", "TouchRippleProps", "type"]);
  
    const buttonRef = React.useRef(null);
  
    function getButtonNode() {
      // #StrictMode ready
      return ReactDOM.findDOMNode(buttonRef.current);
    }
  
    const rippleRef = React.useRef(null);
    const [focusVisible, setFocusVisible] = React.useState(false);
  
    if (disabled && focusVisible) {
      setFocusVisible(false);
    }
  
    const {
      isFocusVisible,
      onBlurVisible,
      ref: focusVisibleRef
    } = useIsFocusVisible();
    React.useImperativeHandle(action, () => ({
      focusVisible: () => {
        setFocusVisible(true);
        buttonRef.current.focus();
      }
    }), []);
    React.useEffect(() => {
      if (focusVisible && focusRipple && !disableRipple) {
        rippleRef.current.pulsate();
      }
    }, [disableRipple, focusRipple, focusVisible]);
  
    function useRippleHandler(rippleAction, eventCallback, skipRippleAction = disableTouchRipple) {
      return useEventCallback(event => {
        if (eventCallback) {
          eventCallback(event);
        }
  
        const ignore = skipRippleAction;
  
        if (!ignore && rippleRef.current) {
          rippleRef.current[rippleAction](event);
        }
  
        return true;
      });
    }
  
    const handleMouseDown = useRippleHandler('start', onMouseDown);
    const handleDragLeave = useRippleHandler('stop', onDragLeave);
    const handleMouseUp = useRippleHandler('stop', onMouseUp);
    const handleMouseLeave = useRippleHandler('stop', event => {
      if (focusVisible) {
        event.preventDefault();
      }
  
      if (onMouseLeave) {
        onMouseLeave(event);
      }
    });
    const handleTouchStart = useRippleHandler('start', onTouchStart);
    const handleTouchEnd = useRippleHandler('stop', onTouchEnd);
    const handleTouchMove = useRippleHandler('stop', onTouchMove);
    const handleBlur = useRippleHandler('stop', event => {
      if (focusVisible) {
        onBlurVisible(event);
        setFocusVisible(false);
      }
  
      if (onBlur) {
        onBlur(event);
      }
    }, false);
    const handleFocus = useEventCallback(event => {
      // Fix for https://github.com/facebook/react/issues/7769
      if (!buttonRef.current) {
        buttonRef.current = event.currentTarget;
      }
  
      if (isFocusVisible(event)) {
        setFocusVisible(true);
  
        if (onFocusVisible) {
          onFocusVisible(event);
        }
      }
  
      if (onFocus) {
        onFocus(event);
      }
    });
  
    const isNonNativeButton = () => {
      const button = getButtonNode();
      return component && component !== 'button' && !(button.tagName === 'A' && button.href);
    };
    /**
     * IE 11 shim for https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat
     */
  
  
    const keydownRef = React.useRef(false);
    const handleKeyDown = useEventCallback(event => {
      // Check if key is already down to avoid repeats being counted as multiple activations
      if (focusRipple && !keydownRef.current && focusVisible && rippleRef.current && event.key === ' ') {
        keydownRef.current = true;
        event.persist();
        rippleRef.current.stop(event, () => {
          rippleRef.current.start(event);
        });
      }
  
      if (event.target === event.currentTarget && isNonNativeButton() && event.key === ' ') {
        event.preventDefault();
      }
  
      if (onKeyDown) {
        onKeyDown(event);
      } // Keyboard accessibility for non interactive elements
  
  
      if (event.target === event.currentTarget && isNonNativeButton() && event.key === 'Enter' && !disabled) {
        event.preventDefault();
  
        if (onClick) {
          onClick(event);
        }
      }
    });
    const handleKeyUp = useEventCallback(event => {
      // calling preventDefault in keyUp on a <button> will not dispatch a click event if Space is pressed
      // https://codesandbox.io/s/button-keyup-preventdefault-dn7f0
      if (focusRipple && event.key === ' ' && rippleRef.current && focusVisible && !event.defaultPrevented) {
        keydownRef.current = false;
        event.persist();
        rippleRef.current.stop(event, () => {
          rippleRef.current.pulsate(event);
        });
      }
  
      if (onKeyUp) {
        onKeyUp(event);
      } // Keyboard accessibility for non interactive elements
  
  
      if (onClick && event.target === event.currentTarget && isNonNativeButton() && event.key === ' ' && !event.defaultPrevented) {
        onClick(event);
      }
    });
    let ComponentProp = component;
  
    if (ComponentProp === 'button' && other.href) {
      ComponentProp = 'a';
    }
  
    const buttonProps = {};
  
    if (ComponentProp === 'button') {
      buttonProps.type = type;
      buttonProps.disabled = disabled;
    } else {
      if (ComponentProp !== 'a' || !other.href) {
        buttonProps.role = 'button';
      }
  
      buttonProps['aria-disabled'] = disabled;
    }
  
    const handleUserRef = useForkRef(buttonRefProp, ref);
    const handleOwnRef = useForkRef(focusVisibleRef, buttonRef);
    const handleRef = useForkRef(handleUserRef, handleOwnRef);
    const [mountedState, setMountedState] = React.useState(false);
    React.useEffect(() => {
      setMountedState(true);
    }, []);
    const enableTouchRipple = mountedState && !disableRipple && !disabled;
  
    if (process.env.NODE_ENV !== 'production') {
      // eslint-disable-next-line react-hooks/rules-of-hooks
      React.useEffect(() => {
        if (enableTouchRipple && !rippleRef.current) {
          console.error(['Material-UI: the `component` prop provided to ButtonBase is invalid.', 'Please make sure the children prop is rendered in this custom component.'].join('\n'));
        }
      }, [enableTouchRipple]);
    }
  
    return /*#__PURE__*/React.createElement(ComponentProp, _extends({
      className: clsx(classes.root, className, focusVisible && [classes.focusVisible, focusVisibleClassName], disabled && classes.disabled),
      onBlur: handleBlur,
      onClick: onClick,
      onFocus: handleFocus,
      onKeyDown: handleKeyDown,
      onKeyUp: handleKeyUp,
      onMouseDown: handleMouseDown,
      onMouseLeave: handleMouseLeave,
      onMouseUp: handleMouseUp,
      onDragLeave: handleDragLeave,
      onTouchEnd: handleTouchEnd,
      onTouchMove: handleTouchMove,
      onTouchStart: handleTouchStart,
      ref: handleRef,
      tabIndex: disabled ? -1 : tabIndex
    }, buttonProps, other), children, enableTouchRipple ?
    /*#__PURE__*/
  
    /* TouchRipple is only needed client-side, x2 boost on the server. */
    React.createElement(TouchRipple, _extends({
      ref: rippleRef,
      center: centerRipple
    }, TouchRippleProps)) : null);
  });
  process.env.NODE_ENV !== "production" ? ButtonBase.propTypes = {
    /**
     * A ref for imperative actions.
     * It currently only supports `focusVisible()` action.
     */
    action: refType,
  
    /**
     * @ignore
     *
     * Use that prop to pass a ref to the native button component.
     * @deprecated Use `ref` instead.
     */
    buttonRef: refType,
  
    /**
     * If `true`, the ripples will be centered.
     * They won't start at the cursor interaction position.
     */
    centerRipple: PropTypes.bool,
  
    /**
     * The content of the component.
     */
    children: PropTypes.node,
  
    /**
     * Override or extend the styles applied to the component.
     * See [CSS API](#css) below for more details.
     */
    classes: PropTypes.object.isRequired,
  
    /**
     * @ignore
     */
    className: PropTypes.string,
  
    /**
     * The component used for the root node.
     * Either a string to use a HTML element or a component.
     */
    component: elementTypeAcceptingRef,
  
    /**
     * If `true`, the base button will be disabled.
     */
    disabled: PropTypes.bool,
  
    /**
     * If `true`, the ripple effect will be disabled.
     *
     * ⚠️ Without a ripple there is no styling for :focus-visible by default. Be sure
     * to highlight the element by applying separate styles with the `focusVisibleClassName`.
     */
    disableRipple: PropTypes.bool,
  
    /**
     * If `true`, the touch ripple effect will be disabled.
     */
    disableTouchRipple: PropTypes.bool,
  
    /**
     * If `true`, the base button will have a keyboard focus ripple.
     * `disableRipple` must also be `false`.
     */
    focusRipple: PropTypes.bool,
  
    /**
     * This prop can help a person know which element has the keyboard focus.
     * The class name will be applied when the element gain the focus through a keyboard interaction.
     * It's a polyfill for the [CSS :focus-visible selector](https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo).
     * The rationale for using this feature [is explained here](https://github.com/WICG/focus-visible/blob/master/explainer.md).
     * A [polyfill can be used](https://github.com/WICG/focus-visible) to apply a `focus-visible` class to other components
     * if needed.
     */
    focusVisibleClassName: PropTypes.string,
  
    /**
     * @ignore
     */
    onBlur: PropTypes.func,
  
    /**
     * @ignore
     */
    onClick: PropTypes.func,
  
    /**
     * @ignore
     */
    onDragLeave: PropTypes.func,
  
    /**
     * @ignore
     */
    onFocus: PropTypes.func,
  
    /**
     * Callback fired when the component is focused with a keyboard.
     * We trigger a `onFocus` callback too.
     */
    onFocusVisible: PropTypes.func,
  
    /**
     * @ignore
     */
    onKeyDown: PropTypes.func,
  
    /**
     * @ignore
     */
    onKeyUp: PropTypes.func,
  
    /**
     * @ignore
     */
    onMouseDown: PropTypes.func,
  
    /**
     * @ignore
     */
    onMouseLeave: PropTypes.func,
  
    /**
     * @ignore
     */
    onMouseUp: PropTypes.func,
  
    /**
     * @ignore
     */
    onTouchEnd: PropTypes.func,
  
    /**
     * @ignore
     */
    onTouchMove: PropTypes.func,
  
    /**
     * @ignore
     */
    onTouchStart: PropTypes.func,
  
    /**
     * @ignore
     */
    role: PropTypes.string,
  
    /**
     * @ignore
     */
    tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  
    /**
     * Props applied to the `TouchRipple` element.
     */
    TouchRippleProps: PropTypes.object,
  
    /**
     * Used to control the button's purpose.
     * This prop passes the value to the `type` attribute of the native button component.
     */
    type: PropTypes.oneOf(['submit', 'reset', 'button'])
  } : void 0;
  export default withStyles(styles, {
    name: 'MuiButtonBase'
  })(ButtonBase);