UNPKG

@chl1860/dynamic-form-vue3

Version:

Vue3 + TypeScript + Ant Design Vue 动态表单组件

1,788 lines 71.5 kB
var __defProp = Object.defineProperty;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var prop of __getOwnPropSymbols(b)) {
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
var __async = (__this, __arguments, generator) => {
  return new Promise((resolve, reject) => {
    var fulfilled = (value) => {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    };
    var rejected = (value) => {
      try {
        step(generator.throw(value));
      } catch (e) {
        reject(e);
      }
    };
    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
    step((generator = generator.apply(__this, __arguments)).next());
  });
};
import { reactive, ref, markRaw, computed, watch, nextTick, defineComponent, resolveComponent, createBlock, openBlock, inject, withCtx, createElementBlock, Fragment, renderList, createTextVNode, toDisplayString, normalizeClass, createCommentVNode, createElementVNode, normalizeStyle, createVNode, unref, resolveDynamicComponent, mergeProps, toHandlers, provide, onMounted, createSlots, withDirectives, vModelText } from "vue";
import { QuestionCircleOutlined, ExclamationCircleOutlined, DownOutlined } from "@ant-design/icons-vue";
function getByPath(obj, path) {
  if (!obj || !path) return void 0;
  const keys = path.split(".");
  let current = obj;
  for (const key of keys) {
    if (current == null || typeof current !== "object") {
      return void 0;
    }
    current = current[key];
  }
  return current;
}
function setByPath(obj, path, value) {
  if (!obj || !path) return;
  const keys = path.split(".");
  let current = obj;
  for (let i = 0; i < keys.length - 1; i++) {
    const key = keys[i];
    if (!(key in current) || typeof current[key] !== "object") {
      current[key] = {};
    }
    current = current[key];
  }
  const lastKey = keys[keys.length - 1];
  current[lastKey] = value;
}
function deleteByPath(obj, path) {
  if (!obj || !path) return;
  const keys = path.split(".");
  let current = obj;
  for (let i = 0; i < keys.length - 1; i++) {
    const key = keys[i];
    if (!(key in current) || typeof current[key] !== "object") {
      return;
    }
    current = current[key];
  }
  const lastKey = keys[keys.length - 1];
  delete current[lastKey];
}
function hasPath(obj, path) {
  return getByPath(obj, path) !== void 0;
}
function getAllPaths(obj, prefix = "") {
  const result = {};
  if (obj == null || typeof obj !== "object") {
    return result;
  }
  for (const key in obj) {
    const value = obj[key];
    const fullPath = prefix ? `${prefix}.${key}` : key;
    if (value && typeof value === "object" && !Array.isArray(value)) {
      Object.assign(result, getAllPaths(value, fullPath));
    } else {
      result[fullPath] = value;
    }
  }
  return result;
}
const globalComponents = reactive(/* @__PURE__ */ new Map());
const globalComponentsVersion = ref(0);
function createComponentRegistry() {
  const components = reactive(/* @__PURE__ */ new Map());
  const localVersion = ref(0);
  return {
    register(type, component) {
      components.set(type, markRaw(component));
      localVersion.value++;
    },
    get(type) {
      localVersion.value;
      globalComponentsVersion.value;
      return components.get(type) || globalComponents.get(type);
    },
    has(type) {
      localVersion.value;
      globalComponentsVersion.value;
      return components.has(type) || globalComponents.has(type);
    },
    unregister(type) {
      components.delete(type);
      localVersion.value++;
    },
    clear() {
      components.clear();
      localVersion.value++;
    },
    getAll() {
      localVersion.value;
      globalComponentsVersion.value;
      const allComponents = {};
      globalComponents.forEach((component, type) => {
        allComponents[type] = component;
      });
      components.forEach((component, type) => {
        allComponents[type] = component;
      });
      return allComponents;
    }
  };
}
const globalComponentRegistry = {
  /**
   * 注册全局自定义字段组件
   * @param type 字段类型
   * @param component Vue 组件
   */
  register(type, component) {
    globalComponents.set(type, markRaw(component));
    globalComponentsVersion.value++;
  },
  /**
   * 获取全局注册的组件
   * @param type 字段类型
   */
  get(type) {
    globalComponentsVersion.value;
    return globalComponents.get(type);
  },
  /**
   * 检查是否存在指定类型的组件
   * @param type 字段类型
   */
  has(type) {
    globalComponentsVersion.value;
    return globalComponents.has(type);
  },
  /**
   * 取消注册全局组件
   * @param type 字段类型
   */
  unregister(type) {
    globalComponents.delete(type);
    globalComponentsVersion.value++;
  },
  /**
   * 清空所有全局组件
   */
  clear() {
    globalComponents.clear();
    globalComponentsVersion.value++;
  },
  /**
   * 获取所有全局注册的组件
   */
  getAll() {
    globalComponentsVersion.value;
    const result = {};
    globalComponents.forEach((component, type) => {
      result[type] = component;
    });
    return result;
  },
  /**
   * 批量注册组件
   * @param components 组件映射表
   */
  registerBatch(components) {
    Object.entries(components).forEach(([type, component]) => {
      this.register(type, component);
    });
  }
};
const SimpleFormPlugin = {
  install(app, options = {}) {
    app.config.globalProperties.$simpleFormRegistry = globalComponentRegistry;
    if (options.components) {
      globalComponentRegistry.registerBatch(options.components);
    }
    app.provide("simpleFormRegistry", globalComponentRegistry);
  }
};
function useSimpleForm(schema, initialData = {}) {
  const formData = reactive(__spreadValues({}, initialData));
  const errors = ref({});
  const asyncStates = reactive({});
  const fieldOptionsCache = reactive({});
  const componentRegistry = createComponentRegistry();
  const getValue = (path) => {
    return getByPath(formData, path);
  };
  const setValue = (path, value) => {
    setByPath(formData, path, value);
    if (errors.value[path]) {
      delete errors.value[path];
    }
  };
  const getFieldConfig = (fieldName) => {
    const findField = (fields) => {
      for (const field of fields) {
        if (field.name === fieldName) {
          return field;
        }
        if (field.type === "group" && field.children) {
          const found = findField(field.children);
          if (found) return found;
        }
      }
      return null;
    };
    return findField(schema.fields);
  };
  const validateField = (path) => {
    const fieldConfig = getFieldConfig(path.split(".").pop() || path);
    if (!fieldConfig || !fieldConfig.rules) return true;
    const value = getValue(path);
    for (const rule of fieldConfig.rules) {
      if (rule.required && (value === void 0 || value === null || value === "")) {
        errors.value[path] = rule.message || `${fieldConfig.label} is required`;
        return false;
      }
      if (rule.validator) {
        const result = rule.validator(value, formData);
        if (result !== true) {
          errors.value[path] = typeof result === "string" ? result : rule.message || "Invalid value";
          return false;
        }
      }
    }
    delete errors.value[path];
    return true;
  };
  const validateForm = () => {
    const allPaths = getAllPaths(formData);
    let isValid = true;
    for (const path in allPaths) {
      if (!validateField(path)) {
        isValid = false;
      }
    }
    const validateRequiredFields = (fields, prefix = "") => {
      var _a;
      for (const field of fields) {
        if (field.type === "group" && field.children) {
          validateRequiredFields(field.children, `${field.name}.`);
        } else {
          const fieldPath = prefix + field.name;
          if ((_a = field.rules) == null ? void 0 : _a.some((rule) => rule.required)) {
            if (!validateField(fieldPath)) {
              isValid = false;
            }
          }
        }
      }
    };
    validateRequiredFields(schema.fields);
    return isValid;
  };
  const resetForm = () => {
    Object.keys(formData).forEach((key) => {
      delete formData[key];
    });
    Object.assign(formData, __spreadValues({}, initialData));
    errors.value = {};
  };
  const formValues = computed(() => __spreadValues({}, formData));
  const hasErrors = computed(() => Object.keys(errors.value).length > 0);
  const getFieldError = (path) => {
    return errors.value[path];
  };
  const initializeAsync = () => __async(this, null, function* () {
    if (!schema.asyncInitializer) return;
    const initKey = "__init__";
    asyncStates[initKey] = { loading: true };
    try {
      const asyncData = yield schema.asyncInitializer();
      if (asyncData && typeof asyncData === "object") {
        Object.assign(formData, asyncData);
      }
      asyncStates[initKey] = { loading: false };
      yield nextTick();
      yield triggerAsyncLinkageForInitialization();
    } catch (error) {
      asyncStates[initKey] = {
        loading: false,
        error: error instanceof Error ? error.message : "初始化失败"
      };
    }
  });
  const triggerAsyncLinkageForInitialization = () => __async(this, null, function* () {
    var _a;
    for (const field of schema.fields) {
      if (((_a = field.linkage) == null ? void 0 : _a.asyncOptionsLoader) && field.linkage.dependsOn) {
        const dependentValue = getByPath(formData, field.linkage.dependsOn);
        if (dependentValue !== void 0) {
          yield loadFieldOptions(field.name, dependentValue);
        }
      }
    }
  });
  const loadFieldOptions = (fieldName, dependentValue) => __async(this, null, function* () {
    var _a;
    const fieldConfig = getFieldConfig(fieldName);
    if (!((_a = fieldConfig == null ? void 0 : fieldConfig.linkage) == null ? void 0 : _a.asyncOptionsLoader)) return [];
    const cacheKey = `${fieldName}_${dependentValue}`;
    asyncStates[cacheKey] = { loading: true };
    try {
      const options = yield fieldConfig.linkage.asyncOptionsLoader(dependentValue, formData);
      fieldOptionsCache[cacheKey] = options;
      asyncStates[cacheKey] = { loading: false };
      return options;
    } catch (error) {
      asyncStates[cacheKey] = {
        loading: false,
        error: error instanceof Error ? error.message : "加载选项失败"
      };
      return [];
    }
  });
  const getFieldOptions = (fieldName, dependentValue) => {
    var _a, _b;
    const fieldConfig = getFieldConfig(fieldName);
    if (!fieldConfig) return [];
    if (((_a = fieldConfig.linkage) == null ? void 0 : _a.asyncOptionsLoader) && dependentValue !== void 0) {
      const cacheKey = `${fieldName}_${dependentValue}`;
      return fieldOptionsCache[cacheKey] || [];
    }
    if (((_b = fieldConfig.linkage) == null ? void 0 : _b.optionsMap) && dependentValue !== void 0) {
      return fieldConfig.linkage.optionsMap[dependentValue] || [];
    }
    return fieldConfig.options || [];
  };
  const getAsyncState = (key) => {
    return asyncStates[key] || { loading: false };
  };
  const validateFieldAsync = (path) => __async(this, null, function* () {
    const fieldConfig = getFieldConfig(path.split(".").pop() || path);
    if (!fieldConfig || !fieldConfig.rules) return true;
    const value = getValue(path);
    if (!validateField(path)) return false;
    for (const rule of fieldConfig.rules) {
      if (rule.asyncValidator) {
        const validationKey = `${path}_validation`;
        asyncStates[validationKey] = { loading: true };
        try {
          const result = yield rule.asyncValidator(value, formData);
          asyncStates[validationKey] = { loading: false };
          if (result !== true) {
            errors.value[path] = typeof result === "string" ? result : rule.message || "Invalid value";
            return false;
          }
        } catch (error) {
          asyncStates[validationKey] = {
            loading: false,
            error: error instanceof Error ? error.message : "验证失败"
          };
          errors.value[path] = rule.message || "验证失败";
          return false;
        }
      }
    }
    delete errors.value[path];
    return true;
  });
  const setupFieldWatchers = () => {
    const fieldsWithDependencies = schema.fields.filter((field) => {
      var _a;
      return (_a = field.linkage) == null ? void 0 : _a.dependsOn;
    });
    fieldsWithDependencies.forEach((field) => {
      var _a;
      if ((_a = field.linkage) == null ? void 0 : _a.dependsOn) {
        watch(
          () => getByPath(formData, field.linkage.dependsOn),
          (newValue, oldValue) => __async(this, null, function* () {
            var _a2, _b;
            if (newValue !== oldValue) {
              const shouldReset = ((_a2 = field.linkage) == null ? void 0 : _a2.resetOnChange) !== false;
              if (shouldReset) {
                const initialValue = getInitialValue(field);
                setValue(field.name, initialValue);
              }
              if (((_b = field.linkage) == null ? void 0 : _b.asyncOptionsLoader) && newValue !== void 0) {
                const cacheKey = `${field.name}_${newValue}`;
                const hasCache = fieldOptionsCache[cacheKey] && fieldOptionsCache[cacheKey].length > 0;
                if (!hasCache) {
                  yield loadFieldOptions(field.name, newValue);
                }
              }
            }
          }),
          { immediate: false }
          // 不在初始化时立即触发
        );
      }
    });
  };
  setupFieldWatchers();
  const getInitialValue = (field) => {
    switch (field.type) {
      case "input":
      case "text":
      case "textarea":
        return "";
      case "select":
      case "radio":
        return void 0;
      case "checkbox":
        return false;
      case "number":
        return void 0;
      case "date":
        return void 0;
      default:
        return void 0;
    }
  };
  return {
    formData,
    formValues,
    errors: computed(() => errors.value),
    hasErrors,
    getValue,
    setValue,
    getFieldConfig,
    validateField,
    validateFieldAsync,
    validateForm,
    resetForm,
    getFieldError,
    // 异步功能
    initializeAsync,
    loadFieldOptions,
    getFieldOptions,
    getAsyncState,
    asyncStates: computed(() => asyncStates),
    fieldOptionsCache: computed(() => fieldOptionsCache),
    // 组件注册功能
    componentRegistry,
    // Schema 配置
    schema
  };
}
const _sfc_main$7 = /* @__PURE__ */ defineComponent({
  __name: "SimpleInput",
  props: {
    field: {},
    value: {},
    disabled: { type: Boolean }
  },
  emits: ["update:value", "blur", "focus"],
  setup(__props, { emit: __emit }) {
    const emit = __emit;
    const handleChange = (value) => {
      emit("update:value", value);
    };
    const handleBlur = () => {
      emit("blur");
    };
    const handleFocus = () => {
      emit("focus");
    };
    return (_ctx, _cache) => {
      var _a, _b, _c;
      const _component_a_input = resolveComponent("a-input");
      return openBlock(), createBlock(_component_a_input, {
        value: _ctx.value,
        placeholder: _ctx.field.placeholder,
        disabled: _ctx.disabled,
        size: (_a = _ctx.field.props) == null ? void 0 : _a.size,
        "allow-clear": (_b = _ctx.field.props) == null ? void 0 : _b.allowClear,
        "max-length": (_c = _ctx.field.props) == null ? void 0 : _c.maxLength,
        "onUpdate:value": handleChange,
        onBlur: handleBlur,
        onFocus: handleFocus
      }, null, 8, ["value", "placeholder", "disabled", "size", "allow-clear", "max-length"]);
    };
  }
});
const _sfc_main$6 = /* @__PURE__ */ defineComponent({
  __name: "SimpleSelect",
  props: {
    field: {},
    value: {},
    disabled: { type: Boolean },
    loading: { type: Boolean }
  },
  emits: ["update:value", "blur", "focus"],
  setup(__props, { emit: __emit }) {
    const props = __props;
    const emit = __emit;
    const formContext = inject("formContext");
    const currentOptions = computed(() => {
      var _a;
      if (((_a = props.field.linkage) == null ? void 0 : _a.dependsOn) && formContext) {
        const dependentValue = formContext.getValue(props.field.linkage.dependsOn);
        if (props.field.linkage.asyncOptionsLoader && dependentValue !== void 0) {
          return formContext.getFieldOptions(props.field.name, dependentValue);
        }
        if (props.field.linkage.optionsMap && dependentValue !== void 0) {
          return props.field.linkage.optionsMap[dependentValue] || [];
        }
      }
      return props.field.options || [];
    });
    const isLoadingOptions = computed(() => {
      var _a;
      if (!((_a = props.field.linkage) == null ? void 0 : _a.dependsOn) || !formContext) return false;
      const dependentValue = formContext.getValue(props.field.linkage.dependsOn);
      if (props.field.linkage.asyncOptionsLoader && dependentValue !== void 0) {
        const cacheKey = `${props.field.name}_${dependentValue}`;
        return formContext.getAsyncState(cacheKey).loading;
      }
      return false;
    });
    const handleChange = (value) => {
      emit("update:value", value);
    };
    const handleBlur = () => {
      emit("blur");
    };
    const handleFocus = () => {
      emit("focus");
    };
    return (_ctx, _cache) => {
      var _a, _b, _c, _d, _e;
      const _component_a_select_option = resolveComponent("a-select-option");
      const _component_a_select = resolveComponent("a-select");
      return openBlock(), createBlock(_component_a_select, {
        value: _ctx.value,
        placeholder: _ctx.field.placeholder,
        disabled: _ctx.disabled,
        loading: _ctx.loading || isLoadingOptions.value,
        "allow-clear": (_a = _ctx.field.props) == null ? void 0 : _a.allowClear,
        "show-search": (_b = _ctx.field.props) == null ? void 0 : _b.showSearch,
        "filter-option": (_c = _ctx.field.props) == null ? void 0 : _c.filterOption,
        mode: (_d = _ctx.field.props) == null ? void 0 : _d.mode,
        size: (_e = _ctx.field.props) == null ? void 0 : _e.size,
        "onUpdate:value": handleChange,
        onBlur: handleBlur,
        onFocus: handleFocus
      }, {
        default: withCtx(() => [
          (openBlock(true), createElementBlock(Fragment, null, renderList(currentOptions.value, (option) => {
            return openBlock(), createBlock(_component_a_select_option, {
              key: option.value,
              value: option.value,
              disabled: option.disabled
            }, {
              default: withCtx(() => [
                createTextVNode(toDisplayString(option.label), 1)
              ]),
              _: 2
            }, 1032, ["value", "disabled"]);
          }), 128))
        ]),
        _: 1
      }, 8, ["value", "placeholder", "disabled", "loading", "allow-clear", "show-search", "filter-option", "mode", "size"]);
    };
  }
});
const _sfc_main$5 = /* @__PURE__ */ defineComponent({
  __name: "SimpleRadio",
  props: {
    field: {},
    value: {},
    disabled: { type: Boolean }
  },
  emits: ["update:value"],
  setup(__props, { emit: __emit }) {
    const props = __props;
    const emit = __emit;
    const formContext = inject("formContext");
    const currentOptions = computed(() => {
      var _a;
      if (((_a = props.field.linkage) == null ? void 0 : _a.dependsOn) && formContext) {
        const dependentValue = formContext.getValue(props.field.linkage.dependsOn);
        if (props.field.linkage.optionsMap && dependentValue !== void 0) {
          return props.field.linkage.optionsMap[dependentValue] || [];
        }
      }
      return props.field.options || [];
    });
    const handleChange = (value) => {
      emit("update:value", value);
    };
    return (_ctx, _cache) => {
      var _a, _b;
      const _component_a_radio = resolveComponent("a-radio");
      const _component_a_radio_group = resolveComponent("a-radio-group");
      return openBlock(), createBlock(_component_a_radio_group, {
        value: _ctx.value,
        disabled: _ctx.disabled,
        size: (_a = _ctx.field.props) == null ? void 0 : _a.size,
        direction: ((_b = _ctx.field.props) == null ? void 0 : _b.direction) || "horizontal",
        "onUpdate:value": handleChange
      }, {
        default: withCtx(() => [
          (openBlock(true), createElementBlock(Fragment, null, renderList(currentOptions.value, (option) => {
            return openBlock(), createBlock(_component_a_radio, {
              key: option.value,
              value: option.value,
              disabled: option.disabled
            }, {
              default: withCtx(() => [
                createTextVNode(toDisplayString(option.label), 1)
              ]),
              _: 2
            }, 1032, ["value", "disabled"]);
          }), 128))
        ]),
        _: 1
      }, 8, ["value", "disabled", "size", "direction"]);
    };
  }
});
const _hoisted_1$4 = {
  key: 0,
  class: "simple-group-header"
};
const _hoisted_2$4 = {
  key: 0,
  class: "simple-group-title"
};
const _hoisted_3$3 = {
  key: 1,
  class: "simple-group-description"
};
const _sfc_main$4 = /* @__PURE__ */ defineComponent({
  __name: "SimpleGroup",
  props: {
    field: {},
    path: {}
  },
  setup(__props) {
    const props = __props;
    const formContext = inject("formContext");
    const layoutClass = computed(() => {
      return props.field.layout === "horizontal" ? "simple-group-horizontal" : "simple-group-vertical";
    });
    const getChildPath = (childName) => {
      return props.path ? `${props.path}.${childName}` : childName;
    };
    const visibleChildren = computed(() => {
      if (!props.field.children) return [];
      return props.field.children.filter((child) => {
        var _a;
        if (!((_a = child.linkage) == null ? void 0 : _a.visibleWhen)) return true;
        const childPath = getChildPath(child.name);
        const value = formContext == null ? void 0 : formContext.getValue(childPath);
        return child.linkage.visibleWhen(value, formContext == null ? void 0 : formContext.formData);
      });
    });
    return (_ctx, _cache) => {
      var _a, _b;
      return openBlock(), createElementBlock("div", {
        class: normalizeClass(["simple-group", { "simple-group-bordered": _ctx.field.bordered }])
      }, [
        _ctx.field.label || ((_a = _ctx.field.props) == null ? void 0 : _a.description) ? (openBlock(), createElementBlock("div", _hoisted_1$4, [
          _ctx.field.label ? (openBlock(), createElementBlock("h4", _hoisted_2$4, toDisplayString(_ctx.field.label), 1)) : createCommentVNode("", true),
          ((_b = _ctx.field.props) == null ? void 0 : _b.description) ? (openBlock(), createElementBlock("p", _hoisted_3$3, toDisplayString(_ctx.field.props.description), 1)) : createCommentVNode("", true)
        ])) : createCommentVNode("", true),
        createElementVNode("div", {
          class: normalizeClass(["simple-group-content", layoutClass.value])
        }, [
          (openBlock(true), createElementBlock(Fragment, null, renderList(visibleChildren.value, (childField) => {
            return openBlock(), createBlock(SimpleFormItem, {
              key: childField.name,
              field: childField,
              path: getChildPath(childField.name)
            }, null, 8, ["field", "path"]);
          }), 128))
        ], 2)
      ], 2);
    };
  }
});
const _export_sfc = (sfc, props) => {
  const target = sfc.__vccOpts || sfc;
  for (const [key, val] of props) {
    target[key] = val;
  }
  return target;
};
const SimpleGroup = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-f4248fd8"]]);
const _hoisted_1$3 = { class: "simple-form-item-control" };
const _hoisted_2$3 = {
  key: 9,
  class: "unsupported-field"
};
const _hoisted_3$2 = { class: "error-title" };
const _hoisted_4$2 = { class: "error-details" };
const _hoisted_5$1 = { class: "debug-info" };
const _hoisted_6 = { key: 2 };
const _hoisted_7 = { class: "simple-form-item-control" };
const _hoisted_8 = {
  key: 9,
  class: "unsupported-field"
};
const _hoisted_9 = { class: "error-title" };
const _hoisted_10 = { class: "error-details" };
const _hoisted_11 = { class: "debug-info" };
const _hoisted_12 = {
  key: 2,
  class: "simple-form-item-validating"
};
const _hoisted_13 = {
  key: 3,
  class: "simple-form-item-error-message"
};
const _sfc_main$3 = /* @__PURE__ */ defineComponent({
  __name: "SimpleFormItem",
  props: {
    field: {},
    path: {}
  },
  setup(__props) {
    const props = __props;
    const fieldAsGroup = computed(() => props.field);
    const formContext = inject("formContext");
    const injectedFormLayout = inject("formLayout", null);
    const fieldPath = computed(() => {
      return props.path || props.field.name;
    });
    const fieldValue = computed(() => {
      return formContext == null ? void 0 : formContext.getValue(fieldPath.value);
    });
    const isRequired = computed(() => {
      var _a;
      return ((_a = props.field.rules) == null ? void 0 : _a.some((rule) => rule.required)) || false;
    });
    const isDisabled = computed(() => {
      var _a;
      if (!((_a = props.field.linkage) == null ? void 0 : _a.disabledWhen)) return false;
      return props.field.linkage.disabledWhen(fieldValue.value, formContext == null ? void 0 : formContext.formData);
    });
    const hasError = computed(() => {
      return !!(formContext == null ? void 0 : formContext.getFieldError(fieldPath.value));
    });
    const errorMessage = computed(() => {
      return formContext == null ? void 0 : formContext.getFieldError(fieldPath.value);
    });
    const handleValueChange = (value) => {
      formContext == null ? void 0 : formContext.setValue(fieldPath.value, value);
    };
    const handleBlur = () => __async(this, null, function* () {
      var _a;
      formContext == null ? void 0 : formContext.validateField(fieldPath.value);
      const fieldConfig = formContext == null ? void 0 : formContext.getFieldConfig(props.field.name);
      if ((_a = fieldConfig == null ? void 0 : fieldConfig.rules) == null ? void 0 : _a.some((rule) => rule.asyncValidator)) {
        yield formContext == null ? void 0 : formContext.validateFieldAsync(fieldPath.value);
      }
    });
    const isValidating = computed(() => {
      const validationKey = `${fieldPath.value}_validation`;
      return (formContext == null ? void 0 : formContext.getAsyncState(validationKey).loading) || false;
    });
    const customComponent = computed(() => {
      if (props.field.component) {
        console.log(`字段 ${props.field.name} 使用内联组件:`, props.field.component);
        return markRaw(props.field.component);
      }
      const registeredComponent = formContext == null ? void 0 : formContext.componentRegistry.get(props.field.type);
      if (registeredComponent) {
        console.log(`字段 ${props.field.name} 找到注册组件:`, props.field.type);
      } else {
        console.warn(`字段 ${props.field.name} 未找到对应的组件:`, props.field.type);
        console.log("当前已注册的组件:", formContext == null ? void 0 : formContext.componentRegistry.getAll());
      }
      return registeredComponent;
    });
    const mergedComponentProps = computed(() => {
      const baseProps = __spreadValues({
        placeholder: props.field.placeholder
      }, props.field.props);
      if (props.field.componentProps) {
        Object.assign(baseProps, props.field.componentProps);
      }
      return baseProps;
    });
    const customComponentEvents = computed(() => {
      return {};
    });
    const handleFocus = () => {
    };
    const getTooltipTitle = computed(() => {
      var _a;
      if (typeof props.field.tooltip === "string") {
        return props.field.tooltip;
      }
      return ((_a = props.field.tooltip) == null ? void 0 : _a.title) || "";
    });
    const getTooltipPlacement = computed(() => {
      var _a;
      if (typeof props.field.tooltip === "string") {
        return "top";
      }
      return ((_a = props.field.tooltip) == null ? void 0 : _a.placement) || "top";
    });
    const getTooltipColor = computed(() => {
      var _a;
      if (typeof props.field.tooltip === "string") {
        return void 0;
      }
      return (_a = props.field.tooltip) == null ? void 0 : _a.color;
    });
    const getTooltipOverlayClassName = computed(() => {
      var _a;
      if (typeof props.field.tooltip === "string") {
        return void 0;
      }
      return (_a = props.field.tooltip) == null ? void 0 : _a.overlayClassName;
    });
    const getTooltipOverlayStyle = computed(() => {
      var _a;
      if (typeof props.field.tooltip === "string") {
        return void 0;
      }
      return (_a = props.field.tooltip) == null ? void 0 : _a.overlayStyle;
    });
    const fieldLayout = computed(() => props.field.layout || {});
    const formLayout = computed(() => {
      var _a;
      return (injectedFormLayout == null ? void 0 : injectedFormLayout.value) || ((_a = formContext == null ? void 0 : formContext.schema) == null ? void 0 : _a.layout) || {};
    });
    const isInlineLayout = computed(() => (formLayout.value.type || "vertical") === "inline");
    const formItemGutter = computed(() => {
      const gutter = formLayout.value.gutter;
      if (Array.isArray(gutter)) {
        return gutter;
      }
      return gutter ? [gutter, gutter] : [8, 8];
    });
    const useRowLayout = computed(() => {
      const layoutType = formLayout.value.type || "vertical";
      if (layoutType === "horizontal" || layoutType === "grid") {
        return true;
      }
      const hasFieldLayoutCols = typeof fieldLayout.value === "object" && (fieldLayout.value.labelCol || fieldLayout.value.wrapperCol);
      const hasFormLayoutCols = formLayout.value.labelCol || formLayout.value.wrapperCol;
      return hasFieldLayoutCols || hasFormLayoutCols;
    });
    const formItemClasses = computed(() => {
      const classes = [];
      const layoutType = formLayout.value.type || "vertical";
      classes.push(`simple-form-item-${layoutType}`);
      if (hasError.value) {
        classes.push("simple-form-item-error");
      }
      if (typeof fieldLayout.value === "object" && fieldLayout.value.className) {
        classes.push(fieldLayout.value.className);
      }
      return classes;
    });
    const formItemStyle = computed(() => {
      return typeof fieldLayout.value === "object" && fieldLayout.value.style || {};
    });
    const labelClasses = computed(() => {
      const classes = [];
      const labelAlign = formLayout.value.labelAlign;
      if (labelAlign) {
        classes.push(`label-${labelAlign}`);
      }
      return classes;
    });
    const labelColSpan = computed(() => {
      var _a, _b;
      const fieldLayoutCol = typeof fieldLayout.value === "object" ? (_a = fieldLayout.value.labelCol) == null ? void 0 : _a.span : void 0;
      const formLayoutCol = (_b = formLayout.value.labelCol) == null ? void 0 : _b.span;
      const layoutType = formLayout.value.type || "vertical";
      let defaultSpan = 6;
      if (layoutType === "horizontal") {
        defaultSpan = 6;
      }
      return fieldLayoutCol || formLayoutCol || defaultSpan;
    });
    const labelColOffset = computed(() => {
      var _a, _b;
      const fieldLayoutOffset = typeof fieldLayout.value === "object" ? (_a = fieldLayout.value.labelCol) == null ? void 0 : _a.offset : void 0;
      return fieldLayoutOffset || ((_b = formLayout.value.labelCol) == null ? void 0 : _b.offset) || 0;
    });
    const wrapperColSpan = computed(() => {
      var _a, _b;
      const fieldLayoutSpan = typeof fieldLayout.value === "object" ? (_a = fieldLayout.value.wrapperCol) == null ? void 0 : _a.span : void 0;
      const formLayoutSpan = (_b = formLayout.value.wrapperCol) == null ? void 0 : _b.span;
      const layoutType = formLayout.value.type || "vertical";
      if (fieldLayoutSpan || formLayoutSpan) {
        return fieldLayoutSpan || formLayoutSpan;
      }
      const labelSpan = labelColSpan.value;
      const labelOffset = labelColOffset.value;
      if (layoutType === "horizontal") {
        return 24 - labelSpan - labelOffset;
      }
      return 24 - labelSpan - labelOffset;
    });
    const wrapperColOffset = computed(() => {
      var _a, _b;
      const fieldLayoutOffset = typeof fieldLayout.value === "object" ? (_a = fieldLayout.value.wrapperCol) == null ? void 0 : _a.offset : void 0;
      return fieldLayoutOffset || ((_b = formLayout.value.wrapperCol) == null ? void 0 : _b.offset) || 0;
    });
    return (_ctx, _cache) => {
      var _a, _b, _c, _d, _e, _f, _g, _h, _i;
      const _component_a_tooltip = resolveComponent("a-tooltip");
      const _component_a_col = resolveComponent("a-col");
      const _component_a_input_number = resolveComponent("a-input-number");
      const _component_a_textarea = resolveComponent("a-textarea");
      const _component_a_checkbox = resolveComponent("a-checkbox");
      const _component_a_date_picker = resolveComponent("a-date-picker");
      const _component_a_row = resolveComponent("a-row");
      const _component_a_spin = resolveComponent("a-spin");
      return openBlock(), createElementBlock("div", {
        class: normalizeClass(["simple-form-item", formItemClasses.value]),
        style: normalizeStyle(formItemStyle.value)
      }, [
        useRowLayout.value ? (openBlock(), createBlock(_component_a_row, {
          key: 0,
          gutter: formItemGutter.value
        }, {
          default: withCtx(() => [
            _ctx.field.label ? (openBlock(), createBlock(_component_a_col, {
              key: 0,
              span: labelColSpan.value,
              offset: labelColOffset.value,
              class: "simple-form-item-label-col"
            }, {
              default: withCtx(() => [
                createElementVNode("div", {
                  class: normalizeClass(["simple-form-item-label", labelClasses.value])
                }, [
                  createElementVNode("span", {
                    class: normalizeClass({ required: isRequired.value })
                  }, toDisplayString(_ctx.field.label), 3),
                  _ctx.field.tooltip ? (openBlock(), createBlock(_component_a_tooltip, {
                    key: 0,
                    title: getTooltipTitle.value,
                    placement: getTooltipPlacement.value,
                    color: getTooltipColor.value,
                    "overlay-class-name": getTooltipOverlayClassName.value,
                    "overlay-style": getTooltipOverlayStyle.value
                  }, {
                    default: withCtx(() => [
                      createVNode(unref(QuestionCircleOutlined), { class: "field-tooltip-icon" })
                    ]),
                    _: 1
                  }, 8, ["title", "placement", "color", "overlay-class-name", "overlay-style"])) : createCommentVNode("", true)
                ], 2)
              ]),
              _: 1
            }, 8, ["span", "offset"])) : createCommentVNode("", true),
            createVNode(_component_a_col, {
              span: wrapperColSpan.value,
              offset: wrapperColOffset.value,
              class: "simple-form-item-control-col"
            }, {
              default: withCtx(() => {
                var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2;
                return [
                  createElementVNode("div", _hoisted_1$3, [
                    _ctx.field.type === "group" ? (openBlock(), createBlock(SimpleGroup, {
                      key: 0,
                      field: fieldAsGroup.value,
                      path: _ctx.path || ""
                    }, null, 8, ["field", "path"])) : _ctx.field.type === "input" || _ctx.field.type === "text" ? (openBlock(), createBlock(_sfc_main$7, {
                      key: 1,
                      field: _ctx.field,
                      value: fieldValue.value,
                      disabled: isDisabled.value,
                      "onUpdate:value": handleValueChange,
                      onBlur: handleBlur
                    }, null, 8, ["field", "value", "disabled"])) : _ctx.field.type === "select" ? (openBlock(), createBlock(_sfc_main$6, {
                      key: 2,
                      field: _ctx.field,
                      value: fieldValue.value,
                      disabled: isDisabled.value,
                      "onUpdate:value": handleValueChange,
                      onBlur: handleBlur
                    }, null, 8, ["field", "value", "disabled"])) : _ctx.field.type === "radio" ? (openBlock(), createBlock(_sfc_main$5, {
                      key: 3,
                      field: _ctx.field,
                      value: fieldValue.value,
                      disabled: isDisabled.value,
                      "onUpdate:value": handleValueChange
                    }, null, 8, ["field", "value", "disabled"])) : _ctx.field.type === "number" ? (openBlock(), createBlock(_component_a_input_number, {
                      key: 4,
                      value: fieldValue.value,
                      placeholder: _ctx.field.placeholder,
                      disabled: isDisabled.value,
                      min: (_a2 = _ctx.field.props) == null ? void 0 : _a2.min,
                      max: (_b2 = _ctx.field.props) == null ? void 0 : _b2.max,
                      step: (_c2 = _ctx.field.props) == null ? void 0 : _c2.step,
                      precision: (_d2 = _ctx.field.props) == null ? void 0 : _d2.precision,
                      "onUpdate:value": handleValueChange,
                      onBlur: handleBlur
                    }, null, 8, ["value", "placeholder", "disabled", "min", "max", "step", "precision"])) : _ctx.field.type === "textarea" ? (openBlock(), createBlock(_component_a_textarea, {
                      key: 5,
                      value: fieldValue.value,
                      placeholder: _ctx.field.placeholder,
                      disabled: isDisabled.value,
                      rows: ((_e2 = _ctx.field.props) == null ? void 0 : _e2.rows) || 4,
                      "max-length": (_f2 = _ctx.field.props) == null ? void 0 : _f2.maxLength,
                      "show-count": (_g2 = _ctx.field.props) == null ? void 0 : _g2.showCount,
                      "onUpdate:value": handleValueChange,
                      onBlur: handleBlur
                    }, null, 8, ["value", "placeholder", "disabled", "rows", "max-length", "show-count"])) : _ctx.field.type === "checkbox" ? (openBlock(), createBlock(_component_a_checkbox, {
                      key: 6,
                      checked: fieldValue.value,
                      disabled: isDisabled.value,
                      "onUpdate:checked": handleValueChange
                    }, {
                      default: withCtx(() => {
                        var _a3;
                        return [
                          createTextVNode(toDisplayString((_a3 = _ctx.field.props) == null ? void 0 : _a3.label), 1)
                        ];
                      }),
                      _: 1
                    }, 8, ["checked", "disabled"])) : _ctx.field.type === "date" ? (openBlock(), createBlock(_component_a_date_picker, {
                      key: 7,
                      value: fieldValue.value,
                      placeholder: _ctx.field.placeholder,
                      disabled: isDisabled.value,
                      format: (_h2 = _ctx.field.props) == null ? void 0 : _h2.format,
                      "onUpdate:value": handleValueChange,
                      onBlur: handleBlur
                    }, null, 8, ["value", "placeholder", "disabled", "format"])) : customComponent.value ? (openBlock(), createBlock(resolveDynamicComponent(customComponent.value), mergeProps({
                      key: 8,
                      value: fieldValue.value,
                      field: _ctx.field,
                      disabled: isDisabled.value
                    }, mergedComponentProps.value, {
                      "onUpdate:value": handleValueChange,
                      onBlur: handleBlur,
                      onFocus: handleFocus
                    }, toHandlers(customComponentEvents.value)), null, 16, ["value", "field", "disabled"])) : (openBlock(), createElementBlock("div", _hoisted_2$3, [
                      createElementVNode("div", _hoisted_3$2, [
                        createVNode(unref(ExclamationCircleOutlined)),
                        createTextVNode(" 不支持的字段类型: " + toDisplayString(_ctx.field.type), 1)
                      ]),
                      createElementVNode("div", _hoisted_4$2, [
                        createElementVNode("p", null, "字段名: " + toDisplayString(_ctx.field.name), 1),
                        _cache[1] || (_cache[1] = createElementVNode("p", null, "可能的解决方案:", -1)),
                        _cache[2] || (_cache[2] = createElementVNode("ul", null, [
                          createElementVNode("li", null, "检查字段类型是否拼写正确"),
                          createElementVNode("li", null, "确保自定义组件已正确注册"),
                          createElementVNode("li", null, "使用 component 属性直接指定组件"),
                          createElementVNode("li", null, "联系开发者添加对该字段类型的支持")
                        ], -1)),
                        createElementVNode("div", _hoisted_5$1, [
                          createElementVNode("details", null, [
                            _cache[0] || (_cache[0] = createElementVNode("summary", null, "调试信息", -1)),
                            createElementVNode("p", null, "已注册的组件类型: " + toDisplayString(Object.keys(((_i2 = unref(formContext)) == null ? void 0 : _i2.componentRegistry.getAll()) || {}).join(", ") || "无"), 1),
                            createElementVNode("p", null, "字段配置: " + toDisplayString(JSON.stringify(_ctx.field, null, 2)), 1)
                          ])
                        ])
                      ])
                    ]))
                  ])
                ];
              }),
              _: 1
            }, 8, ["span", "offset"])
          ]),
          _: 1
        }, 8, ["gutter"])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
          _ctx.field.label || isInlineLayout.value ? (openBlock(), createElementBlock("div", {
            key: 0,
            class: normalizeClass(["simple-form-item-label", labelClasses.value])
          }, [
            _ctx.field.label ? (openBlock(), createElementBlock("span", {
              key: 0,
              class: normalizeClass({ required: isRequired.value })
            }, toDisplayString(_ctx.field.label), 3)) : createCommentVNode("", true),
            _ctx.field.tooltip ? (openBlock(), createBlock(_component_a_tooltip, {
              key: 1,
              title: getTooltipTitle.value,
              placement: getTooltipPlacement.value,
              color: getTooltipColor.value,
              "overlay-class-name": getTooltipOverlayClassName.value,
              "overlay-style": getTooltipOverlayStyle.value
            }, {
              default: withCtx(() => [
                createVNode(unref(QuestionCircleOutlined), { class: "field-tooltip-icon" })
              ]),
              _: 1
            }, 8, ["title", "placement", "color", "overlay-class-name", "overlay-style"])) : !_ctx.field.label ? (openBlock(), createElementBlock("span", _hoisted_6, " ")) : createCommentVNode("", true)
          ], 2)) : createCommentVNode("", true),
          createElementVNode("div", _hoisted_7, [
            _ctx.field.type === "group" ? (openBlock(), createBlock(SimpleGroup, {
              key: 0,
              field: fieldAsGroup.value,
              path: _ctx.path || ""
            }, null, 8, ["field", "path"])) : _ctx.field.type === "input" || _ctx.field.type === "text" ? (openBlock(), createBlock(_sfc_main$7, {
              key: 1,
              field: _ctx.field,
              value: fieldValue.value,
              disabled: isDisabled.value,
              "onUpdate:value": handleValueChange,
              onBlur: handleBlur
            }, null, 8, ["field", "value", "disabled"])) : _ctx.field.type === "select" ? (openBlock(), createBlock(_sfc_main$6, {
              key: 2,
              field: _ctx.field,
              value: fieldValue.value,
              disabled: isDisabled.value,
              "onUpdate:value": handleValueChange,
              onBlur: handleBlur
            }, null, 8, ["field", "value", "disabled"])) : _ctx.field.type === "radio" ? (openBlock(), createBlock(_sfc_main$5, {
              key: 3,
              field: _ctx.field,
              value: fieldValue.value,
              disabled: isDisabled.value,
              "onUpdate:value": handleValueChange
            }, null, 8, ["field", "value", "disabled"])) : _ctx.field.type === "number" ? (openBlock(), createBlock(_component_a_input_number, {
              key: 4,
              value: fieldValue.value,
              placeholder: _ctx.field.placeholder,
              disabled: isDisabled.value,
              min: (_a = _ctx.field.props) == null ? void 0 : _a.min,
              max: (_b = _ctx.field.props) == null ? void 0 : _b.max,
              step: (_c = _ctx.field.props) == null ? void 0 : _c.step,
              precision: (_d = _ctx.field.props) == null ? void 0 : _d.precision,
              "onUpdate:value": handleValueChange,
              onBlur: handleBlur
            }, null, 8, ["value", "placeholder", "disabled", "min", "max", "step", "precision"])) : _ctx.field.type === "textarea" ? (openBlock(), createBlock(_component_a_textarea, {
              key: 5,
              value: fieldValue.value,
              placeholder: _ctx.field.placeholder,
              disabled: isDisabled.value,
              rows: ((_e = _ctx.field.props) == null ? void 0 : _e.rows) || 4,
              "max-length": (_f = _ctx.field.props) == null ? void 0 : _f.maxLength,
              "show-count": (_g = _ctx.field.props) == null ? void 0 : _g.showCount,
              "onUpdate:value": handleValueChange,
              onBlur: handleBlur
            }, null, 8, ["value", "placeholder", "disabled", "rows", "max-length", "show-count"])) : _ctx.field.type === "checkbox" ? (openBlock(), createBlock(_component_a_checkbox, {
              key: 6,
              checked: fieldValue.value,
              disabled: isDisabled.value,
              "onUpdate:checked": handleValueChange
            }, {
              default: withCtx(() => {
                var _a2;
                return [
                  createTextVNode(toDisplayString((_a2 = _ctx.field.props) == null ? void 0 : _a2.label), 1)
                ];
              }),
              _: 1
            }, 8, ["checked", "disabled"])) : _ctx.field.type === "date" ? (openBlock(), createBlock(_component_a_date_picker, {
              key: 7,
              value: fieldValue.value,
              placeholder: _ctx.field.placeholder,
              disabled: isDisabled.value,
              format: (_h = _ctx.field.props) == null ? void 0 : _h.format,
              "onUpdate:value": handleValueChange,
              onBlur: handleBlur
            }, null, 8, ["value", "placeholder", "disabled", "format"])) : customComponent.value ? (openBlock(), createBlock(resolveDynamicComponent(customComponent.value), mergeProps({
              key: 8,
              value: fieldValue.value,
              field: _ctx.field,
              disabled: isDisabled.value
            }, mergedComponentProps.value, {
              "onUpdate:value": handleValueChange,
              onBlur: handleBlur,
              onFocus: handleFocus
            }, toHandlers(customComponentEvents.value)), null, 16, ["value", "field", "disabled"])) : (openBlock(), createElementBlock("div", _hoisted_8, [
              createElementVNode("div", _hoisted_9, [
                createVNode(unref(ExclamationCircleOutlined)),
                createTextVNode(" 不支持的字段类型: " + toDisplayString(_ctx.field.type), 1)
              ]),
              createElementVNode("div", _hoisted_10, [
                createElementVNode("p", null, "字段名: " + toDisplayString(_ctx.field.name), 1),
                _cache[4] || (_cache[4] = createElementVNode("p", null, "可能的解决方案:", -1)),
                _cache[5] || (_cache[5] = createElementVNode("ul", null, [
                  createElementVNode("li", null, "检查字段类型是否拼写正确"),
                  createElementVNode("li", null, "确保自定义组件已正确注册"),
                  createElementVNode("li", null, "使用 component 属性直接指定组件"),
                  createElementVNode("li", null, "联系开发者添加对该字段类型的支持")
                ], -1)),
                createElementVNode("div", _hoisted_11, [
                  createElementVNode("details", null, [
                    _cache[3] || (_cache[3] = createElementVNode("summary", null, "调试信息", -1)),
                    createElementVNode("p", null, "已注册的组件类型: " + toDisplayString(Object.keys(((_i = unref(formContext)) == null ? void 0 : _i.componentRegistry.getAll()) || {}).join(", ") || "无"), 1),
                    createElementVNode("p", null, "字段配置: " + toDisplayString(JSON.stringify(_ctx.field, null, 2)), 1)
                  ])
                ])
              ])
            ]))
          ])
        ], 64)),
        isValidating.value ? (openBlock(), createElementBlock("div", _hoisted_12, [
          createVNode(_component_a_spin, { size: "small" }),
          _cache[6] || (_cache[6] = createTextVNode(" 验证中... ", -1))
        ])) : hasError.value ? (openBlock(), createElementBlock("div", _hoisted_13, toDisplayString(errorMessage.value), 1)) : createCommentVNode("", true)
      ], 6);
    };
  }
});
const SimpleFormItem = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__scopeId", "data-v-91a77669"]]);
const _hoisted_1$2 = {
  key: 0,
  class: "simple-form-actions inline-actions"
};
const _hoisted_2$2 = {
  key: 2,
  class: "simple-form-actions"
};
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
  __name: "SimpleForm",
  props: {
    schema: {},
    modelValue: {},
    showActions: { type: Boolean, default: true },
    showReset: { type: Boolean, default: true },
    submitText: { default: "提交" },
    resetText: { default: "重置" },
    submitting: { type: Boolean, default: false },
    validateOnChange: { type: Boolean, default: true }
  },
  emits: ["update:modelValue", "submit", "reset", "change", "validate"],
  setup(__props, { expose: __expose, emit: __emit }) {
    const props = __props;
    const emit = __emit;
    const formContext = useSimpleForm(props.schema, props.modelValue);
    const formLayout = computed(() => props.schema.layout || {});
    provide("formContext", formContext);
    provide("formLayout", formLayout);
    const visibleFields = computed(() => {
      return props.schema.fields.filter((field) => {
        var _a;
        if (!((_a = field.linkage) == null ? void 0 : _a.visibleWhen)) return true;
        const dependentValue = field.linkage.dependsOn ? formContext.getValue(field.linkage.dependsOn) : void 0;
        return field.linkage.visibleWhen(dependentValue, formContext.formData);
      });
    });
    const isGridLayout = computed(() => {
      const layoutType = formLayout.value.type;
      return layoutType === "horizontal" || layoutType === "grid";
    });
    const formLayoutClasses = computed(() => {
      const classes = [];
      const layoutType = formLayout.value.type || "vertical";
      classes.push(`simple-form-${layoutType}`);
      if (formLayout.value.labelAlign) {
        classes.push(`simple-form-label-${formLayout.value.labelAlign}`);
      }
      return classes;
    });
    const fieldsContainerClass = computed(() => {
      const layoutType = formLayout.value.type || "vertical";
      return `simple-form-fields simple-form-fields-${layoutType}`;
    });
    const isInlineLayout = computed(() => (formLayout.value.type || "vertical") === "inline");
    const gutterConfig = computed(() => {
      const gutter = formLayout.value.gutter;
      if (Array.isArray(gutter)) {
        return gutter;
      }
      return gutter ? [gutter, gutter] : [16, 16];
    });
    const submitButtonConfig = computed(() => {
      const defaultConfig = {
        text: props.submitText,
        type: "primary",
        size: "middle",
        loading: false,
        disabled: false,
        htmlType: "submit"
      };
      if (props.schema.submitButton) {
        return __spreadValues(__spreadValues({}, defaultConfig), props.schema.submitButton);
      }
      return defaultConfig;
    });
    const getFieldSpan = (field) => {
      var _a, _b;
      if ((_a = field.layout) == null ? void 0 : _a.span) return field.layout.span;
      const cols = formLayout.value.cols || formLayout.value.columns;
      if (cols) {
        const baseSpan = Math.floor(24 / cols);
        const colSpan = ((_b = field.layout) == null ? void 0 : _b.colSpan) || 1;
        return baseSpan * colSpan;
      }
      return 24;
    };
    const getFieldOffset = (field) => {
      var _a;
      return ((_a = field.layout) == null ? void 0 : _a.offset) || 0;
    };
    const getResponsiveSpan = (breakpoint, field) => {
      const breakpoints = formLayout.value.breakpoints;
      if (breakpoints && breakpoints[breakpoint]) {
        return Math.floor(24 / breakpoints[breakpoint]);
      }
      return void 0;
    };
    const getFieldItemClass = (field) => {
      var _a;
      const classes = [];
      if ((_a = field.layout) == null ? void 0 : _a.className) {
        classes.push(field.layout.className);
      }
      return classes.join(" ");
    };
    const getFieldItemStyle = (field) => {
      var _a;
      return ((_a = field.layout) == null ? void 0 : _a.style) || {};
    };
    const getFieldsContainerStyle = () => {
      const layoutType = formLayout.value.type || "vertical";
      const gutter = gutterConfig.value;
      const [horizontalGutter, verticalGutter] = Array.isArray(gutter) ? gutter : [gutter, gutter];
      const styles = {};
      if (layoutType === "vertical" && verticalGutter > 0) {
        styles.gap = `${verticalGutter}px`;
        styles.display = "flex";
        styles.flexDirection = "column";
      } else if (layoutType === "inline" && horizontalGutter > 0) {
        styles.gap = `${horizontalGutter}px`;
        styles.display = "flex";
        styles.flexWrap = "wrap";
        styles.alignItems = "center";
      }
      return styles;
    };
    watch(
      () => formContext.formValues.value,
      (newValue) => {
        emit("update:modelValue", newValue);
        emit("change", newValue);
        if (props.validateOnChange) {
          const isValid = formContext.validateForm();
          emit("validate", isValid, formContext.errors.value);
        }
      },
      { deep: true }
    );
    watch(
      () => props.modelValue,
      (newValue) => {
        if (newValue && JSON.stringify(newValue) !== JSON.stringify(formContext.formValues.value)) {
          Object.keys(formContext.formData).forEach((key) => {
            delete formContext.formData[key];
          });
          Object.assign(formContext.formData, newValue);
        }
      },
      { deep: true }
    );
    const handleSubmit = () => {
      const isValid = formContext.validateForm();
      if (isValid) {
        emit("submit", formContext.formValues.value);
      } else {
        emit("validate", false, formContext.errors.value);
      }
    };
    const handleReset = () => {
      formContext.resetForm();
      emit("reset");
    };
    onMounted(() => __async(this, null, function* () {
      yield formContext.initializeAsync();
    }));
    __expose({
      validate: formContext.validateForm,
      validateAsync: formContext.validateFieldAsync,
      reset: formContext.resetForm,
      setFieldValue: formContext.setValue,
      getFieldValue: formContext.getValue,
      formData: formContext.formValues,
      getAsyncState: formContext.getAsyncState,
      initializeAsync: formContext.initializeAsync,
      // 组件注册功能
      registerComponent: formContext.componentRegistry.register,
      unregisterComponent: formContext.componentRegistry.unregister,
      getComponent: formContext.componentRegistry.get,
      hasComponent: formContext.componentRegistry.has,
      getAllComponents: formContext.componentRegistry.getAll,
      clearComponents: formContext.componentRegistry.clear
    });
    return (_ctx, _cache) => {
      var _a, _b;
      const _component_a_col = resolveComponent("a-col");
      const _component_a_row = resolveComponent("a-row");
      const _component_a_button = resolveComponent("a-button");
      return openBlock(), createElementBlock("div", {
        class: normalizeClass(["simple-form", formLayoutClasses.value])
      }, [
        isGridLayout.value ? (openBlock(), createBlock(_component_a_row, {
          key: 0,
          gutter: gutterConfig.value
        }, {
          default: withCtx(() => [
            (openBlock(true), createElementBlock(Fragment, null, renderList(visibleFields.value, (field) => {
              return openBlock(), createBlock(_component_a_col, {
                key: field.name,
                span: getFieldSpan(field),
                offset: getFieldOffset(field),
                xs: getResponsiveSpan("xs"),
                sm: getResponsiveSpan("sm"),
                md: getResponsiveSpan("md"),
                lg: getResponsiveSpan("lg"),
                xl: getResponsiveSpan("xl"),
                xxl: getResponsiveSpan("xxl")
              }, {
                default: withCtx(() => [
                  createVNode(SimpleFormItem, { field }, null, 8, ["field"])
                ]),
                _: 2
              }, 1032, ["span", "offset", "xs", "sm", "md", "lg", "xl", "xxl"]);
            }), 128))
          ]),
          _: 1
        }, 8, ["gutter"])) : (openBlock(), createElementBlock("div", {
          key: 1,
          class: normalizeClass(fieldsContainerClass.value),
          style: normalizeStyle(getFieldsContainerStyle())
        }, [
          (openBlock(true), createElementBlock(Fragment, null, renderList(visibleFields.value, (field) => {
            return openBlock(), createBlock(SimpleFormItem, {
              key: field.name,
              field,
              class: normalizeClass(getFieldItemClass(field)),
              style: normalizeStyle(getFieldItemStyle(field))
            }, null, 8, ["field", "class", "style"]);
          }), 128)),
          _ctx.showActions && isInlineLayout.value ? (openBlock(), createElementBlock("div", _hoisted_1$2, [
            createVNode(_component_a_button, {
              type: submitButtonConfig.value.type,
              size: submitButtonConfig.value.size,
              loading: _ctx.submitting || submitButtonConfig.value.loading,
              disabled: submitButtonConfig.value.disabled,
              "html-type": submitButtonConfig.value.htmlType,
              onClick: handleSubmit
            }, {
              default: withCtx(() => [
                createTextVNode(toDisplayString(submitButtonConfig.value.text), 1)
              ]),
              _: 1
            }, 8, ["type", "size", "loading", "disabled", "html-type"]),
            _ctx.showReset && !((_a = _ctx.schema.extraButtons) == null ? void 0 : _a.length) ? (openBlock(), createBlock(_component_a_button, {
              key: 0,
              onClick: handleReset
            }, {
              default: withCtx(() => [
                createTextVNode(toDisplayString(_ctx.resetText), 1)
              ]),
              _: 1
            })) : createCommentVNode("", true),
            (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.schema.extraButtons, (button, index2) => {
              return openBlock(), createBlock(_component_a_button, {
                key: `inline-extra-button-${index2}`,
                type: button.type,
                size: button.size,
                loading: button.loading,
                disabled: button.disabled,
                onClick: button.onClick
              }, createSlots({
                default: withCtx(() => [
                  createTextVNode(" " + toDisplayString(button.text), 1)
                ]),
                _: 2
              }, [
                button.icon ? {
                  name: "icon",
                  fn: withCtx(() => [
                    button.icon === "down" ? (openBlock(), createBlock(unref(DownOutlined), { key: 0 })) : createCommentVNode("", true)
                  ]),
                  key: "0"
                } : void 0
              ]), 1032, ["type", "size", "loading", "disabled", "onClick"]);
            }), 128))
          ])) : createCommentVNode("", true)
        ], 6)),
        _ctx.showActions && !isInlineLayout.value ? (openBlock(), createElementBlock("div", _hoisted_2$2, [
          createVNode(_component_a_button, {
            type: submitButtonConfig.value.type,
            size: submitButtonConfig.value.size,
            loading: _ctx.submitting || submitButtonConfig.value.loading,
            disabled: submitButtonConfig.value.disabled,
            "html-type": submitButtonConfig.value.htmlType,
            onClick: handleSubmit
          }, {
            default: withCtx(() => [
              createTextVNode(toDisplayString(submitButtonConfig.value.text), 1)
            ]),
            _: 1
          }, 8, ["type", "size", "loading", "disabled", "html-type"]),
          _ctx.showReset && !((_b = _ctx.schema.extraButtons) == null ? void 0 : _b.length) ? (openBlock(), createBlock(_component_a_button, {
            key: 0,
            onClick: handleReset
          }, {
            default: withCtx(() => [
              createTextVNode(toDisplayString(_ctx.resetText), 1)
            ]),
            _: 1
          })) : createCommentVNode("", true),
          (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.schema.extraButtons, (button, index2) => {
            return openBlock(), createBlock(_component_a_button, {
              key: `extra-button-${index2}`,
              type: button.type,
              size: button.size,
              loading: button.loading,
              disabled: button.disabled,
              onClick: button.onClick
            }, createSlots({
              default: withCtx(() => [
                createTextVNode(" " + toDisplayString(button.text), 1)
              ]),
              _: 2
            }, [
              button.icon ? {
                name: "icon",
                fn: withCtx(() => [
                  button.icon === "down" ? (openBlock(), createBlock(unref(DownOutlined), { key: 0 })) : createCommentVNode("", true)
                ]),
                key: "0"
              } : void 0
            ]), 1032, ["type", "size", "loading", "disabled", "onClick"]);
          }), 128))
        ])) : createCommentVNode("", true)
      ], 2);
    };
  }
});
const SimpleForm = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-3cfaf46c"]]);
const _hoisted_1$1 = { class: "custom-rating-field" };
const _hoisted_2$1 = { class: "rating-stars" };
const _hoisted_3$1 = ["onClick", "onMouseenter"];
const _hoisted_4$1 = {
  key: 0,
  class: "rating-text"
};
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
  __name: "CustomRatingField",
  props: {
    value: { default: 0 },
    field: {},
    disabled: { type: Boolean, default: false },
    maxStars: { default: 5 },
    showText: { type: Boolean, default: true },
    textLabels: { default: () => ["很差", "较差", "一般", "较好", "很好"] }
  },
  emits: ["update:value", "blur", "focus"],
  setup(__props, { emit: __emit }) {
    const props = __props;
    const emit = __emit;
    const currentValue = ref(props.value || 0);
    const hoverValue = ref(0);
    watch(
      () => props.value,
      (newValue) => {
        currentValue.value = newValue || 0;
      }
    );
    computed(() => {
      return hoverValue.value || currentValue.value;
    });
    const handleStarClick = (star) => {
      currentValue.value = star;
      emit("update:value", star);
      emit("blur");
    };
    const handleStarHover = (star) => {
      hoverValue.value = star;
    };
    const handleStarLeave = () => {
      hoverValue.value = 0;
    };
    const getRatingText = (rating) => {
      if (rating === 0) return "未评分";
      const index2 = Math.min(rating - 1, props.textLabels.length - 1);
      return props.textLabels[index2] || `${rating}星`;
    };
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", _hoisted_1$1, [
        createElementVNode("div", _hoisted_2$1, [
          (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.maxStars, (star) => {
            return openBlock(), createElementBlock("span", {
              key: star,
              class: normalizeClass(["star", { active: star <= currentValue.value, disabled: _ctx.disabled }]),
              onClick: ($event) => !_ctx.disabled && handleStarClick(star),
              onMouseenter: ($event) => !_ctx.disabled && handleStarHover(star),
              onMouseleave: _cache[0] || (_cache[0] = ($event) => !_ctx.disabled && handleStarLeave())
            }, " ★ ", 42, _hoisted_3$1);
          }), 128))
        ]),
        _ctx.showText ? (openBlock(), createElementBlock("div", _hoisted_4$1, toDisplayString(getRatingText(currentValue.value)), 1)) : createCommentVNode("", true)
      ]);
    };
  }
});
const CustomRatingField = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-24777e9b"]]);
const _hoisted_1 = { class: "custom-color-picker" };
const _hoisted_2 = {
  key: 0,
  class: "placeholder"
};
const _hoisted_3 = ["disabled"];
const _hoisted_4 = {
  key: 1,
  class: "preset-colors"
};
const _hoisted_5 = ["onClick"];
const _sfc_main = /* @__PURE__ */ defineComponent({
  __name: "CustomColorPicker",
  props: {
    value: { default: "" },
    field: {},
    disabled: { type: Boolean, default: false },
    showInput: { type: Boolean, default: true },
    showPresetColors: { type: Boolean, default: true },
    presetColors: { default: () => [
      "#ff4d4f",
      "#fa541c",
      "#fa8c16",
      "#faad14",
      "#fadb14",
      "#a0d911",
      "#52c41a",
      "#13c2c2",
      "#1890ff",
      "#2f54eb",
      "#722ed1",
      "#eb2f96",
      "#f5222d",
      "#fa8c16",
      "#fadb14"
    ] }
  },
  emits: ["update:value", "blur", "focus"],
  setup(__props, { emit: __emit }) {
    const props = __props;
    const emit = __emit;
    const currentColor = ref(props.value || "");
    watch(
      () => props.value,
      (newValue) => {
        currentColor.value = newValue || "";
      }
    );
    const handleColorChange = (event) => {
      const target = event.target;
      currentColor.value = target.value;
      emit("update:value", target.value);
    };
    const selectPresetColor = (color) => {
      currentColor.value = color;
      emit("update:value", color);
      emit("blur");
    };
    const togglePicker = () => {
      const colorInput = document.querySelector(".color-input");
      if (colorInput) {
        colorInput.click();
      }
    };
    const handleBlur = () => {
      emit("blur");
    };
    const handleFocus = () => {
      emit("focus");
    };
    return (_ctx, _cache) => {
      return openBlock(), createElementBlock("div", _hoisted_1, [
        createElementVNode("div", {
          class: "color-display",
          style: normalizeStyle({ backgroundColor: currentColor.value }),
          onClick: _cache[0] || (_cache[0] = ($event) => !_ctx.disabled && togglePicker)
        }, [
          !currentColor.value ? (openBlock(), createElementBlock("span", _hoisted_2, toDisplayString(_ctx.field.placeholder || "选择颜色"), 1)) : createCommentVNode("", true)
        ], 4),
        _ctx.showInput ? withDirectives((openBlock(), createElementBlock("input", {
          key: 0,
          "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => currentColor.value = $event),
          type: "color",
          disabled: _ctx.disabled,
          class: "color-input",
          onChange: handleColorChange,
          onBlur: handleBlur,
          onFocus: handleFocus
        }, null, 40, _hoisted_3)), [
          [vModelText, currentColor.value]
        ]) : createCommentVNode("", true),
        _ctx.showPresetColors ? (openBlock(), createElementBlock("div", _hoisted_4, [
          (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.presetColors, (color) => {
            return openBlock(), createElementBlock("div", {
              key: color,
              class: normalizeClass(["preset-color", { active: currentColor.value === color, disabled: _ctx.disabled }]),
              style: normalizeStyle({ backgroundColor: color }),
              onClick: ($event) => !_ctx.disabled && selectPresetColor(color)
            }, null, 14, _hoisted_5);
          }), 128))
        ])) : createCommentVNode("", true)
      ]);
    };
  }
});
const CustomColorPicker = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-f46e8b99"]]);
const install = (app, options = {}) => {
  const { componentPrefix = "Simple", customComponents } = options;
  app.component(`${componentPrefix}Form`, SimpleForm);
  SimpleFormPlugin.install(app, { components: customComponents });
  app.config.globalProperties.$dynamicForm = {
    version: "2.0.0",
    debug: options.debug || false,
    architecture: "simplified",
    customComponentsEnabled: true
  };
  app.provide("dynamicFormGlobalConfig", options);
};
const index = {
  install,
  version: "2.0.0",
  architecture: "simplified"
};
const createFormSchema = (fields, options = {}) => {
  return __spreadValues({
    fields
  }, options);
};
const createFieldConfig = (config) => {
  return __spreadValues({
    name: "",
    type: "input",
    label: "",
    required: false,
    placeholder: "",
    options: [],
    rules: []
  }, config);
};
const VERSION_INFO = {
  current: "2.0.0",
  architecture: "simplified"
};
export {
  CustomColorPicker,
  CustomRatingField,
  SimpleForm,
  SimpleFormItem,
  SimpleFormPlugin,
  SimpleGroup,
  _sfc_main$7 as SimpleInput,
  _sfc_main$5 as SimpleRadio,
  _sfc_main$6 as SimpleSelect,
  VERSION_INFO,
  createComponentRegistry,
  createFieldConfig,
  createFormSchema,
  index as default,
  deleteByPath,
  getAllPaths,
  getByPath,
  globalComponentRegistry,
  hasPath,
  install,
  setByPath,
  useSimpleForm
};