import { r as registerInstance, c as createEvent, h, H as Host, g as getElement } from './index-442cf464.js';
import { c as createColorClasses, g as getClassMap } from './theme-a8bb96f5.js';

var FormGroupTypes;
(function (FormGroupTypes) {
    FormGroupTypes["input"] = "input";
    FormGroupTypes["select"] = "select";
    FormGroupTypes["checkboxGroup"] = "checkbox-group";
    FormGroupTypes["radioGroup"] = "radio-group";
    FormGroupTypes["textArea"] = "text-area";
    FormGroupTypes["comboBox"] = "combo-box";
})(FormGroupTypes || (FormGroupTypes = {}));

const formGroupCss = ":host{--lu-formgroup-label-padding-bottom:0;display:block;position:relative;text-align:initial;box-sizing:border-box}.container{display:flex;flex-flow:column}.label-helper-text-container{display:flex;flex-flow:row;align-items:center;justify-content:space-between}.label-helper-text-container>label{color:#222222;font-size:16px;line-height:26px}.helper-text{color:#686A6F;font-size:12px;font-style:italic;line-height:15px}.helper-text-notification{color:#256EC1;font-size:14px;font-style:inherit;line-height:26px}.error{color:#E4002B;font-size:14px;line-height:22px}.is-invalid{padding-left:9px;padding-right:0;border-left:#E4002B solid 2px}lu-label{--lu-label-padding-bottom:var(--lu-formgroup-label-padding-bottom)}";

const FormGroup = class {
  constructor(hostRef) {
    registerInstance(this, hostRef);
    this.luFormGroupDidUpdate = createEvent(this, "luFormGroupDidUpdate", 7);
    /**
     * object of default error messages
     */
    this.errorText = {
      required: 'This is a required field',
      emailInvalid: 'Please enter a valid email',
      emailInvalidComboBoxMultiSelect: 'One of the selections has an invalid email address.',
      checkboxRequired: 'You must check at least one checkbox',
    };
    /**
     * Shows that inputs value is valid
     */
    this.isValid = false;
    /**
     * Shows that inputs value is NOT valid
     */
    this.isInvalid = false;
    /**
     * tells us if the element is required or not
     */
    this.isRequired = false;
    /**
     * tells us if the element needs email validation
     */
    this.needsEmailValidation = false;
    /**
     * tells us if the element needs pattern validation
     */
    this.needsPatternValidation = false;
    /**
     * tells us if the element needs password validation
     */
    this.needsPasswordValidation = false;
    /**
     * Clears error and error message when clear input is clicked
     */
    this.clearErrorStateOnClearInput = false;
    /**
     * Only used for advanced components where the input, select, etc is not slotted. If true, a clear icon will appear in the input when there is a value. Clicking it clears the input. Defaults to `false`.
     */
    this.clearInput = false;
    /**
     * if external validation is being used this property is used to override isValid state
     */
    this.externallyDeemedValid = false;
    /**
     * if external validation is being used this property is used to override isValid state
     */
    this.externallyDeemedInvalid = false;
    /**
     * tells component to stop its own validation and validate externally
     */
    this.isExternallyValidated = false;
    //todo: figure out if we want to implement this for internal validation and what that would look like.
    /**
     * tells if validation is made on submission
     */
    this.isValidatedOnSubmission = false;
    /**
     * sets the update trigger - options
     */
    this.updateTrigger = 'blur';
    /**
     * Provides option to use asterisk as required indicator
     */
    this.useAsteriskAsRequiredIndicator = false;
    this.getInputElements = () => {
      return Array.from(this.luFormGroupEl.children);
    };
    this.emailValidationCheckFailed = (text) => {
      return !(typeof text === 'string' &&
        /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(text));
    };
  }
  externallyDeemedValidChanged(newExternallyDeemedValid, oldExternallyDeemedValid) {
    if (oldExternallyDeemedValid !== newExternallyDeemedValid)
      this.overrideValidState(newExternallyDeemedValid);
  }
  externallyDeemedInvalidChanged(newExternallyDeemedInvalid, oldExternallyDeemedInvalid) {
    if (oldExternallyDeemedInvalid !== newExternallyDeemedInvalid)
      this.overrideInvalidState(newExternallyDeemedInvalid);
  }
  watchHandler(newValue) {
    this.useId = newValue + '-frm-grp';
  }
  async connectedCallback() {
    if (this.errorMessage) {
      this.generatedErrorMessage = this.errorMessage;
    }
    this.dataSource = this.categorizeDatasource(this.getInputElements()[0]);
    if (this.dataSource) {
      await this.dataSource.element.componentOnReady();
      if (this.dataSource.kind === FormGroupTypes.input ||
        this.dataSource.kind === FormGroupTypes.comboBox) {
        if (this.dataSource.element.type &&
          this.dataSource.element.type === 'email') {
          this.needsEmailValidation = true;
        }
        else if (this.dataSource.kind === FormGroupTypes.input &&
          this.dataSource.element.pattern &&
          this.dataSource.element.pattern !== '') {
          this.needsPatternValidation = true;
          this.pattern = this.dataSource.element.pattern;
        }
      }
      this.handleElementsCommonLoadTasks(this.dataSource);
      this.dataSource.element.addEventListener('luChange', (ev) => {
        this.setValue(ev);
      });
      this.dataSource.element.addEventListener('luBlur', () => this.handleBlur());
      this.dataSource.element.addEventListener('luFocus', () => this.handleFocus());
      if (this.dataSource.kind === FormGroupTypes.input) {
        this.dataSource.element.addEventListener('luSuffixClickedOrTapped', () => this.handleSuffixIconClicked());
      }
      this.value = this.dataSource.element.value;
    }
    else {
      console.error('No input element found.');
    }
  }
  categorizeDatasource(element) {
    if (element.tagName === 'LU-SELECT')
      return {
        kind: FormGroupTypes.select,
        element: element,
      };
    if (element.tagName === 'LU-TEXT-AREA')
      return {
        kind: FormGroupTypes.textArea,
        element: element,
      };
    if (element.tagName === 'LU-RADIO-GROUP')
      return {
        kind: FormGroupTypes.radioGroup,
        element: element,
      };
    if (element.tagName === 'LU-CHECKBOX-GROUP')
      return {
        kind: FormGroupTypes.checkboxGroup,
        element: element,
      };
    if (element.tagName === 'LU-COMBO-BOX')
      return {
        kind: FormGroupTypes.comboBox,
        element: element,
      };
    if (element.tagName === 'LU-INPUT')
      return {
        kind: FormGroupTypes.input,
        element: element,
      };
  }
  disconnectedCallback() {
    this.dataSource.element.removeEventListener('luChange', (ev) => {
      this.setValue(ev);
    });
    this.dataSource.element.removeEventListener('luBlur', () => this.handleBlur());
    this.dataSource.element.removeEventListener('luFocus', () => this.handleFocus());
    this.dataSource.element.removeEventListener('luSuffixClickedOrTapped', () => this.handleSuffixIconClicked());
    this.dataSource = undefined;
  }
  /**
   * starting validation method.
   */
  async validate() {
    //the idea is a list of all validation types which are either valid or invalid
    let validationArray = [];
    if (this.isRequired)
      validationArray.push({ required: false });
    if (this.needsEmailValidation)
      validationArray.push({ emailValidation: false });
    if (this.needsPatternValidation)
      validationArray.push({ patternValidation: false });
    if (!this.isExternallyValidated) {
      this.generatedErrorMessage = this.errorMessage;
      //required
      if (this.isRequired) {
        if (!this.value ||
          this.value === '' ||
          (this.dataSource.kind === FormGroupTypes.checkboxGroup &&
            typeof this.value !== 'string' &&
            typeof this.value !== 'number' &&
            this.value.filter((checkbox) => checkbox.checked === true)
              .length === 0) ||
          (this.dataSource.kind === FormGroupTypes.comboBox &&
            this.dataSource.element.multipleSelections &&
            this.value.length === 0)) {
          this.generatedErrorMessage =
            this.dataSource.kind === FormGroupTypes.checkboxGroup
              ? this.errorText.checkboxRequired
              : this.errorText.required;
          this.setStateAsInvalid();
        }
        else {
          validationArray.filter((validation) => validation.required === false)[0].required = true;
        }
      }
      //email validation
      if (this.needsEmailValidation) {
        // todo: for combo box multi select pass back to the component what the invalid values are to help user
        if (this.value &&
          this.value !== '' &&
          ((!(this.dataSource.kind === FormGroupTypes.comboBox &&
            this.dataSource.element.multipleSelections) &&
            this.emailValidationCheckFailed(this.value)) ||
            (this.dataSource.kind === FormGroupTypes.comboBox &&
              this.dataSource.element.multipleSelections &&
              this.value.length > 0 &&
              this.value.filter((box) => {
                return this.emailValidationCheckFailed(box.value);
              }).length > 0))) {
          if (!this.errorMessage) {
            this.generatedErrorMessage = !!(this.dataSource.kind === FormGroupTypes.comboBox &&
              this.dataSource.element.multipleSelections)
              ? this.errorText.emailInvalidComboBoxMultiSelect
              : this.errorText.emailInvalid;
          }
          this.setStateAsInvalid();
        }
        else {
          validationArray.filter((validation) => validation.emailValidation === false)[0].emailValidation = true;
        }
      }
      //pattern validation
      if (this.value &&
        this.value !== '' &&
        this.needsPatternValidation &&
        this.pattern) {
        const reggie = new RegExp(this.pattern);
        if (!(typeof this.value === 'string' && reggie.test(this.value))) {
          if (!this.errorMessage) {
            this.generatedErrorMessage = this.errorText.patternMatchInvalid;
          }
          this.setStateAsInvalid();
        }
        else {
          validationArray.filter((validation) => validation.patternValidation === false)[0].patternValidation = true;
        }
        // if pattern validation is used but the field is not required and also does not have a value, validate successfully
      }
      else if ((!this.value || this.value === '') &&
        this.needsPatternValidation &&
        this.pattern &&
        !this.isRequired) {
        validationArray.filter((validation) => validation.patternValidation === false)[0].patternValidation = true;
      }
    }
    if (validationArray.filter((validation) => {
      return (Object.keys(validation).filter((key) => {
        return validation[key] !== true;
      }).length !== 0);
    }).length === 0) {
      this.setStateAsValid();
    }
    this.luFormGroupDidUpdate.emit();
  }
  /**
   * update value while reseting error state
   */
  async updateValue(newValue) {
    this.resetInvalidState();
    this.resetValidState();
    await this.dataSource.element.updateValue(newValue);
  }
  async getValidationValues() {
    let requiredStuff = {};
    let validState = false;
    let inValidState = false;
    const type = this.dataSource.kind;
    if (this.isRequired) {
      requiredStuff.required = true;
    }
    if (this.needsEmailValidation) {
      requiredStuff.email = true;
    }
    if (this.needsPatternValidation) {
      requiredStuff.pattern = true;
    }
    if (this.isValid) {
      validState = true;
    }
    if (this.isInvalid) {
      inValidState = true;
    }
    // If we don't have a valid/invalid state we need to derive it on load... basically if it's required or not. We
    // should never have a value in this state
    // todo: make sure we never have a value but no invalid/valid state -> we might need to check for this.
    if ((Object.keys(requiredStuff).length === 0 &&
      !validState &&
      !inValidState) || (!this.isRequired && !validState && !inValidState)) {
      validState = true;
    }
    if (this.isRequired && Object.keys(requiredStuff).length > 0 && !validState && !inValidState) {
      inValidState = true;
    }
    return {
      id: this.useId,
      name: this.dataSource ? this.dataSource.element.name : null,
      isInvalid: inValidState,
      isValid: validState,
      validators: requiredStuff,
      value: this.value,
      type: type,
    };
  }
  /**
   * handles Blur
   */
  handleBlur() {
    if (!this.isValidatedOnSubmission && this.updateTrigger === 'blur') {
      this.validate();
    }
  }
  /**
   * handles focus
   */
  handleFocus() {
  }
  /**
   * Brings focus to input when lu-label is clicked
   */
  handleClick() {
    if (this.dataSource) {
      this.dataSource.element.setFocus();
    }
  }
  /**
   * Handle suffix item clicked responds to suffix icon being clicked when it is clickable
   */
  handleSuffixIconClicked() {
    if (this.clearErrorStateOnClearInput) {
      this.resetInvalidState();
    }
  }
  /**
   * Overrides the valid state... used for external validation
   * @param isValid
   */
  overrideValidState(isValid) {
    if (isValid)
      this.setStateAsValid();
    if (!isValid)
      this.resetValidState();
  }
  /**
   * Overrides the valid state... used for external validation
   * @param isInvalid
   */
  overrideInvalidState(isInvalid) {
    if (isInvalid)
      this.setStateAsInvalid();
    if (!isInvalid)
      this.resetInvalidState();
  }
  /**
   * Takes care of common component did load tasks.
   */
  handleElementsCommonLoadTasks(datasource) {
    datasource.element.hasFormGroup = true;
    if (datasource.element.required === true) {
      this.isRequired = true;
    }
    if (datasource.kind === FormGroupTypes.comboBox) {
      this.forId = datasource.element.nativeInputsId;
    }
    else if (datasource.element.id) {
      this.forId = datasource.element.id.replace('-wrapper', '');
    }
  }
  /**
   * sets state properly for invalid
   */
  setStateAsInvalid() {
    this.isValid = false;
    this.isInvalid = true;
    this.dataSource.element.valid = false;
    this.dataSource.element.invalid = true;
  }
  /**
   * sets state properly for valid
   */
  setStateAsValid() {
    this.isValid = true;
    this.isInvalid = false;
    this.dataSource.element.valid = true;
    this.dataSource.element.invalid = false;
  }
  /**
   * resets state properly for invalid
   */
  resetInvalidState() {
    this.isInvalid = false;
    this.dataSource.element.invalid = false;
  }
  /**
   * resets state properly for invalid
   */
  resetValidState() {
    this.isValid = false;
    this.dataSource.element.valid = false;
  }
  /**
   * sets the state from the event
   */
  setValue(ev) {
    const isResetting = ev.detail.isResetting;
    this.value = ev && ev.detail && ev.detail.value ? ev.detail.value : null;
    if (this.updateTrigger === 'change' && !isResetting) {
      this.validate();
    }
    if (isResetting)
      this.luFormGroupDidUpdate.emit();
  }
  /**
   * 12. render() function
   * Always the last one in the class.
   */
  render() {
    return (h(Host, { class: Object.assign(Object.assign({}, createColorClasses(this.color)), getClassMap(this.cssClass)), valid: this.isValid, invalid: this.isInvalid, id: this.useId }, h("lu-label", { forId: this.forId, labelText: this.labelText, helperText: this.helperText, invalid: this.isInvalid, errorMessage: this.generatedErrorMessage, onClick: this.handleClick.bind(this), required: this.isRequired, optional: !this.needsEmailValidation ? !this.isRequired : false, useAsteriskAsRequiredIndicator: this.useAsteriskAsRequiredIndicator }, h("slot", null))));
  }
  get luFormGroupEl() { return getElement(this); }
  static get watchers() { return {
    "externallyDeemedValid": ["externallyDeemedValidChanged"],
    "externallyDeemedInvalid": ["externallyDeemedInvalidChanged"],
    "forId": ["watchHandler"]
  }; }
};
FormGroup.style = formGroupCss;

export { FormGroup as lu_form_group };

//# sourceMappingURL=lu-form-group.entry.js.map