'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

const index = require('./index-58ea899e.js');
const changeManager = require('./change-manager-a297e4d2.js');
const staticSubjectTitle = require('./static-subject-title-5829a298.js');
const component = require('./component-1e352960.js');
const globalSlimmerRegistry = require('./global-slimmer-registry-b3bce7e0.js');
const placeholder = require('./placeholder-cb6d37ad.js');
const componentUsageRuntimeMetrics = require('./component-usage-runtime-metrics-4572c5b7.js');
const eventEmitSlimmer = require('./event-emit-slimmer-80e1c8ca.js');
const childNodesEventPreventSlimmer = require('./child-nodes-event-prevent-slimmer-f3979a03.js');
const vegaEventId = require('./vega-event-id-d9994eb3.js');
const subStateNotifySlimmer = require('./sub-state-notify-slimmer-b33171b0.js');
const subStateObserverSlimmer = require('./sub-state-observer-slimmer-b8f6f27b.js');
const formFieldControllerSlimmer = require('./form-field-controller-slimmer-a07e3de0.js');
const tryGetDocument = require('./try-get-document-c0ebd39a.js');
const vegaInternalEventId = require('./vega-internal-event-id-87014e4f.js');
const domNodeSubjectObserverFactory = require('./dom-node-subject-observer-factory-9110cb94.js');
const observer = require('./observer-f49483e8.js');
const ui = require('./ui-ae4ee13d.js');
const typeGuard = require('./type-guard-2e97fc56.js');
const immutableMap = require('./immutable-map-d711339d.js');
const childNodesNotifyObserverSlimmer = require('./child-nodes-notify-observer-slimmer-2631c381.js');
const array = require('./array-249289f2.js');
require('./dynamic-slimmer-f31fdfd7.js');
require('./internal-vega-event-manager-7e0d966d.js');
require('./vega-env-manager-23b8b23c.js');
require('./feature-flag-controller-9129ef52.js');
require('./index-f054eb5d.js');
require('./string-39438062.js');
require('./misc-3d30df91.js');
require('./internal-translation-controller-8360a89c.js');
require('./index-592b4052.js');
require('./page-resize-observer-slimmer-273d62ef.js');
require('./breakpoints-1cc2c4c6.js');
require('./ui-32120990.js');
require('./breakpoints-ebde4837.js');
require('./internal-form-field-validation-rule.abstract-07cdff46.js');
require('./mutation-observer-slimmer-749d5020.js');
require('./mutation-observer-filters-38cebc6d.js');
require('./typography-4560e7f1.js');
require('./number-4816603d.js');

var __decorate$6 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
/**
 * Sync data from parent vega form
 */
class VegaFormNestStateController extends subStateObserverSlimmer.SubStateObserverSlimmer {
  // eslint-disable-next-line jsdoc/require-jsdoc
  constructor() {
    super({
      parent: 'vega-form',
      subStates: [
        {
          subStateName: 'disableBlurValidation',
          parentStateName: 'disableBlurValidation',
        },
      ],
    });
  }
}
__decorate$6([
  globalSlimmerRegistry.MapToComponentField()
], VegaFormNestStateController.prototype, "host", void 0);
__decorate$6([
  globalSlimmerRegistry.MapToComponentField({ writable: true })
], VegaFormNestStateController.prototype, "disableBlurValidation", void 0);

var __decorate$5 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
/**
 * The field error controller for vega form to set validation errors on form fields.
 */
class VegaFormFieldValidationStateController extends globalSlimmerRegistry.VegaSlimmer {
  /**
   * Set validation states for the form fields.
   *
   * @param {VegaFormFieldValidationState[]} states - An array of validation error objects.
   */
  setValidationStates(states) {
    if (states.length === 0) {
      Array.from(this.host.querySelectorAll('[data-vega-form]'))
        .filter((child) => formFieldControllerSlimmer.FormFieldControllerSlimmer.isValidFormField(child))
        .forEach((fieldHost) => {
        this.updateFieldValidationState(fieldHost, { isValid: true });
      });
      return;
    }
    states.forEach((item) => {
      const fieldHost = this.getHostByFieldName(item.fieldName);
      if (fieldHost) {
        this.updateFieldValidationState(fieldHost, {
          isValid: item.isValid,
          errorMessage: !item.isValid ? item.errorMessage : '',
        });
      }
    });
  }
  /**
   * Get the host element by field name, support nested field name with dot notation.
   *
   * @param {string} fieldName - The field name, can be nested with dot notation.
   * @returns {Nullable<FormFieldElement<unknown>>} The host element or null if not found.
   */
  getHostByFieldName(fieldName) {
    const fields = fieldName.split('.');
    let currentHost = this.host;
    for (const fieldName of fields) {
      const element = currentHost.querySelector(`[data-vega-form="${fieldName}"]`);
      if (formFieldControllerSlimmer.FormFieldControllerSlimmer.isValidFormField(element)) {
        currentHost = element;
      }
      else {
        return null;
      }
    }
    return currentHost;
  }
  /**
   * Update the validation state of a form field element.
   *
   * @param {FormFieldElement<unknown>} target - The target form field element.
   * @param {Pick<VegaFormFieldValidationState, 'isValid' | 'errorMessage'>} payload - An object containing the validation state and error message.
   */
  updateFieldValidationState(target, { isValid, errorMessage }) {
    target.isValid = isValid;
    changeManager.ChangeManager.notify(staticSubjectTitle.FIELD_ERROR_MESSAGE_CHANGE, {
      host: target,
      message: !isValid ? errorMessage : '',
      isValid: isValid,
    });
    changeManager.ChangeManager.notify(staticSubjectTitle.FORM_ELEMENT_VALIDATE, { host: target, detail: isValid });
  }
}
__decorate$5([
  globalSlimmerRegistry.MapToComponentField()
], VegaFormFieldValidationStateController.prototype, "host", void 0);
__decorate$5([
  globalSlimmerRegistry.MapToComponentMethod('setValidationStates')
], VegaFormFieldValidationStateController.prototype, "setValidationStates", null);

var __decorate$4 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
/**
 * The native form renderer for vega form to render a native HTML form element.
 */
class NativeFormRenderer extends globalSlimmerRegistry.VegaSlimmer {
  getNativeFormRef() {
    return this.nativeFormRef;
  }
  render() {
    return (index.h("form", { action: this.action, method: this.method, ref: (ref) => {
        if (ref) {
          this.nativeFormRef = ref;
        }
      } },
      index.h("slot", null)));
  }
}
__decorate$4([
  globalSlimmerRegistry.MapToComponentField()
], NativeFormRenderer.prototype, "method", void 0);
__decorate$4([
  globalSlimmerRegistry.MapToComponentField()
], NativeFormRenderer.prototype, "action", void 0);

var __decorate$3 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
/**
 * Controller responsible for handling form submission in the VegaForm component.
 */
class VegaFormSubmitController extends globalSlimmerRegistry.VegaSlimmer {
  /**
   * Component lifecycle - [connectedCallback]
   */
  connectedCallback() {
    this.registerFormSubmitChangeManager();
  }
  /**
   * Component lifecycle - [disconnectedCallback]
   */
  disconnectedCallback() {
    this.unregisterFormSubmitChangeManager();
  }
  /**
   * Submits the form using native HTML form submission with all current field values.
   *
   * This method collects all form field values, creates hidden input elements for each field,
   * appends them to a container inside the native form, and then triggers the native
   * `requestSubmit()` method to submit the form.
   *
   * The method ensures that the form data is available in the native form for submission,
   * which is useful when `useNativeForm` is enabled.
   *
   * @returns {Promise<void>} Resolves when the form submission process is complete.
   */
  async submitWithFormData() {
    if (!this.useNativeForm)
      return;
    const data = await this.host.getValue();
    for (const dataKey in data) {
      if (typeof data[dataKey] === 'object') {
        // Use bracket notation for nested form object values
        const bracketKeyMap = this.flattenObjectWithBrackets({
          [dataKey]: data[dataKey],
        });
        for (const bracketKey in bracketKeyMap) {
          const nestedHiddenInput = this.createHiddenInput(bracketKey, bracketKeyMap[bracketKey]);
          this.nativeFormRenderer.getNativeFormRef().append(nestedHiddenInput);
        }
      }
      else {
        const hiddenInput = this.createHiddenInput(dataKey, data[dataKey]);
        this.nativeFormRenderer.getNativeFormRef().append(hiddenInput);
      }
    }
    this.nativeFormRenderer.getNativeFormRef().requestSubmit();
  }
  /**
   * Creates a hidden input element with the specified name and value.
   *
   * @param {string} name - The name attribute for the hidden input.
   * @param {unknown} value - The value attribute for the hidden input.
   * @returns {HTMLInputElement} The created hidden input element.
   */
  createHiddenInput(name, value) {
    const hiddenInput = tryGetDocument.tryGetDocument().createElement('input');
    hiddenInput.type = 'hidden';
    hiddenInput.name = name;
    hiddenInput.value = typeGuard.isNonNullable(value) ? String(value) : '';
    return hiddenInput;
  }
  /**
   * Registers the form submit event observer with the ChangeManager.
   */
  registerFormSubmitChangeManager() {
    var _a;
    this.formSubmitEventObserver = new observer.Observer(this.canAcceptFormSubmitEvent.bind(this), this.handleSubmitEvents.bind(this));
    const outerForm = (_a = ui.findParent(this.host, 'vega-form', { outerMost: true })) !== null && _a !== void 0 ? _a : this.host;
    changeManager.ChangeManager.register(domNodeSubjectObserverFactory.domNodeSubjectFactory.getSubject(outerForm, vegaInternalEventId.VegaInternalFormSubmit), this.formSubmitEventObserver);
  }
  /**
   * Unregister the form submit event observer from the ChangeManager.
   */
  unregisterFormSubmitChangeManager() {
    var _a;
    const outerForm = (_a = ui.findParent(this.host, 'vega-form', { outerMost: true })) !== null && _a !== void 0 ? _a : this.host;
    changeManager.ChangeManager.unregister(domNodeSubjectObserverFactory.domNodeSubjectFactory.getSubject(outerForm, vegaInternalEventId.VegaInternalFormSubmit), this.formSubmitEventObserver);
  }
  /*
   * The below method is e2e-test covered in
   * @see{module:vega-form-field-enter-to-submit-e2e}
   */
  /* istanbul ignore next */
  /**
   * Can accept handler for FORM_SUBMIT.
   *
   * @param {FormEventsPayload} payload - The payload containing the host element that triggered the submit event.
   * @returns {boolean} True if the host element is part of the current form, false otherwise.
   */
  canAcceptFormSubmitEvent(payload) {
    return this.vegaFormFieldController.isElementInCurrentForm(payload.host);
  }
  /**
   * Handles the form submission process.
   *
   * @returns {Promise<void>} Resolves when the submission process is complete.
   */
  async handleSubmitEvents() {
    const valid = await this.host.valid();
    if (valid.isValid) {
      const formValue = await this.host.getValue();
      const submitEvent = this.submitEventEmitter.emit(formValue);
      if (!submitEvent.defaultPrevented) {
        await this.submitWithFormData();
      }
    }
  }
  /**
   * Flattens a nested object into a single-level object with bracket notation for keys.
   *
   * @param {Record<string, unknown>} data - The nested object to be flattened.
   * @param {string} [parentKey=''] - The prefix for the keys in the flattened object.
   * @param {Record<string, unknown>} [out={}] - The output object that accumulates the flattened key-value pairs.
   * @returns {Record<string, unknown>} The flattened object with bracket notation keys.
   */
  flattenObjectWithBrackets(data, parentKey = '', out = {}) {
    Object.entries(data).forEach(([key, value]) => {
      const currentKey = parentKey ? `${parentKey}[${key}]` : key;
      if (Array.isArray(value)) {
        // Recursively handle array items using index as key
        value.forEach((item, index) => {
          const arrayKey = `${currentKey}[${index}]`;
          if (typeof item === 'object' && item !== null) {
            // Recursively flatten objects inside the array
            this.flattenObjectWithBrackets(item, arrayKey, out);
          }
          else {
            out[arrayKey] = item;
          }
        });
      }
      else if (typeGuard.isNonNullable(value) && typeof value === 'object') {
        this.flattenObjectWithBrackets(value, currentKey, out);
      }
      else {
        out[currentKey] = value;
      }
    });
    return out;
  }
}
__decorate$3([
  globalSlimmerRegistry.MapToComponentField()
], VegaFormSubmitController.prototype, "host", void 0);
__decorate$3([
  globalSlimmerRegistry.MapToComponentField()
], VegaFormSubmitController.prototype, "useNativeForm", void 0);
__decorate$3([
  globalSlimmerRegistry.MapToComponentField()
], VegaFormSubmitController.prototype, "nativeFormRenderer", void 0);
__decorate$3([
  globalSlimmerRegistry.MapToComponentField()
], VegaFormSubmitController.prototype, "submitEventEmitter", void 0);
__decorate$3([
  globalSlimmerRegistry.MapToComponentField()
], VegaFormSubmitController.prototype, "vegaFormFieldController", void 0);
__decorate$3([
  globalSlimmerRegistry.MapToComponentMethod('connectedCallback')
], VegaFormSubmitController.prototype, "connectedCallback", null);
__decorate$3([
  globalSlimmerRegistry.MapToComponentMethod('disconnectedCallback')
], VegaFormSubmitController.prototype, "disconnectedCallback", null);

var __decorate$2 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
/**
 * The form field controller for vega form to manage the form field states.
 */
class VegaFormFieldController extends globalSlimmerRegistry.VegaSlimmer {
  constructor() {
    super(...arguments);
    this.childNotifyObserver = new childNodesNotifyObserverSlimmer.ChildNodesNotifyObserverSlimmer(staticSubjectTitle.FORM_ELEMENT_VALIDATE, (input) => this.updateInternalValidStatus(input));
    this.childNodeValueChangeObserver = new childNodesNotifyObserverSlimmer.ChildNodesNotifyObserverSlimmer(staticSubjectTitle.FORM_ELEMENT_VALUE_CHANGE, () => {
      this.isTouched = true;
    });
    this._invalidFieldPathMap = new immutableMap.ImmutableMap(new Map(), (newMap) => {
      this._invalidFieldPathMap = newMap;
      this.updateIsValidFlag();
    });
    /**
     * The form field element pending async valid map
     */
    this._pendingValidFieldPathMap = new immutableMap.ImmutableMap(new Map(), (newMap) => {
      this._pendingValidFieldPathMap = newMap;
      this.updateIsValidFlag();
    });
    /**
     * If the element is valid, remove it from the set of
     *    invalid elements. If the element is invalid,
     *    add it to the set of invalid elements.
     *
     * @param {NotifyObserverPayload<boolean>} payload - CustomEvent<boolean> the vegaValidate subject notify from child elements
     */
    this.updateInternalValidStatus = (payload) => {
      if (payload.host !== this.host) {
        const target = payload.host;
        const isElementValid = payload.detail;
        if (formFieldControllerSlimmer.FormFieldControllerSlimmer.isValidFormField(target) &&
          this.shouldVisitElement(target, false, false)) {
          if (isElementValid) {
            this.invalidFieldPathMap.delete(target);
          }
          else {
            this.invalidFieldPathMap.set(target, target.dataset['vegaForm']);
          }
        }
      }
    };
  }
  /**
   * Component lifecycle - [connectedCallback]
   */
  connectedCallback() {
    this.initFormFieldDisconnectedObserver();
    this.registerFormFieldPendingValid();
  }
  /**
   * When the vegaForm is deleted, it is necessary to notify the parent's vegaForm to update its isValid status.
   */
  disconnectedCallback() {
    changeManager.ChangeManager.notify(staticSubjectTitle.FORM_FIELD_ELEMENT_DISCONNECTED, { host: this.host });
    changeManager.ChangeManager.unregister(staticSubjectTitle.FORM_FIELD_ELEMENT_DISCONNECTED, this.formFieldDisconnectedObserver);
    changeManager.ChangeManager.unregister(staticSubjectTitle.FORM_FIELD_PENDING_VALID_CHANGE, this.formFieldPendingValidObserver);
  }
  /**
   * @inheritDoc
   */
  async getValue(option) {
    const result = {};
    await this.navigateVegaFormChildren(async (element, isForm) => {
      const formFieldName = this.getFormFieldName(element);
      if (isForm) {
        result[formFieldName] = await element.getValue(option);
      }
      else {
        result[formFieldName] = this.getFormFieldValue(element);
      }
    }, option);
    return (array.isObjectArrayLike(result) ? Object.values(result) : result);
  }
  /**
   * @inheritDoc
   */
  async setValue(value, option) {
    if (value) {
      await this.navigateVegaFormChildren(async (element, isForm) => {
        const formFieldName = this.getFormFieldName(element);
        if (isForm) {
          await element.setValue(value[formFieldName], option);
        }
        else {
          await element.componentOnReady(); // Link issue https://gethired.atlassian.net/browse/GHUI-385
          if (value[formFieldName] !== undefined) {
            // If element have setValue method, we will directly call this method, otherwise we set the value to value property.
            typeof element['setValue'] === 'function'
              ? await element['setValue'](value[formFieldName])
              : (element['value'] = value[formFieldName]);
          }
        }
      }, option);
      this.isTouched = false;
    }
  }
  /**
   * @inheritDoc
   */
  async valid(showError = true) {
    const result = { isValid: true, invalidFields: [] };
    await this.navigateVegaFormChildren(async (element, isForm) => {
      if (typeof element['valid'] === 'function' && isForm) {
        const nestedFormValidationResult = await element.valid(showError);
        if (!nestedFormValidationResult.isValid) {
          result.isValid = false;
          result.invalidFields.push(...nestedFormValidationResult.invalidFields);
          result.invalidFieldsErrorMessages = Object.assign(Object.assign({}, result.invalidFieldsErrorMessages), nestedFormValidationResult.invalidFieldsErrorMessages);
        }
      }
      else {
        const { isValid, message } = await this.handleChildFormFieldElementValid(element, showError);
        if (!isValid) {
          result.isValid = false;
          result.invalidFields.push(this.getFormFieldName(element));
          if (!result.invalidFieldsErrorMessages) {
            result.invalidFieldsErrorMessages = {};
          }
          result.invalidFieldsErrorMessages[this.getFormFieldName(element)] = message;
        }
      }
    });
    return result;
  }
  /**
   * The getter for the {@link _invalidFieldPathMap}
   *
   * @returns {ImmutableMap<HTMLElement, string>} The map of invalid field elements and their paths
   */
  get invalidFieldPathMap() {
    return this._invalidFieldPathMap;
  }
  /**
   * The getter for the {@link _pendingValidFieldPathMap}
   *
   * @returns {ImmutableMap<HTMLElement, string>} The map of pending valid field elements and their paths
   */
  get pendingValidFieldPathMap() {
    return this._pendingValidFieldPathMap;
  }
  /**
   * Set the isTouched property of the form.
   *
   * @param {boolean} isTouched - The new value for isTouched.
   */
  setIsTouched(isTouched) {
    this.isTouched = isTouched;
  }
  /**
   * It returns the value of data-vega-form that the given element is associated with.
   *
   * @param {HTMLElement} element - The element that is being validated.
   * @returns {string} The name of the field.
   */
  getFormFieldName(element) {
    return element.dataset['vegaForm'];
  }
  /**
   * Check if the given element is part of the current form.
   *
   * @param {HTMLElement} element - The element to check.
   * @returns {boolean} True if the element is part of the current form, false otherwise.
   */
  isElementInCurrentForm(element) {
    return this.invalidFieldPathMap.has(element) || ui.isParent(element, this.host);
  }
  /**
   * Navigate the immediate child node under current vega form element with the following strategy
   *  - if a matched vega field element found, will pass it to the visitor method passed in
   *  - if a non-matched node found, it will call itself recursively and pass the node as the second parameter
   * Once the navigation is finished, it will wait for all the pending visitor/self-invocation promise finished before return
   *
   * @param  {(element: HTMLElement, isForm: boolean) => Promise<void>} visitor async callback method that will be invoked if a matched vega field element found
   * @param {FormControlOption} [option] form control option to skip disabled/invisible components
   * @param {HTMLElement} [startElementNode=this.host] the element to start the navigation, default to current vega form host
   * @returns {Promise<void>} return void wrapped with promise to notify the navigation is done
   */
  async navigateVegaFormChildren(visitor, option, startElementNode = this.host) {
    const promiseQueue = [];
    Array.from(startElementNode.children).forEach((child) => {
      if (formFieldControllerSlimmer.FormFieldControllerSlimmer.isValidFormField(child)) {
        if (this.shouldVisitElement(child, option === null || option === void 0 ? void 0 : option.skipDisabled, option === null || option === void 0 ? void 0 : option.skipInvisible)) {
          promiseQueue.push(visitor(child, child.tagName === 'VEGA-FORM'));
        }
      }
      else {
        promiseQueue.push(this.navigateVegaFormChildren(visitor, option, child));
      }
    });
    await Promise.all(promiseQueue);
  }
  /**
   * Update the {@link isValid} property value based on the size of {@link invalidFieldPathMap}
   * If the number of invalid elements is zero, then the form is valid.
   */
  updateIsValidFlag() {
    this.isValid = this.pendingValidFieldPathMap.size > 0 ? null : this.invalidFieldPathMap.size === 0;
  }
  /**
   * Registers an observer with the ChangeManager that will be notified when a form field's pending validation state changes.
   */
  registerFormFieldPendingValid() {
    this.formFieldPendingValidObserver = new observer.Observer(this.canAcceptFormFieldPendingValid.bind(this), this.handleFieldPendingValid.bind(this));
    changeManager.ChangeManager.register(staticSubjectTitle.FORM_FIELD_PENDING_VALID_CHANGE, this.formFieldPendingValidObserver);
  }
  /**
   * Can accept handler for FORM_FIELD_PENDING_VALID_CHANGE.
   *
   * @param {PendingValidPayload} payload - The payload containing the host element that triggered the pending valid change event.
   * @returns {boolean} True if the host element is part of the current form, false otherwise.
   */
  canAcceptFormFieldPendingValid(payload) {
    return this.isElementInCurrentForm(payload.host);
  }
  /**
   * Handles the pending valid state change for a form field.
   *
   * @param {PendingValidPayload} payload - The payload containing the host element and its pending valid state.
   */
  handleFieldPendingValid(payload) {
    if (typeof payload.detail === 'boolean') {
      this.pendingValidFieldPathMap.delete(payload.host);
    }
    else {
      this.pendingValidFieldPathMap.set(payload.host, payload.host.dataset['vegaForm']);
    }
  }
  /**
   * This function registers an observer with the ChangeManager that will be notified when an element
   * delete operation is triggered
   */
  initFormFieldDisconnectedObserver() {
    this.formFieldDisconnectedObserver = new observer.Observer(this.canAcceptFormFieldDisconnectedOperation.bind(this), this.updateInvalidFieldPath.bind(this));
    changeManager.ChangeManager.register(staticSubjectTitle.FORM_FIELD_ELEMENT_DISCONNECTED, this.formFieldDisconnectedObserver);
  }
  /**
   * If the deleted element is a child or grandchild of current vegaForm, the isValid of all these vegaForms will be updated.
   *
   * @param {DisconnectedElementOperationPayload} payload -  the delete element and vegaForm array.
   * @returns {boolean} A boolean value.
   */
  canAcceptFormFieldDisconnectedOperation(payload) {
    return this.invalidFieldPathMap.has(payload.host);
  }
  /**
   * Get the fieldName of the deleted element in the current vegaForm, delete it from the invalidFieldPathSet array, and update isValid at the same time.
   *
   * @param {DisconnectedElementOperationPayload} payload - the delete element and vegaForm array.
   */
  async updateInvalidFieldPath(payload) {
    this.invalidFieldPathMap.delete(payload.host);
    this.pendingValidFieldPathMap.delete(payload.host);
  }
  /**
   * Return true if the HTMLElement has data-vega-form property, and it's not disabled and not invisible if these two properties have to be checked.
   *
   * @param {HTMLElement} element - The HTMLElement to check.
   * @param {boolean} skipDisabled - If true, then disabled form fields will be skipped.
   * @param {boolean} skipInvisible - If true, only visible elements will be visited.
   * @returns {boolean} a boolean value.
   */
  shouldVisitElement(element, skipDisabled, skipInvisible) {
    return (this.getFormFieldName(element) &&
      (!skipDisabled || !element['disabled']) &&
      (!skipInvisible || ui.isElementVisible(element)));
  }
  /**
   * It retrieves the value of a form field element.
   *
   * @param {HTMLElement} element - The form field element.
   * @returns {unknown} The value of the form field element.
   */
  getFormFieldValue(element) {
    return typeof element['value'] === 'undefined'
      ? // use element.getAttribute since the value property is not available in unit testing
        element.getAttribute('value')
      : element['value'];
  }
  /**
   * It handles the validation of a child form field element.
   *
   * @param {HTMLElement} element - The form field element to validate.
   * @param {boolean | 'rule'} showError - Whether to show error messages.
   * @returns {Promise<EvaluateResultBase>} The validation result.
   */
  async handleChildFormFieldElementValid(element, showError) {
    const subject = domNodeSubjectObserverFactory.domNodeSubjectFactory.getSubject(element, vegaInternalEventId.VegaInternalValid);
    const { isValid, message } = await new Promise((resolve) => {
      //This setTimeout method here to avoid the dom node subject observer not existing and blocks the promise status
      const timerId = setTimeout(() => {
        resolve({ isValid: true, message: '' });
      }, 2000);
      changeManager.ChangeManager.notify(subject, {
        host: element,
        message: showError,
        promiseResolve: resolve,
        timerId,
      });
    });
    return { isValid, message };
  }
}
__decorate$2([
  globalSlimmerRegistry.MapToComponentField()
], VegaFormFieldController.prototype, "host", void 0);
__decorate$2([
  globalSlimmerRegistry.MapToComponentField({ writable: true })
], VegaFormFieldController.prototype, "isValid", void 0);
__decorate$2([
  globalSlimmerRegistry.MapToComponentField({ writable: true })
], VegaFormFieldController.prototype, "isTouched", void 0);
__decorate$2([
  globalSlimmerRegistry.InjectVegaSlimmer()
], VegaFormFieldController.prototype, "childNotifyObserver", void 0);
__decorate$2([
  globalSlimmerRegistry.InjectVegaSlimmer()
], VegaFormFieldController.prototype, "childNodeValueChangeObserver", void 0);
__decorate$2([
  globalSlimmerRegistry.MapToComponentMethod('connectedCallback')
], VegaFormFieldController.prototype, "connectedCallback", null);
__decorate$2([
  globalSlimmerRegistry.MapToComponentMethod('disconnectedCallback')
], VegaFormFieldController.prototype, "disconnectedCallback", null);
__decorate$2([
  globalSlimmerRegistry.MapToComponentMethod('getValue')
], VegaFormFieldController.prototype, "getValue", null);
__decorate$2([
  globalSlimmerRegistry.MapToComponentMethod('setValue')
], VegaFormFieldController.prototype, "setValue", null);
__decorate$2([
  globalSlimmerRegistry.MapToComponentMethod('valid')
], VegaFormFieldController.prototype, "valid", null);

var __decorate$1 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
/**
 * Reset controller for handling form reset events in the VegaForm component.
 */
class VegaFormResetController extends globalSlimmerRegistry.VegaSlimmer {
  /**
   * Component lifecycle - [connectedCallback]
   */
  connectedCallback() {
    this.registerFormResetChangeManager();
  }
  /**
   * Component lifecycle - [disconnectedCallback]
   */
  disconnectedCallback() {
    this.unregisterFormResetChangeManager();
  }
  /**
   * @inheritDoc
   */
  async reset(defaultValueMap = {}, option) {
    await this.vegaFormFieldController.navigateVegaFormChildren(async (element, isForm) => {
      const formFieldName = this.vegaFormFieldController.getFormFieldName(element);
      if (isForm) {
        await element.reset(defaultValueMap[formFieldName] || {}, option);
      }
    }, option);
    changeManager.ChangeManager.notify(staticSubjectTitle.FORM_RESET_OPERATION_TRIGGERED, {
      host: this.host,
      defaultValueMap,
      option,
    });
    this.vegaFormFieldController.setIsTouched(false);
  }
  /**
   * Registers the form reset event observer with the ChangeManager.
   */
  registerFormResetChangeManager() {
    var _a;
    const outerForm = (_a = ui.findParent(this.host, 'vega-form', { outerMost: true })) !== null && _a !== void 0 ? _a : this.host;
    this.formResetEventObserver = new observer.Observer(this.canAcceptFormResetEvent.bind(this), this.handleResetEvents.bind(this));
    changeManager.ChangeManager.register(domNodeSubjectObserverFactory.domNodeSubjectFactory.getSubject(outerForm, vegaInternalEventId.VegaInternalFormReset), this.formResetEventObserver);
  }
  /**
   * Unregister the form reset event observer from the ChangeManager.
   */
  unregisterFormResetChangeManager() {
    var _a;
    const outerForm = (_a = ui.findParent(this.host, 'vega-form', { outerMost: true })) !== null && _a !== void 0 ? _a : this.host;
    changeManager.ChangeManager.unregister(domNodeSubjectObserverFactory.domNodeSubjectFactory.getSubject(outerForm, vegaInternalEventId.VegaInternalFormReset), this.formResetEventObserver);
  }
  /**
   * Can accept form reset event.
   *
   * @param {FormEventsPayload} payload - The form events payload.
   * @returns {boolean} True if the event can be accepted, false otherwise.
   */
  canAcceptFormResetEvent(payload) {
    return this.vegaFormFieldController.isElementInCurrentForm(payload.host);
  }
  /**
   * Handles reset events by resetting the form and emitting a reset event.
   */
  async handleResetEvents() {
    await this.host.reset();
    this.resetEventEmitter.emit();
  }
}
__decorate$1([
  globalSlimmerRegistry.MapToComponentField()
], VegaFormResetController.prototype, "host", void 0);
__decorate$1([
  globalSlimmerRegistry.MapToComponentField()
], VegaFormResetController.prototype, "vegaFormFieldController", void 0);
__decorate$1([
  globalSlimmerRegistry.MapToComponentField()
], VegaFormResetController.prototype, "resetEventEmitter", void 0);
__decorate$1([
  globalSlimmerRegistry.MapToComponentMethod('connectedCallback')
], VegaFormResetController.prototype, "connectedCallback", null);
__decorate$1([
  globalSlimmerRegistry.MapToComponentMethod('disconnectedCallback')
], VegaFormResetController.prototype, "disconnectedCallback", null);
__decorate$1([
  globalSlimmerRegistry.MapToComponentMethod('reset')
], VegaFormResetController.prototype, "reset", null);

const vegaFormCss = ":host{display:block}";

var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
    r = Reflect.decorate(decorators, target, key, desc);
  else
    for (var i = decorators.length - 1; i >= 0; i--)
      if (d = decorators[i])
        r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const VegaForm = class {
  constructor(hostRef) {
    index.registerInstance(this, hostRef);
    this.vegaValidate = index.createEvent(this, "vegaValidate", 7);
    this.validate = index.createEvent(this, "validate", 7);
    this.vegaFormSubmit = index.createEvent(this, "vegaFormSubmit", 7);
    this.formSubmit = index.createEvent(this, "formSubmit", 7);
    this.vegaFormReset = index.createEvent(this, "vegaFormReset", 7);
    this.formReset = index.createEvent(this, "formReset", 7);
    this.globalSlimmers = {};
    this.submitEventEmitter = eventEmitSlimmer.createEventEmitSlimmer(VegaForm, vegaEventId.VegaFormSubmit);
    this.resetEventEmitter = eventEmitSlimmer.createEventEmitSlimmer(VegaForm, vegaEventId.VegaFormReset);
    this.validateEventEmitter = eventEmitSlimmer.createEventEmitSlimmer(VegaForm, vegaEventId.VegaValidate);
    this.disableBlurValidationNotifySlimmer = subStateNotifySlimmer.createSubStateNotifySlimmer(VegaForm, 'disableBlurValidation', 'watchDisableBlurValidation');
    this.stateController = new VegaFormNestStateController();
    this.childEventPrevent = new childNodesEventPreventSlimmer.ChildNodesEventPreventSlimmer([vegaEventId.VegaFormSubmit, vegaEventId.VegaFormReset], () => this.host.querySelector('vega-form'), {
      customPreventHandle: (e) => {
        e.stopPropagation();
      },
    });
    this.childFormValidateEventPrevent = new childNodesEventPreventSlimmer.ChildNodesEventPreventSlimmer([vegaEventId.VegaValidate], () => this.host, {
      customPreventHandle: (e) => {
        e.stopPropagation();
      },
    });
    this.vegaComponentUsageRuntimeMetricsSlimmer = new componentUsageRuntimeMetrics.VegaComponentUsageRuntimeMetricsSlimmer();
    this.vegaFormFieldValidationStateController = new VegaFormFieldValidationStateController();
    this.nativeFormRenderer = new NativeFormRenderer();
    this.vegaFormSubmitController = new VegaFormSubmitController();
    this.vegaFormResetController = new VegaFormResetController();
    this.vegaFormFieldController = new VegaFormFieldController();
    /**
     * Indicates whether the current form-controlled elements are valid.
     *
     * Form-controlled elements are considered for validation if they
     *    have the `data-vega-form` property.
     *
     * Disabled and invisible elements are excluded from validation.
     *
     * If the value is `undefined`, it means there are no
     *    form-controlled elements that can be validated.
     *
     * **Additional Notes:**
     *   1. When depending on `isValid` for form validation, it is advised
     *      not to modify the following properties of the monitored DOM:
     *      - `disabled` property
     *      - Element visibility style
     *   2. As this property relies heavily on the `VegaValidate` event emitted,
     *      it is highly recommended to enable auto-validation for all
     *      form-controlled elements to ensure that the value reflects
     *      the most up-to-date form validation status.
     *
     * @vegaVersion 1.3.0
     */
    /* eslint-disable-next-line @stencil/strict-mutable */
    this.isValid = null;
    /**
     * Indicates whether the value of any current
     *    form-controlled elements has been changed.
     *
     *   1. When the value of any form-controlled element is changed,
     *      this parameter is set to `true`.
     *   2. When resetting the form, this parameter is set to `false`.
     *   3. When invoking the `setValue` method, this parameter is set to `false`.
     *
     * @vegaVersion 1.3.0
     */
    /* eslint-disable-next-line @stencil/strict-mutable */
    this.isTouched = false;
    /**
     * Specifies whether form validation should be disabled on blur events of form elements.
     *
     *  - This helps prevent validation on blur when clicking Submit inside an input,
     *        avoiding error messages that shift the button and block the click.
     *  - For nested forms, the parent form will override this property
     *        to ensure consistent validation behavior.
     *
     * @vegaVersion 2.47.0
     */
    /* eslint-disable-next-line @stencil/strict-mutable */
    this.disableBlurValidation = false;
    /**
     * Determines whether the `vega-form` content is wrapped in a native HTML <form> element.
     *
     * @vegaVersion 2.64.0
     */
    this.useNativeForm = false;
    /**
     * Specifies the HTTP method used for form submission.
     *   This property takes effect only when {@link useNativeForm} is set to `true`.
     *
     * @vegaVersion 2.64.0
     */
    this.method = 'get';
  }
  watchIsValid() {
    this.validateEventEmitter.emit(this.isValid);
    changeManager.ChangeManager.notify(staticSubjectTitle.FORM_ELEMENT_VALIDATE, { host: this.host, detail: this.isValid });
  }
  watchDisableBlurValidation() {
  }
  /**
   * Invoke this method asynchronously to retrieve the validation result for
   *    all the vega field elements nested within the `vega-form`.
   *
   * If an element is a `vega-form` itself, it will recursively
   *    invoke its `valid()` method.
   *
   * @param {boolean | 'rule'} showError determine whether the validation result should be reflected in UI
   * @return {Promise<FormValidateResult> } validation result
   * @vegaVersion 1.3.0
   */
  async valid(showError = true) {
    return placeholder.methodPlaceholder(showError);
  }
  /**
   * Invoke this method asynchronously to retrieve the values for
   *    all the available vega field elements nested within the `vega-form`.
   *
   * @param {FormControlOption} [option] form control option to skip disabled/invisible components
   * @return {Promise<T>} object with key and field value as key-value pair
   * @vegaVersion 1.3.0
   */
  async getValue(option) {
    return placeholder.methodPlaceholder(option);
  }
  /**
   * Invoke this method to prefill the `vega-form` with the given value.
   *
   * This action will also set the `isTouched` property to `false`.
   *
   * @param value to prefill into the vega-form
   * @param {FormControlOption} [option] form control option to skip disabled/invisible components
   * @vegaVersion 1.3.0
   */
  async setValue(value, option) {
  }
  /**
   * Invoke this method to reset the vega field elements in the form to
   *    the default value provided, or an empty string if
   *    no default value is found.
   *
   * @param defaultValueMap map of the vega form field name to default value
   * @param {FormControlOption} [option] form control option to skip disabled/invisible components
   *
   * @vegaVersion 1.3.0
   */
  async reset(defaultValueMap = {}, option) {
  }
  /**
   * Invoke this method to set validation states on specific form fields.
   *
   * @param {VegaFormFieldValidationState[]} states - An array of validation error objects.
   *
   * @vegaVersion 2.59.0
   */
  async setValidationStates(states) {
  }
  render() {
    return component.sanitizeVegaComponent(index.h(index.Host, null, this.useNativeForm ? this.nativeFormRenderer.render() : index.h("slot", null)), this.host);
  }
  get host() { return index.getElement(this); }
  static get watchers() { return {
    "isValid": ["watchIsValid"],
    "disableBlurValidation": ["watchDisableBlurValidation"]
  }; }
};
__decorate([
  componentUsageRuntimeMetrics.InjectVegaGlobalSlimmer()
], VegaForm.prototype, "globalSlimmers", void 0);
__decorate([
  globalSlimmerRegistry.InjectVegaSlimmer()
], VegaForm.prototype, "submitEventEmitter", void 0);
__decorate([
  globalSlimmerRegistry.InjectVegaSlimmer()
], VegaForm.prototype, "resetEventEmitter", void 0);
__decorate([
  globalSlimmerRegistry.InjectVegaSlimmer()
], VegaForm.prototype, "validateEventEmitter", void 0);
__decorate([
  globalSlimmerRegistry.InjectVegaSlimmer()
], VegaForm.prototype, "disableBlurValidationNotifySlimmer", void 0);
__decorate([
  globalSlimmerRegistry.InjectVegaSlimmer()
], VegaForm.prototype, "stateController", void 0);
__decorate([
  globalSlimmerRegistry.InjectVegaSlimmer()
], VegaForm.prototype, "childEventPrevent", void 0);
__decorate([
  globalSlimmerRegistry.InjectVegaSlimmer()
], VegaForm.prototype, "childFormValidateEventPrevent", void 0);
__decorate([
  globalSlimmerRegistry.InjectVegaSlimmer()
], VegaForm.prototype, "vegaComponentUsageRuntimeMetricsSlimmer", void 0);
__decorate([
  globalSlimmerRegistry.InjectVegaSlimmer()
], VegaForm.prototype, "vegaFormFieldValidationStateController", void 0);
__decorate([
  globalSlimmerRegistry.InjectVegaSlimmer()
], VegaForm.prototype, "nativeFormRenderer", void 0);
__decorate([
  globalSlimmerRegistry.InjectVegaSlimmer()
], VegaForm.prototype, "vegaFormSubmitController", void 0);
__decorate([
  globalSlimmerRegistry.InjectVegaSlimmer()
], VegaForm.prototype, "vegaFormResetController", void 0);
__decorate([
  globalSlimmerRegistry.InjectVegaSlimmer()
], VegaForm.prototype, "vegaFormFieldController", void 0);
VegaForm.style = vegaFormCss;

exports.vega_form = VegaForm;
