var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) {
  function adopt(value) {
    return value instanceof P ? value : new P(function (resolve) {
      resolve(value);
    });
  }
  return new (P || (P = Promise))(function (resolve, reject) {
    function fulfilled(value) {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    }
    function rejected(value) {
      try {
        step(generator["throw"](value));
      } catch (e) {
        reject(e);
      }
    }
    function step(result) {
      result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
    }
    step((generator = generator.apply(thisArg, _arguments || [])).next());
  });
};
import { h, defineComponent, provide, ref } from 'vue';
import { useConfig, useTheme } from "../../_mixins/index.mjs";
import { formLight } from "../styles/index.mjs";
import style from "./styles/form.cssr.mjs";
import { keysOf } from "../../_utils/index.mjs";
import { formInjectionKey, formItemInstsInjectionKey } from "./context.mjs";
export const formProps = Object.assign(Object.assign({}, useTheme.props), {
  inline: Boolean,
  labelWidth: [Number, String],
  labelAlign: String,
  labelPlacement: {
    type: String,
    default: 'top'
  },
  model: {
    type: Object,
    default: () => {}
  },
  rules: Object,
  disabled: Boolean,
  size: String,
  showRequireMark: {
    type: Boolean,
    default: undefined
  },
  requireMarkPlacement: String,
  showFeedback: {
    type: Boolean,
    default: true
  },
  onSubmit: {
    type: Function,
    default: e => {
      e.preventDefault();
    }
  },
  showLabel: {
    type: Boolean,
    default: undefined
  },
  validateMessages: Object
});
export default defineComponent({
  name: 'Form',
  props: formProps,
  setup(props) {
    const {
      mergedClsPrefixRef
    } = useConfig(props);
    useTheme('Form', '-form', style, formLight, props, mergedClsPrefixRef);
    // from path to form-item
    const formItems = {};
    // for label-width = 'auto'
    const maxChildLabelWidthRef = ref(undefined);
    const deriveMaxChildLabelWidth = currentWidth => {
      const currentMaxChildLabelWidth = maxChildLabelWidthRef.value;
      if (currentMaxChildLabelWidth === undefined || currentWidth >= currentMaxChildLabelWidth) {
        maxChildLabelWidthRef.value = currentWidth;
      }
    };
    function validate(validateCallback, shouldRuleBeApplied = () => true) {
      return __awaiter(this, void 0, void 0, function* () {
        yield new Promise((resolve, reject) => {
          const formItemValidationPromises = [];
          for (const key of keysOf(formItems)) {
            const formItemInstances = formItems[key];
            for (const formItemInstance of formItemInstances) {
              if (formItemInstance.path) {
                formItemValidationPromises.push(formItemInstance.internalValidate(null, shouldRuleBeApplied));
              }
            }
          }
          void Promise.all(formItemValidationPromises).then(results => {
            const formInvalid = results.some(result => !result.valid);
            const errors = results.filter(result => {
              var _a;
              return (_a = result.errors) === null || _a === void 0 ? void 0 : _a.length;
            }).map(result => result.errors);
            const warnings = results.filter(result => {
              var _a;
              return (_a = result.warnings) === null || _a === void 0 ? void 0 : _a.length;
            }).map(result => result.warnings);
            if (validateCallback) {
              validateCallback((errors === null || errors === void 0 ? void 0 : errors.length) ? errors : undefined, {
                warnings: (warnings === null || warnings === void 0 ? void 0 : warnings.length) ? warnings : undefined
              });
            } else {
              formInvalid ? reject(errors) : resolve();
            }
          });
        });
      });
    }
    function restoreValidation() {
      for (const key of keysOf(formItems)) {
        const formItemInstances = formItems[key];
        for (const formItemInstance of formItemInstances) {
          formItemInstance.restoreValidation();
        }
      }
    }
    provide(formInjectionKey, {
      props,
      maxChildLabelWidthRef,
      deriveMaxChildLabelWidth
    });
    provide(formItemInstsInjectionKey, {
      formItems
    });
    const formExposedMethod = {
      validate,
      restoreValidation
    };
    return Object.assign(formExposedMethod, {
      mergedClsPrefix: mergedClsPrefixRef
    });
  },
  render() {
    const {
      mergedClsPrefix
    } = this;
    return h("form", {
      class: [`${mergedClsPrefix}-form`, this.inline && `${mergedClsPrefix}-form--inline`],
      onSubmit: this.onSubmit
    }, this.$slots);
  }
});