import _extends from "@babel/runtime/helpers/extends";
import _objectSpread from "@babel/runtime/helpers/objectSpread";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _defineProperty from "@babel/runtime/helpers/defineProperty";

/**
 * Web Button Component
 *
 */
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import Context from '../../shared/Context';
import IconPrimary from '../icon-primary/IconPrimary';
import { isTrue, extendPropsWithContext, registerElement, validateDOMAttributes, processChildren, pickRenderProps, dispatchCustomElementEvent } from '../../shared/component-helper';
const renderProps = {
  on_click: null
};
export const propTypes = {
  /** the content of the button. */
  text: PropTypes.string,
  type: PropTypes.string,
  title: PropTypes.string,

  /* _(optional)_ defines the kind of button. Possible values are `primary`, `secondary`, `tertiary` and `signal`.  */
  variant: PropTypes.oneOf(['primary', 'secondary', 'tertiary', 'signal']),
  size: PropTypes.oneOf(['default', 'small', 'medium', 'large']),
  icon: PropTypes.oneOfType([PropTypes.string, PropTypes.node, PropTypes.func]),
  icon_position: PropTypes.oneOf(['left', 'right']),
  icon_size: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  id: PropTypes.string,
  class: PropTypes.string,
  href: PropTypes.string,
  bounding: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
  disabled: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
  // React props
  className: PropTypes.string,
  innerRef: PropTypes.object,
  children: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.node]),
  // Web Component props
  custom_element: PropTypes.object,
  custom_method: PropTypes.func,
  // Events
  onClick: PropTypes.func,
  on_click: PropTypes.oneOfType([PropTypes.string, PropTypes.func])
};
export const defaultProps = {
  type: 'button',
  text: null,
  variant: null,
  size: null,
  title: null,
  icon: null,
  icon_position: 'right',
  icon_size: 'default',
  href: null,
  id: null,
  class: null,
  bounding: false,
  disabled: null,
  // React props
  className: null,
  innerRef: null,
  children: null,
  // Web Component props
  custom_element: null,
  custom_method: null,
  // Events
  onClick: null,
  on_click: null
  /**
   * The button component should be used as the call-to-action in a form, or as a user interaction mechanism. Generally speaking, a button should not be used when a link would do the trick. Exceptions are made at times when it is used as a navigation element in the action-nav element.
   */

};
export default class Button extends PureComponent {
  static enableWebComponent() {
    registerElement(Button.tagName, Button, defaultProps);
  }

  static getContent(props) {
    return processChildren(props);
  }

  constructor(props) {
    super(props);

    _defineProperty(this, "onMouseOutHandler", () => {
      if (this._ref.current) {
        this._ref.current.blur();
      }
    });

    _defineProperty(this, "onClickHandler", event => {
      const afterContent = dispatchCustomElementEvent(this, 'on_click', {
        event
      });

      if (afterContent && React.isValidElement(afterContent)) {
        this.setState({
          afterContent
        });
      }
    });

    this._ref = React.createRef(); // pass along all props we wish to have as params

    this.renderProps = pickRenderProps(props, renderProps);
    this.state = {
      afterContent: null
    };
  }

  componentDidMount() {
    if (this.props.innerRef && typeof this.props.innerRef.current !== 'undefined') {
      this.props.innerRef.current = this._ref.current;
    }
  }

  render() {
    // consume the formRow context
    const props = this.context.formRow ? // use only the props from context, who are available here anyway
    extendPropsWithContext(this.props, this.context.formRow) : this.props;

    const {
      class: class_name,
      className,
      type,
      variant,
      size,
      title,
      id,
      disabled,
      text,
      icon,
      icon_position,
      href,
      bounding,
      // eslint-disable-line
      innerRef
    } = props,
          attributes = _objectWithoutProperties(props, ["class", "className", "type", "variant", "size", "title", "id", "disabled", "text", "icon", "icon_position", "href", "bounding", "innerRef"]);

    let usedVariant = variant;
    let usedSize = size; // if only has Icon, then resize it and define it as secondary

    const isIconOnly = Boolean(!text && icon);

    if (isIconOnly) {
      if (!usedVariant) {
        usedVariant = 'secondary';
      }

      if (!usedSize) {
        usedSize = 'medium';
      }
    } else if (text) {
      if (!usedVariant) {
        usedVariant = 'primary';
      }

      if (!usedSize) {
        usedSize = 'default';
      }
    }

    const content = Button.getContent(this.props);
    const classes = classnames('dnb-button', "dnb-button--".concat(usedVariant || 'primary'), usedSize && usedSize !== 'default' ? "dnb-button--size-".concat(usedSize) : null, icon && icon_position ? "dnb-button--icon-position-".concat(icon_position) : null, text ? 'dnb-button--has-text' : null, icon ? 'dnb-button--has-icon' : null, class_name, className, href ? '' : null // dnb-anchor--no-underline dnb-anchor--no-hover
    );

    const params = _objectSpread({}, this.renderProps, {
      className: classes,
      type,
      title,
      id,
      disabled: isTrue(disabled)
    }, attributes, {
      onMouseOut: this.onMouseOutHandler,
      // for resetting the button to the default state
      onClick: this.onClickHandler
    });

    if (!params['aria-label'] && !text && title) {
      params['aria-label'] = title;
    } // also used for code markup simulation


    validateDOMAttributes(this.props, params);
    return React.createElement(React.Fragment, null, href ? React.createElement("a", _extends({
      href: href,
      ref: this._ref
    }, params), React.createElement(Content, _extends({}, this.props, {
      content: content,
      isIconOnly: isIconOnly
    }))) : React.createElement("button", _extends({
      ref: this._ref
    }, params), React.createElement(Content, _extends({}, this.props, {
      content: content,
      isIconOnly: isIconOnly
    }))), this.state.afterContent);
  }

}

_defineProperty(Button, "tagName", 'dnb-button');

_defineProperty(Button, "defaultProps", defaultProps);

_defineProperty(Button, "renderProps", renderProps);

_defineProperty(Button, "contextType", Context);

Button.propTypes = process.env.NODE_ENV !== "production" ? propTypes : {};

var _ref =
/*#__PURE__*/
React.createElement("span", {
  key: "button-bounding",
  className: "dnb-button__bounding"
});

class Content extends PureComponent {
  render() {
    const {
      text,
      title,
      content,
      icon,
      icon_size,
      bounding,
      isIconOnly
    } = this.props;
    const ret = [];

    if (bounding) {
      ret.push(_ref);
    }

    if (content) {
      ret.push(content);
    }

    if (text) {
      ret.push(React.createElement("span", {
        key: "button-text",
        className: "dnb-button__text"
      }, text));
    }

    if (icon) {
      const alt = title || text;
      ret.push(React.createElement(IconPrimary, {
        key: "button-icon",
        className: "dnb-button__icon",
        icon: icon,
        size: icon_size,
        alt: alt,
        "aria-hidden": isIconOnly ? false : Boolean(alt)
      }));
    }

    return ret;
  }

}

_defineProperty(Content, "defaultProps", {
  text: null,
  title: null,
  content: null,
  icon: null,
  icon_size: 'default',
  bounding: false,
  isIconOnly: null
});

Content.propTypes = process.env.NODE_ENV !== "production" ? {
  text: PropTypes.string,
  title: PropTypes.string,
  content: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
  icon: PropTypes.oneOfType([PropTypes.string, PropTypes.node, PropTypes.func]),
  icon_size: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  bounding: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
  isIconOnly: PropTypes.bool
} : {};