<commit_before>import React, { Component } from 'react';
import Radium from 'radium';
import _ from 'lodash/object';
import defaultValidator from '../Utils/Validators/default';

//Default style used as defualt prop
const defaultStyle = {
  fieldContainer: {
    width: '300px',
    minHeight: '90px',
    margin: '8px 0px',
  },
  fieldText: {
    textAlign: 'left',
    fontFamily: 'sans-serif',
    lineHeight: 1,
  },
  fieldLabel: {
    fontSize: '14px',
    margin: '0px 0px 4px 0px',
  },
  fieldHintText: {
    margin: '0px 0px 4px 0px',
    fontSize: '12px',
    color: '#7a7a7a',
  },
  fieldInput: {
    base: {
      border: '1px solid #c3c3c3',
      borderRadius: '3px',
      padding: '8px',
      width: '250px',
      fontSize: '16px',
      ':focus': {
        border: '1px solid #494949',
        outline: 0,
      },
      ':disabled': {
        backgroundColor: '#f7f7f7',
      }
    },
    valid: {
      border: '1px solid #009c19',
      ':focus': {
        border: '1px solid #009c19',
        outline: 0,
      }
    },
    invalid: {
      border: '1px solid #c70000',
      ':focus': {
        border: '1px solid #c70000',
        outline: 0,
      }
    }
  },
  fieldFeedback: {
    base: {
      margin: '4px 0px 4px 0px',
      fontSize: '12px',
      color: '#7a7a7a',
    },
    valid: {
      color: '#009c19',
    },
    invalid: {
      color: '#c70000',
    },
  }
};
function DefaultFeedbackElement(state) {
  return(
    <p style={[state.style.fieldFeedback.base, state.style.fieldFeedback[state.state]]}>
      {state.feedbackMessage}
    </p>
  )
};

class AgileTextField extends Component {
  constructor(props) {
    super(props);
    //Overwrite defaultStyle if custom has been provided, Without removing untouched defaultStyles
    //Creates a new object based on the defaultStyle and the custom style from prop
    var styles = this.props.style ? _.merge({},defaultStyle, this.props.style) : defaultStyle;
    this.state = {
      state: 'base',
      value: '',
      isValid: true,
      feedbackMessage: '',
      style: styles
    };
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleValidate = this.handleValidate.bind(this);
  }
  handleInputChange(event) {
    this.setState({value: event.target.value}, () => {
      //Call done inside callback
      //Insures that the state has been updated before calling
      if(this.props.validateOnChange) {
        this.handleValidate();
      }
      this.props.onValueChange(this.state);
    });
  }
  handleValidate() {
    //The validator returns an object representing the state
    var result = this.props.validator(this.state.value);
    this.setState(result, () => {
      //Call done inside callback
      //Insures that the state has been updated before calling
      this.props.onStateChange(this.state);
    });
  }
  render() {
    return (
      <div style={[this.state.style.fieldContainer, this.state.style.fieldText]}>
        <p style={this.state.style.fieldLabel}>{this.props.label}</p>
        {this.props.hintText.length > 0 &&
          <p style={this.state.style.fieldHintText}>{this.props.hintText}</p>
        }
          <input style={[this.state.style.fieldInput.base, this.state.style.fieldInput[this.state.state]]}
            type={this.props.type}
            name={this.props.name}
            value={this.state.value}
            onChange={this.handleInputChange}
            onBlur={this.props.validateInput && this.handleValidate}
            disabled={this.props.disabled}
          />
          {this.props.feedbackElement(this.state)}
      </div>
    );
  }
}

//Specifies the propTypes
AgileTextField.propTypes = {
  type: React.PropTypes.oneOf(['text', 'password']),
  name: React.PropTypes.string,
  label: React.PropTypes.string.isRequired,
  hintText: React.PropTypes.string,
  validator: React.PropTypes.func,
  validateInput: React.PropTypes.bool,
  validateOnChange: React.PropTypes.bool,
  onStateChange: React.PropTypes.func,
  onValueChange: React.PropTypes.func,
  feedbackElement: React.PropTypes.func,
  style: React.PropTypes.object,
  disabled: React.PropTypes.bool,
};
// Specifies the default values for props:
AgileTextField.defaultProps = {
  type: 'text',
  hintText: '',
  validator: defaultValidator,
  validateInput: false,
  validateOnChange: false,<commit_msg>Added optional indicator via prop<commit_after>import React, { Component } from 'react';
import Radium from 'radium';
import _ from 'lodash/object';
import defaultValidator from '../Utils/Validators/default';

//Default style used as defualt prop
const defaultStyle = {
  fieldContainer: {
    width: '300px',
    minHeight: '90px',
    margin: '8px 0px',
  },
  fieldText: {
    textAlign: 'left',
    fontFamily: 'sans-serif',
    lineHeight: 1,
  },
  fieldLabel: {
    fontSize: '14px',
    margin: '0px 0px 4px 0px',
  },
  fieldLabelOptional: {
    color: '#7a7a7a',
    fontStyle: 'italic'
  },
  fieldHintText: {
    margin: '0px 0px 4px 0px',
    fontSize: '12px',
    color: '#7a7a7a',
  },
  fieldInput: {
    base: {
      border: '1px solid #c3c3c3',
      borderRadius: '3px',
      padding: '8px',
      width: '250px',
      fontSize: '16px',
      ':focus': {
        border: '1px solid #494949',
        outline: 0,
      },
      ':disabled': {
        backgroundColor: '#f7f7f7',
      }
    },
    valid: {
      border: '1px solid #009c19',
      ':focus': {
        border: '1px solid #009c19',
        outline: 0,
      }
    },
    invalid: {
      border: '1px solid #c70000',
      ':focus': {
        border: '1px solid #c70000',
        outline: 0,
      }
    }
  },
  fieldFeedback: {
    base: {
      margin: '4px 0px 4px 0px',
      fontSize: '12px',
      color: '#7a7a7a',
    },
    valid: {
      color: '#009c19',
    },
    invalid: {
      color: '#c70000',
    },
  }
};
function DefaultFeedbackElement(state) {
  return(
    <p style={[state.style.fieldFeedback.base, state.style.fieldFeedback[state.state]]}>
      {state.feedbackMessage}
    </p>
  )
};

class AgileTextField extends Component {
  constructor(props) {
    super(props);
    //Overwrite defaultStyle if custom has been provided, Without removing untouched defaultStyles
    //Creates a new object based on the defaultStyle and the custom style from prop
    var styles = this.props.style ? _.merge({},defaultStyle, this.props.style) : defaultStyle;
    this.state = {
      state: 'base',
      value: '',
      isValid: true,
      feedbackMessage: '',
      style: styles
    };
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleValidate = this.handleValidate.bind(this);
  }
  handleInputChange(event) {
    this.setState({value: event.target.value}, () => {
      //Call done inside callback
      //Insures that the state has been updated before calling
      if(this.props.validateOnChange) {
        this.handleValidate();
      }
      this.props.onValueChange(this.state);
    });
  }
  handleValidate() {
    //The validator returns an object representing the state
    var result = this.props.validator(this.state.value);
    this.setState(result, () => {
      //Call done inside callback
      //Insures that the state has been updated before calling
      this.props.onStateChange(this.state);
    });
  }
  render() {
    return (
      <div style={[this.state.style.fieldContainer, this.state.style.fieldText]}>
        <p style={this.state.style.fieldLabel}>
          {this.props.label}
          {this.props.optional &&
            <span style={this.state.style.fieldLabelOptional}> - Optional</span>
          }
        </p>
        {this.props.hintText.length > 0 &&
          <p style={this.state.style.fieldHintText}>{this.props.hintText}</p>
        }
          <input style={[this.state.style.fieldInput.base, this.state.style.fieldInput[this.state.state]]}
            type={this.props.type}
            name={this.props.name}
            value={this.state.value}
            onChange={this.handleInputChange}
            onBlur={this.props.validateInput && this.handleValidate}
            disabled={this.props.disabled}
          />
          {this.props.feedbackElement(this.state)}
      </div>
    );
  }
}

//Specifies the propTypes
AgileTextField.propTypes = {
  type: React.PropTypes.oneOf(['text', 'password']),
  name: React.PropTypes.string,
  label: React.PropTypes.string.isRequired,
  optional: React.PropTypes.bool,
  hintText: React.PropTypes.string,
  validator: React.PropTypes.func,
  validateInput: React.PropTypes.bool,
  validateOnChange: React.PropTypes.bool,
  onStateChange: React.PropTypes.func,
  onValueChange: React.PropTypes.func,
  feedbackElement: React.PropTypes.func,
  style: React.PropTypes.object,
  disabled: React.PropTypes.bool,
};
// Specifies the default values for props:
AgileTextField.defaultProps = {
  type: 'text',
  optional: false,
  hintText: '',
  validator: defaultValidator,
  validateInput: false,
  validateOnChange: false,
{'fraction_non_alphanumeric': 0.1369649805447471, 'fraction_numerical': 0.02056698165647582, 'mean_word_length': 2.6628664495114007, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 29, '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': '7630653', 'n_tokens_mistral': 2963, 'n_tokens_neox': 2878, 'n_words': 606}