content: import React from 'react';
  import PropTypes from 'prop-types';
  import { Transition } from 'react-transition-group';
  import { duration } from '../styles/transitions';
  import useTheme from '../styles/useTheme';
  import { reflow, getTransitionProps } from '../transitions/utils';
  import { useForkRef } from '../utils/reactHelpers';
  
  const styles = {
    entering: {
      opacity: 1,
    },
    entered: {
      opacity: 1,
    },
  };
  
  const defaultTimeout = {
    enter: duration.enteringScreen,
    exit: duration.leavingScreen,
  };
  
  /**
   * The Fade transition is used by the [Modal](/components/modal/) component.
   * It uses [react-transition-group](https://github.com/reactjs/react-transition-group) internally.
   */
  const Fade = React.forwardRef(function Fade(props, ref) {
    const {
      children,
      in: inProp,
      onEnter,
      onExit,
      style,
      timeout = defaultTimeout,
      ...other
    } = props;
    const theme = useTheme();
    const handleRef = useForkRef(children.ref, ref);
  
    const handleEnter = (node, isAppearing) => {
      reflow(node); // So the animation always start from the start.
  
      const transitionProps = getTransitionProps(
        { style, timeout },
        {
          mode: 'enter',
        },
      );
      node.style.webkitTransition = theme.transitions.create('opacity', transitionProps);
      node.style.transition = theme.transitions.create('opacity', transitionProps);
  
      if (onEnter) {
        onEnter(node, isAppearing);
      }
    };
  
    const handleExit = node => {
      const transitionProps = getTransitionProps(
        { style, timeout },
        {
          mode: 'exit',
        },
      );
      node.style.webkitTransition = theme.transitions.create('opacity', transitionProps);
      node.style.transition = theme.transitions.create('opacity', transitionProps);
  
      if (onExit) {
        onExit(node);
      }
    };
  
    return (
      <Transition
        appear
        in={inProp}
        onEnter={handleEnter}
        onExit={handleExit}
        timeout={timeout}
        {...other}
      >
        {(state, childProps) => {
          return React.cloneElement(children, {
            style: {
              opacity: 0,
              visibility: state === 'exited' && !inProp ? 'hidden' : undefined,
              ...styles[state],
              ...style,
              ...children.props.style,
            },
            ref: handleRef,
            ...childProps,
          });
        }}
      </Transition>
    );
  });
  
  Fade.propTypes = {
    /**
     * A single child content element.
     */
    children: PropTypes.element,
    /**
     * If `true`, the component will transition in.
     */
    in: PropTypes.bool,
    /**
     * @ignore
     */
    onEnter: PropTypes.func,
    /**
     * @ignore
     */
    onExit: PropTypes.func,
    /**
     * @ignore
     */
    style: PropTypes.object,
    /**
     * The duration for the transition, in milliseconds.
     * You may specify a single timeout for all transitions, or individually with an object.
     */
    timeout: PropTypes.oneOfType([
      PropTypes.number,
      PropTypes.shape({ enter: PropTypes.number, exit: PropTypes.number }),
    ]),
  };
  
  export default Fade;
  