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

/**
 * Web Checkbox Component
 *
 */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import keycode from 'keycode';
import { isTrue, extendPropsWithContext, registerElement, validateDOMAttributes, dispatchCustomElementEvent } from '../../shared/component-helper';
import FormLabel from '../form-label/FormLabel';
import FormStatus from '../form-status/FormStatus';
const renderProps = {
  on_change: null,
  on_state_update: null
};
export const propTypes = {
  label: PropTypes.string,
  label_position: PropTypes.oneOf(['left', 'right']),
  title: PropTypes.string,
  default_state: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
  checked: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
  disabled: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
  id: PropTypes.string,
  status: PropTypes.string,
  status_state: PropTypes.string,
  status_animation: PropTypes.string,
  value: PropTypes.string,
  attributes: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
  readOnly: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
  class: PropTypes.string,
  /// React props
  className: PropTypes.string,
  children: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
  // Web Component props
  custom_element: PropTypes.object,
  custom_method: PropTypes.func,
  on_change: PropTypes.func,
  on_state_update: PropTypes.func
};
export const defaultProps = _objectSpread({
  label: null,
  label_position: 'right',
  title: null,
  default_state: null,
  checked: 'default',
  //we have to send this as a string
  disabled: null,
  id: null,
  status: null,
  status_state: 'error',
  status_animation: null,
  value: null,
  attributes: null,
  readOnly: false,
  class: null,
  // React props
  className: null,
  children: null,
  // Web Component props
  custom_element: null,
  custom_method: null
}, renderProps);
/**
 * The checkbox component is our enhancement of the classic checkbox button. It acts like a checkbox. Example: On/off, yes/no.
 */

var _ref =
/*#__PURE__*/
React.createElement("span", {
  "aria-hidden": true,
  className: "dnb-checkbox__button"
}, React.createElement("span", {
  className: "dnb-checkbox__focus"
}));

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

  static getDerivedStateFromProps(props, state) {
    if (state._listenForPropChanges) {
      if (state.hasDefaultState) {
        state.checked = Checkbox.parseChecked(props.default_state);
        state.hasDefaultState = false;
      } else if (props.checked !== 'default') {
        state.checked = Checkbox.parseChecked(props.checked);
      }
    }

    state._listenForPropChanges = true;
    return state;
  }

  constructor(props) {
    super(props);

    _defineProperty(this, "onKeyDownHandler", event => {
      switch (keycode(event)) {
        case 'enter':
          this.onChangeHandler(event);
          break;
      }
    });

    _defineProperty(this, "onChangeHandler", event => {
      if (isTrue(this.props.readOnly)) {
        return event.preventDefault();
      }

      const checked = !this.state.checked;
      this.setState({
        checked,
        _listenForPropChanges: false
      });
      dispatchCustomElementEvent(this, 'on_change', {
        checked,
        event
      }); // help firefox and safari to have an correct state after a click

      if (this._refInput.current) {
        this._refInput.current.focus();
      }
    });

    _defineProperty(this, "onMouseOutHandler", () => {
      // this way we keep the new state after the user changed the state, without getting the error state back vissually
      if (this.props.status && this.props.status_state === 'error') {
        return;
      }

      if (this._refInput.current) {
        this._refInput.current.blur();
      }
    });

    this._refInput = React.createRef();
    this._id = props.id || "dnb-checkbox-".concat(Math.round(Math.random() * 999)); // cause we need an id anyway

    this.state = {
      _listenForPropChanges: true,
      hasDefaultState: props.default_state !== null,
      checked: Checkbox.parseChecked(props.default_state || props.checked)
    };
  }

  shouldComponentUpdate(nextProps, nextState) {
    if (Checkbox.parseChecked(this.props.checked) !== Checkbox.parseChecked(nextProps.checked)) {
      const {
        checked
      } = nextState;
      dispatchCustomElementEvent(this, 'on_state_update', {
        checked
      });
    }

    return true;
  }

  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 {
      value,
      status,
      status_state,
      status_animation,
      label,
      label_position,
      title,
      disabled,
      readOnly,
      className,
      class: _className,
      id: _id,
      // eslint-disable-line
      default_state: _default_state,
      // eslint-disable-line
      checked: _checked,
      // eslint-disable-line
      attributes,
      // eslint-disable-line
      children,
      // eslint-disable-line
      on_change,
      // eslint-disable-line
      on_state_update,
      // eslint-disable-line
      custom_method,
      // eslint-disable-line
      custom_element
    } = props,
          rest = _objectWithoutProperties(props, ["value", "status", "status_state", "status_animation", "label", "label_position", "title", "disabled", "readOnly", "className", "class", "id", "default_state", "checked", "attributes", "children", "on_change", "on_state_update", "custom_method", "custom_element"]);

    const {
      checked
    } = this.state;
    const id = this._id;
    const showStatus = status && status !== 'error';
    const classes = classnames('dnb-checkbox', status && "dnb-checkbox__status--".concat(status_state), className, _className);

    const inputParams = _objectSpread({
      disabled,
      checked,
      onMouseOut: this.onMouseOutHandler
    }, rest);

    if (showStatus) {
      inputParams['aria-describedby'] = id + '-status';
    }

    if (label) {
      inputParams['aria-labelledby'] = id + '-label';
    }

    if (readOnly) {
      inputParams['aria-readonly'] = inputParams.readOnly = true;
    } // also used for code markup simulation


    validateDOMAttributes(this.props, inputParams);
    const statusComp = showStatus && React.createElement(FormStatus, {
      text: status,
      status: status_state,
      text_id: id + '-status' // used for "aria-describedby"
      ,
      animation: status_animation
    });
    return React.createElement(React.Fragment, null, React.createElement("span", {
      className: classnames('dnb-checkbox--modifier', label && label_position && "dnb-checkbox--label-position-".concat(label_position))
    }, label && React.createElement(FormLabel, {
      id: id + '-label',
      for_id: id,
      text: label,
      disabled: disabled
    }), React.createElement("span", {
      className: classes
    }, React.createElement("span", {
      className: "dnb-checkbox__shell"
    }, React.createElement("input", _extends({
      id: id,
      name: id,
      type: "checkbox",
      title: title,
      "aria-checked": checked,
      className: "dnb-checkbox__input",
      value: checked ? value || '' : '',
      disabled: isTrue(disabled)
    }, inputParams, {
      onChange: this.onChangeHandler,
      onKeyDown: this.onKeyDownHandler,
      ref: this._refInput
    })), _ref, _ref2), label_position === 'left' && statusComp)), label_position === 'right' && statusComp);
  }

}

_defineProperty(Checkbox, "tagName", 'dnb-checkbox');

_defineProperty(Checkbox, "defaultProps", defaultProps);

_defineProperty(Checkbox, "renderProps", renderProps);

_defineProperty(Checkbox, "parseChecked", state => /true|on/.test(String(state)));

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

var _ref3 =
/*#__PURE__*/
React.createElement("path", {
  d: "M5.86 12.95a.75.75 0 1 0-1.22.86l1.22-.86zm2.15 4.34l.62-.42-.01-.01-.61.43zm.94.52l.02-.75-.02.75zm.98-.46l-.6-.47v.01l.6.46zm9.4-10.7a.75.75 0 0 0-1.17-.93l1.18.93zm-14.7 7.16l2.76 3.91 1.23-.86-2.76-3.91-1.22.86zm2.75 3.9c.35.52.93.84 1.55.85l.04-1.5a.43.43 0 0 1-.34-.19l-1.25.84zm1.55.85c.62.02 1.22-.26 1.6-.76l-1.2-.9a.43.43 0 0 1-.36.16l-.04 1.5zm1.59-.75l8.82-11.16-1.18-.93-8.82 11.16 1.18.93z"
});

const CheckGfx = props => React.createElement("svg", _extends({
  xmlns: "http://www.w3.org/2000/svg",
  width: "24",
  height: "24",
  viewBox: "0 0 24 24",
  fill: "none"
}, props), _ref3),
      _ref2 =
/*#__PURE__*/
React.createElement(CheckGfx, {
  className: "dnb-checkbox__gfx"
});