<commit_before>import React from "react";
import PropTypes from "prop-types";
import cx from "classnames";
import { InputCore } from "../Input";
import messages from "../utils/messages.js";

let labelStyle, title_label, disabledClass, checkboxDisplay;
/**
 * Simple component for a basic checkbox
 */
class Checkbox extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      checked: this.props.checked || false,
      valid: true,
      errorMessage: "",
      focus: false
    };
    labelStyle = cx({
      label: props.labelPosition !== "left",
      label_left: props.labelPosition === "left"
    });
    title_label = props.title ? props.title : props.label;
    disabledClass = props.disabled
      ? cx("disabled", "inline_block", "relative", "padding")
      : cx("inline_block", "relative", "padding");
    checkboxDisplay = props.labelPosition === "left"
      ? cx("float_right")
      : cx("float_left");
  }

  // Handles new checkbox clicks and sets value and checked status of hidden input
  _clickHandler = event => {
    if (!this.props.disabled) {
      /* Check if onClick has been passed, if so call it. */
      if (this.props.onClick) {
        /* Pass the event object, and a data object to the click handler.
         The data object contains a boolean for whether the checkbox was
         clicked or not, plus all the props passed to the object.  */
        this.props.onClick(event, {
          checked: this.state.checked,
          props: this.props
        });
      }

      this._handleChange();

      /* Check if onChange has been passed, if so call it. */
      if (this.props.onChange) {
        /* Pass the event object, and a data object to the click handler.
         The data object contains a boolean for whether the checkbox was
         clicked or not, plus all the props passed to the object.  */
        this.props.onChange(event, {
          checked: this.state.checked,
          props: this.props
        });
      }
    }
  };

  _validationHandler = callback => {
    // If custom validation callback is provided set validationObject with response, otherwise check if required
    const validationObject = callback
      ? callback(event, this.state.checked)
      : {
          valid:
            (this.props.required && this.state.checked) || !this.props.required,
          message: this.props.requiredMessage || messages.requiredMessage
        };
    this.setState({
      valid: validationObject.valid,
      errorMessage: validationObject.message
    });
  };

  _blur = callback => {
    this.setState({ focus: false });
    this._validationHandler(callback);
  };

  _focus = () => {
    this.setState({ focus: true });
  };

  _handleChange = () => {
    if (
      typeof this.props.onBeforeChange === "undefined" ||
      this.props.onBeforeChange(this.state.checked)
    ) {
      if (this.state.checked) {
        this.setState({ checked: false }, function() {
          this._validationHandler(this.props.errorCallback);
          if (typeof this.props.groupHandleClick !== "undefined") {
            this.props.groupHandleClick(this.state.checked);
          }
        });
      } else {
        this.setState({ checked: true }, function() {
          this._validationHandler(this.props.errorCallback);
          if (typeof this.props.groupHandleClick !== "undefined") {
            this.props.groupHandleClick(this.state.checked);
          }
        });
      }
    }
  };

  render() {
    const {
      label,
      disabled,
      className,
      name,
      groupError,
      errorCallback,
      inline
    } = this.props;
    const inlineCheckbox = cx({ inline_block: inline, checkbox_padding: true }); // TODO: Figure out why, if moved to constructor, this causes an error with CheckboxGroup
    const error = groupError || !this.state.valid;
    let checkboxClass = cx({
      checked: this.state.checked,
      error: error,
      not_checked: !this.state.checked,
      focus: this.state.focus
    });

    return (
      <div
        onClick={this._clickHandler}
        styleName={inlineCheckbox}
        onFocus={() => {
          this._focus();
        }}
        onBlur={() => {
          this._blur(errorCallback);
        }}
      >
        <div styleName={disabledClass}>
          {label &&
            <label
              styleName={labelStyle}
              title={title_label}
              className={cx(className)}
            >
              {label}
            </label>}
          <div styleName={checkboxDisplay}>
            <InputCore
              label={label}
              type="checkbox"
              disabled={disabled}
              checked={this.state.checked}
              hidden={disabled}
              name={name}
            />
            <div styleName={checkboxClass}>
              {this.state.checked && <div styleName={cx("checkmark")} />}
            </div>
          </div>
          {this.props.required &&
            <span styleName={"error_text"}>*</span>
          }
        </div>
        {error &&
          !groupError &&
          <div styleName={cx("error_message")}>{this.state.errorMessage}</div>}
      </div>
    );
  }
}

Checkbox.propTypes = {
  /**
   * Text for checkbox label
   * @examples 'Some Label'
   */
  label: PropTypes.string,
  /**
   * A css class name that will be appended to the wrapping <label> element around the <input> and <span> elements.
   */
  className: PropTypes.string,
  /**
   * If included, checkbox is disabled
   * @examples <Checkbox disabled />, <Checkbox disabled={true} />
   */
  disabled: PropTypes.bool,
  /**<commit_msg>Moving more variables out of the constructor to avoid state change defects<commit_after>import React from "react";
import PropTypes from "prop-types";
import cx from "classnames";
import { InputCore } from "../Input";
import messages from "../utils/messages.js";

/**
 * Simple component for a basic checkbox
 */
class Checkbox extends React.PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      checked: this.props.checked || false,
      valid: true,
      errorMessage: "",
      focus: false
    };
  }

  // Handles new checkbox clicks and sets value and checked status of hidden input
  _clickHandler = event => {
    if (!this.props.disabled) {
      /* Check if onClick has been passed, if so call it. */
      if (this.props.onClick) {
        /* Pass the event object, and a data object to the click handler.
         The data object contains a boolean for whether the checkbox was
         clicked or not, plus all the props passed to the object.  */
        this.props.onClick(event, {
          checked: this.state.checked,
          props: this.props
        });
      }

      this._handleChange();

      /* Check if onChange has been passed, if so call it. */
      if (this.props.onChange) {
        /* Pass the event object, and a data object to the click handler.
         The data object contains a boolean for whether the checkbox was
         clicked or not, plus all the props passed to the object.  */
        this.props.onChange(event, {
          checked: this.state.checked,
          props: this.props
        });
      }
    }
  };

  _validationHandler = callback => {
    // If custom validation callback is provided set validationObject with response, otherwise check if required
    const validationObject = callback
      ? callback(event, this.state.checked)
      : {
          valid:
            (this.props.required && this.state.checked) || !this.props.required,
          message: this.props.requiredMessage || messages.requiredMessage
        };
    this.setState({
      valid: validationObject.valid,
      errorMessage: validationObject.message
    });
  };

  _blur = callback => {
    this.setState({ focus: false });
    this._validationHandler(callback);
  };

  _focus = () => {
    this.setState({ focus: true });
  };

  _handleChange = () => {
    if (
      typeof this.props.onBeforeChange === "undefined" ||
      this.props.onBeforeChange(this.state.checked)
    ) {
      if (this.state.checked) {
        this.setState({ checked: false }, function() {
          this._validationHandler(this.props.errorCallback);
          if (typeof this.props.groupHandleClick !== "undefined") {
            this.props.groupHandleClick(this.state.checked);
          }
        });
      } else {
        this.setState({ checked: true }, function() {
          this._validationHandler(this.props.errorCallback);
          if (typeof this.props.groupHandleClick !== "undefined") {
            this.props.groupHandleClick(this.state.checked);
          }
        });
      }
    }
  };

  render() {
    const {
      label,
      title,
      disabled,
      className,
      name,
      groupError,
      errorCallback,
      inline,
      labelPosition
    } = this.props;
    // TODO: Figure out why, if moved to constructor, the following variables cause issues on click
    const inlineCheckbox = cx({ inline_block: inline, checkbox_padding: true });
    const labelStyle = cx({
      label: labelPosition !== "left",
      label_left: labelPosition === "left"
    });
    const checkboxDisplay = labelPosition === "left"
      ? cx("float_right")
      : cx("float_left");
    const title_label = title ? title : label;
    const disabledClass = disabled
      ? cx("disabled", "inline_block", "relative", "padding")
      : cx("inline_block", "relative", "padding");
    const error = groupError || !this.state.valid;
    let checkboxClass = cx({
      checked: this.state.checked,
      error: error,
      not_checked: !this.state.checked,
      focus: this.state.focus
    });

    return (
      <div
        onClick={this._clickHandler}
        styleName={inlineCheckbox}
        onFocus={() => {
          this._focus();
        }}
        onBlur={() => {
          this._blur(errorCallback);
        }}
      >
        <div styleName={disabledClass}>
          {label &&
            <label
              styleName={labelStyle}
              title={title_label}
              className={cx(className)}
            >
              {label}
            </label>}
          <div styleName={checkboxDisplay}>
            <InputCore
              label={label}
              type="checkbox"
              disabled={disabled}
              checked={this.state.checked}
              hidden={disabled}
              name={name}
            />
            <div styleName={checkboxClass}>
              {this.state.checked && <div styleName={cx("checkmark")} />}
            </div>
          </div>
          {this.props.required && <span styleName={"error_text"}>*</span>}
        </div>
        {error &&
          !groupError &&
          <div styleName={cx("error_message")}>{this.state.errorMessage}</div>}
      </div>
    );
  }
}

Checkbox.propTypes = {
  /**
   * Text for checkbox label
   * @examples 'Some Label'
   */
  label: PropTypes.string,
  /**
   * A css class name that will be appended to the wrapping <label> element around the <input> and <span> elements.
   */
  className: PropTypes.string,
  /**
   * If included, checkbox is disabled
   * @examples <Checkbox disabled />, <Checkbox disabled={true} />
   */
  disabled: PropTypes.bool,
  /**
{'fraction_non_alphanumeric': 0.12297189467151343, 'fraction_numerical': 0.0, 'mean_word_length': 2.104017611447441, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '670165', 'n_tokens_mistral': 3062, 'n_tokens_neox': 3038, 'n_words': 803}