text: /**
   * Copyright IBM Corp. 2016, 2018
   *
   * This source code is licensed under the Apache-2.0 license found in the
   * LICENSE file in the root directory of this source tree.
   */
  
  import PropTypes from 'prop-types';
  import React from 'react';
  import classNames from 'classnames';
  import { settings } from 'carbon-components';
  import { ButtonTypes } from '../../prop-types/types';
  import warning from 'warning';
  
  const { prefix } = settings;
  
  let didWarnAboutDeprecation = false;
  
  const Button = React.forwardRef(function Button(
    {
      children,
      as,
      className,
      disabled,
      small,
      size,
      kind,
      href,
      tabIndex,
      type,
      renderIcon: ButtonImageElement,
      iconDescription,
      ...other
    },
    ref
  ) {
    const buttonClasses = classNames(className, {
      [`${prefix}--btn`]: true,
      [`${prefix}--btn--field`]: size === 'field',
      [`${prefix}--btn--sm`]: size === 'small' || small,
      [`${prefix}--btn--primary`]: kind === 'primary',
      [`${prefix}--btn--danger`]: kind === 'danger',
      [`${prefix}--btn--secondary`]: kind === 'secondary',
      [`${prefix}--btn--ghost`]: kind === 'ghost',
      [`${prefix}--btn--danger--primary`]: kind === 'danger--primary',
      [`${prefix}--btn--tertiary`]: kind === 'tertiary',
      [`${prefix}--btn--disabled`]: disabled,
    });
  
    if (__DEV__) {
      if (small && !didWarnAboutDeprecation) {
        warning(
          false,
          `\nThe prop \`small\` for Button has been deprecated in favor of \`size\`. Please use \`type="small"\` instead.`
        );
        didWarnAboutDeprecation = true;
      }
    }
  
    const commonProps = {
      tabIndex,
      className: buttonClasses,
      ref,
    };
  
    const buttonImage = !ButtonImageElement ? null : (
      <ButtonImageElement
        aria-label={iconDescription}
        className={`${prefix}--btn__icon`}
        aria-hidden={true}
      />
    );
  
    let component = 'button';
    let otherProps = {
      disabled,
      type,
    };
    const anchorProps = {
      role: 'button',
      href,
    };
    if (as) {
      component = as;
      otherProps = {
        ...otherProps,
        ...anchorProps,
      };
    } else if (href) {
      component = 'a';
      otherProps = anchorProps;
    }
    return React.createElement(
      component,
      {
        ...other,
        ...commonProps,
        ...otherProps,
      },
      children,
      buttonImage
    );
  });
  
  Button.propTypes = {
    /**
     * Specify the content of your Button
     */
    children: PropTypes.node,
  
    /**
     * Specify how the button itself should be rendered.
     * Make sure to apply all props to the root node and render children appropriately
     */
    as: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
  
    /**
     * Specify an optional className to be added to your Button
     */
    className: PropTypes.string,
  
    /**
     * Specify whether the Button should be disabled, or not
     */
    disabled: PropTypes.bool,
  
    /**
     * Specify the size of the button, from a list of available sizes.
     * For `default` buttons, this prop can remain unspecified.
     */
    size: PropTypes.oneOf(['default', 'field', 'small']),
  
    /**
     * Deprecated in v10 in favor of `size`.
     * Specify whether the Button should be a small variant
     */
    small: PropTypes.bool,
  
    /**
     * Specify the kind of Button you want to create
     */
    kind: ButtonTypes.buttonKind.isRequired,
  
    /**
     * Optionally specify an href for your Button to become an <a> element
     */
    href: PropTypes.string,
  
    /**
     * Optional prop to specify the tabIndex of the Button
     */
    tabIndex: PropTypes.number,
  
    /**
     * Optional prop to specify the type of the Button
     */
    type: PropTypes.oneOf(['button', 'reset', 'submit']),
  
    /**
     * Optional prop to specify the role of the Button
     */
    role: PropTypes.string,
  
    /**
     * Optional prop to allow overriding the icon rendering.
     * Can be a React component class
     */
    renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
  
    /**
     * If specifying the `icon` prop, provide a description for that icon that can
     * be read by screen readers
     */
    iconDescription: props => {
      if (props.renderIcon && !props.children && !props.iconDescription) {
        return new Error(
          'renderIcon property specified without also providing an iconDescription property.'
        );
      }
      return undefined;
    },
  };
  
  Button.defaultProps = {
    tabIndex: 0,
    type: 'button',
    disabled: false,
    small: false,
    kind: 'primary',
  };
  
  export default Button;
  