function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

/* Copyright (c) 2015-present, salesforce.com, inc. All rights reserved */

/* Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license */
// Implements the [Button design pattern](https://lightningdesignsystem.com/components/buttons/) in React.
// Based on SLDS v2.2.1
import React from 'react';
import createReactClass from 'create-react-class';
import requiredIf from 'react-required-if';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import ButtonIcon from '../icon/button-icon';
import checkProps from './check-props';
import componentDoc from './docs.json';
import Tooltip from '../tooltip';
import { BUTTON } from '../../utilities/constants';
var defaultProps = {
  assistiveText: {
    icon: ''
  },
  disabled: false,
  hint: false,
  iconSize: 'medium',
  responsive: false,
  type: 'button',
  variant: 'neutral'
};
/**
 * The Button component is the Lightning Design System Button component. The Button should be used for label buttons, icon buttons, or buttons that have both labels and icons.
 * Either a <code>label</code> or <code>assistiveText.icon</code> is required; see the Prop Details table below.
 * For buttons that maintain selected/unselected states, use the <a href="#/button-stateful">ButtonStateful</a> component.
 */

var Button = createReactClass({
  displayName: BUTTON,
  propTypes: {
    /**
     * Used if the Button triggers a tooltip. The value should match the `id` of the element with `role="tooltip"`.
     */
    'aria-describedby': PropTypes.string,

    /**
     * Establishes a relationship between an interactive parent element and a child element to indicate which child element a parent element affects. Frequently used in cases where buttons or tabs are associated with exposing expandable regions.
     */
    'aria-controls': PropTypes.string,

    /**
     * Used if the Button triggers a menu or popup. Bool indicates if the menu or popup is open or closed.
     */
    'aria-expanded': PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),

    /**
     * True if Button triggers a menu or popup to open/close.
     */
    'aria-haspopup': PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),

    /**
     * **Assistive text for accessibility.**
     * This object is merged with the default props object on every render.
     * * `icon`: Text that is visually hidden but read aloud by screenreaders to tell the user what the icon means. If the button has an icon and a visible label, you can omit the <code>assistiveText.icon</code> prop and use the <code>label</code> prop.
     */
    assistiveText: PropTypes.shape({
      icon: PropTypes.string
    }),

    /**
     * Callback that passes in the DOM reference of the `<button>` DOM node within this component. Primary use is to allow `focus` to be called. You should still test if the node exists, since rendering is asynchronous. `buttonRef={(component) => { if(component) console.log(component); }}`
     */
    buttonRef: PropTypes.func,

    /**
     * CSS classes to be added to button.
     */
    className: PropTypes.oneOfType([PropTypes.array, PropTypes.object, PropTypes.string]),

    /**
     * Disables the button and adds disabled styling.
     */
    disabled: PropTypes.bool,

    /**
     * Associates an icon button with another element on the page by changes the color of the SVG. Please reference <a href="http://www.lightningdesignsystem.com/components/buttons/#hint">Lightning Design System Buttons > Hint</a>.
     */
    hint: PropTypes.bool,

    /**
     * Name of the icon category. Visit <a href="http://www.lightningdesignsystem.com/resources/icons">Lightning Design System Icons</a> to reference icon categories.
     */
    iconCategory: requiredIf(PropTypes.oneOf(['action', 'custom', 'doctype', 'standard', 'utility']), function (props) {
      return !!props.iconName;
    }),

    /**
     * CSS classes to be added to icon.
     */
    iconClassName: PropTypes.oneOfType([PropTypes.array, PropTypes.object, PropTypes.string]),

    /**
     * Name of the icon. Visit <a href="http://www.lightningdesignsystem.com/resources/icons">Lightning Design System Icons</a> to reference icon names.
     */
    iconName: PropTypes.string,

    /**
     * Path to the icon. This will override any global icon settings.
     */
    iconPath: PropTypes.string,

    /**
     * If omitted, icon position is centered.
     */
    iconPosition: PropTypes.oneOf(['left', 'right']),

    /**
     * Determines the size of the icon.
     */
    iconSize: PropTypes.oneOf(['x-small', 'small', 'medium', 'large']),

    /**
     * For icon variants, please reference <a href="http://www.lightningdesignsystem.com/components/buttons/#icon">Lightning Design System Icons</a>.
     */
    iconVariant: PropTypes.oneOf(['bare', 'container', 'border', 'border-filled', 'more', 'global-header']),

    /**
     * Id string applied to button node.
     */
    id: PropTypes.string,

    /**
     * If true, button/icon is white. Meant for buttons or utility icons on dark backgrounds.
     */
    inverse: PropTypes.bool,

    /**
     * Visible label on the button. If the button is an icon button with no label, you must use the <code>assistiveText.icon</code> prop.
     */
    label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),

    /**
     * Triggered when focus is removed.
     */
    onBlur: PropTypes.func,

    /**
     * Triggered when the button is clicked.
     */
    onClick: PropTypes.func,

    /**
     * Triggered when component is focused.
     */
    onFocus: PropTypes.func,

    /**
     * Triggered when a key is pressed down
     */
    onKeyDown: PropTypes.func,

    /**
     * Triggered when a key is pressed and released
     */
    onKeyPress: PropTypes.func,

    /**
     * Triggered when a key is released
     */
    onKeyUp: PropTypes.func,

    /**
     * Triggered when a mouse button is pressed down
     */
    onMouseDown: PropTypes.func,

    /**
     * Triggered when a mouse arrow hovers
     */
    onMouseEnter: PropTypes.func,

    /**
     * Triggered when a mouse arrow no longer hovers
     */
    onMouseLeave: PropTypes.func,

    /**
     * If true, button scales to 100% width on small form factors.
     */
    responsive: PropTypes.bool,

    /**
     * Write <code>"-1"</code> if you don't want the user to tab to the button.
     */
    tabIndex: PropTypes.string,

    /**
     * Button type
     */
    type: PropTypes.oneOf(['reset', 'submit', 'button']),

    /**
     * HTML title attribute
     */
    title: PropTypes.string,

    /**
     * [Deprecated] Tooltip on button. Button should be a child of `Tooltip` instead.
     */
    tooltip: PropTypes.node,

    /**
     * Different types of buttons
     */
    variant: PropTypes.oneOf(['base', 'link', 'neutral', 'brand', 'destructive', 'success', 'icon']),

    /**
     * Custom styles to be passed to the component
     */
    style: PropTypes.object
  },
  getDefaultProps: function getDefaultProps() {
    return defaultProps;
  },
  componentWillMount: function componentWillMount() {
    // `checkProps` issues warnings to developers about properties (similar to React's built in development tools)
    checkProps(BUTTON, this.props, componentDoc);
  },
  getClassName: function getClassName() {
    var _classNames;

    var isIcon = this.props.variant === 'icon';
    var iconVariant = this.props.iconVariant;
    var iconMore = iconVariant === 'more';
    var iconBorder = iconVariant === 'border';
    var iconGlobalHeader = iconVariant === 'global-header';
    var showButtonVariant = this.props.variant !== 'base' && !iconVariant && !this.props.inverse && this.props.variant !== 'link' || iconVariant === 'bare';
    var plainInverseBtn = this.props.inverse && !isIcon;
    var plainInverseIcon = this.props.inverse && isIcon && !iconMore && !iconBorder;
    var moreInverseIcon = this.props.inverse && iconMore;
    var borderInverseIcon = this.props.inverse && iconBorder; // After hijacking `iconVariant` to let `Button` know it's in the header, we reset to container style for the actual button CSS.

    if (iconVariant === 'global-header') {
      iconVariant = 'container';
    }

    return classNames((_classNames = {
      'slds-button': this.props.variant !== 'link'
    }, _defineProperty(_classNames, "slds-button--".concat(this.props.variant), showButtonVariant), _defineProperty(_classNames, 'slds-button--inverse', plainInverseBtn), _defineProperty(_classNames, 'slds-button--icon-inverse', plainInverseIcon || moreInverseIcon), _defineProperty(_classNames, 'slds-button--icon-border-inverse', borderInverseIcon), _defineProperty(_classNames, "slds-button--icon-".concat(iconVariant), iconVariant && !borderInverseIcon), _defineProperty(_classNames, 'slds-global-header__button--icon', iconGlobalHeader), _defineProperty(_classNames, "slds-button--icon-".concat(this.props.iconSize), iconVariant && this.props.iconSize !== 'medium'), _defineProperty(_classNames, 'slds-button--reset', this.props.variant === 'link'), _defineProperty(_classNames, 'slds-text-link', this.props.variant === 'link'), _classNames), this.props.className);
  },
  handleClick: function handleClick(event) {
    if (this.props.onClick) {
      this.props.onClick(event, {});
    }
  },
  renderIcon: function renderIcon(name) {
    var iconSize = this.props.iconSize === '' || this.props.iconVariant ? null : this.props.iconSize;
    return React.createElement(ButtonIcon, {
      category: this.props.iconCategory || 'utility' // BREAKING CHANGE we will introduce in 1.0. For the moment, set default prop here if none specified.
      ,
      className: classNames({
        'slds-global-header__icon': this.props.iconVariant === 'global-header'
      }, this.props.iconClassName),
      hint: this.props.hint,
      inverse: this.props.inverse,
      name: name,
      path: this.props.iconPath,
      position: this.props.iconPosition,
      size: iconSize
    });
  },
  renderLabel: function renderLabel() {
    var iconOnly = this.props.iconName || this.props.iconPath;
    var assistiveTextIcon = typeof this.props.assistiveText === 'string' ? this.props.assistiveText : _objectSpread({}, defaultProps.assistiveText, this.props.assistiveText).icon;
    return iconOnly && assistiveTextIcon ? React.createElement("span", {
      className: "slds-assistive-text"
    }, assistiveTextIcon) : this.props.label;
  },
  renderButton: function renderButton() {
    var _this = this;

    return React.createElement("button", {
      "aria-controls": this.props['aria-controls'],
      "aria-describedby": this.props['aria-describedby'],
      "aria-expanded": this.props['aria-expanded'],
      "aria-haspopup": this.props['aria-haspopup'],
      className: this.getClassName(),
      disabled: this.props.disabled,
      id: this.props.id,
      onBlur: this.props.onBlur,
      onClick: this.handleClick,
      onFocus: this.props.onFocus,
      onKeyDown: this.props.onKeyDown,
      onKeyPress: this.props.onKeyPress,
      onKeyUp: this.props.onKeyUp,
      onMouseDown: this.props.onMouseDown,
      onMouseEnter: this.props.onMouseEnter,
      onMouseLeave: this.props.onMouseLeave,
      ref: function ref(component) {
        if (_this.props.buttonRef) {
          _this.props.buttonRef(component);
        }
      },
      tabIndex: this.props.tabIndex,
      title: this.props.title,
      type: this.props.type,
      style: this.props.style
    }, this.props.iconPosition === 'right' ? this.renderLabel() : null, this.props.iconName || this.props.iconPath ? this.renderIcon(this.props.iconName) : null, this.props.iconVariant === 'more' ? React.createElement(ButtonIcon, {
      category: "utility",
      name: "down",
      size: "x-small"
    }) : null, this.props.iconPosition === 'left' || !this.props.iconPosition ? this.renderLabel() : null, this.props.children // eslint-disable-line react/prop-types
    );
  },
  // This is present for backwards compatibility and should be removed at a future breaking change release. Please wrap a `Button` in a `PopoverTooltip` to achieve the same result. There will be an extra trigger `div` wrapping the `Button` though.
  renderTooltip: function renderTooltip() {
    return React.createElement(Tooltip, {
      content: this.props.tooltip
    }, this.renderButton);
  },
  render: function render() {
    return this.props.tooltip ? this.renderTooltip() : this.renderButton();
  }
});
export default Button;
//# sourceMappingURL=index.js.map