@schemx/vue 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +491 -326
  2. package/dist/analyze.html +1 -1
  3. package/dist/bridge/formBridge.d.ts +4 -4
  4. package/dist/bridge/formBridge.d.ts.map +1 -1
  5. package/dist/bridge/formInstance.d.ts +4 -3
  6. package/dist/bridge/formInstance.d.ts.map +1 -1
  7. package/dist/bridge/index.d.ts +1 -2
  8. package/dist/bridge/index.d.ts.map +1 -1
  9. package/dist/bridge/types.d.ts +4 -6
  10. package/dist/bridge/types.d.ts.map +1 -1
  11. package/dist/components/Col/index.d.ts +29 -6
  12. package/dist/components/Col/index.d.ts.map +1 -1
  13. package/dist/components/ConfigProvider/index.d.ts +32 -5
  14. package/dist/components/ConfigProvider/index.d.ts.map +1 -1
  15. package/dist/components/Dynamic/index.d.ts +19 -15
  16. package/dist/components/Dynamic/index.d.ts.map +1 -1
  17. package/dist/components/Field/index.d.ts.map +1 -1
  18. package/dist/components/Field/slot.d.ts +2 -1
  19. package/dist/components/Field/slot.d.ts.map +1 -1
  20. package/dist/components/Group/index.d.ts +23 -4
  21. package/dist/components/Group/index.d.ts.map +1 -1
  22. package/dist/components/Icon/index.d.ts +29 -0
  23. package/dist/components/Icon/index.d.ts.map +1 -0
  24. package/dist/components/Row/index.d.ts +30 -0
  25. package/dist/components/Row/index.d.ts.map +1 -0
  26. package/dist/components/SchemaList/index.d.ts +8 -8
  27. package/dist/components/SchemaList/index.d.ts.map +1 -1
  28. package/dist/config/defaultVueSchemaConfig.d.ts +25 -3
  29. package/dist/config/defaultVueSchemaConfig.d.ts.map +1 -1
  30. package/dist/config/index.d.ts +0 -4
  31. package/dist/config/index.d.ts.map +1 -1
  32. package/dist/config/vueConfig.d.ts +10 -6
  33. package/dist/config/vueConfig.d.ts.map +1 -1
  34. package/dist/context/configProviderContext.d.ts +56 -5
  35. package/dist/context/configProviderContext.d.ts.map +1 -1
  36. package/dist/context/formContext.d.ts +127 -36
  37. package/dist/context/formContext.d.ts.map +1 -1
  38. package/dist/context/index.d.ts +2 -2
  39. package/dist/context/index.d.ts.map +1 -1
  40. package/dist/form.d.ts +2 -2
  41. package/dist/form.d.ts.map +1 -1
  42. package/dist/hooks/index.d.ts +2 -4
  43. package/dist/hooks/index.d.ts.map +1 -1
  44. package/dist/hooks/useDictionary.d.ts +1 -1
  45. package/dist/hooks/useForm.d.ts +4 -16
  46. package/dist/hooks/useForm.d.ts.map +1 -1
  47. package/dist/index.cjs +1 -1
  48. package/dist/index.cjs.map +1 -1
  49. package/dist/index.d.ts +5 -5
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.mjs +554 -287
  52. package/dist/index.mjs.map +1 -1
  53. package/dist/style.css +1 -1
  54. package/dist/types/definition.d.ts +116 -21
  55. package/dist/types/definition.d.ts.map +1 -1
  56. package/dist/types/field.d.ts +4 -27
  57. package/dist/types/field.d.ts.map +1 -1
  58. package/dist/types/form.d.ts +41 -6
  59. package/dist/types/form.d.ts.map +1 -1
  60. package/dist/types/icon.d.ts +15 -0
  61. package/dist/types/icon.d.ts.map +1 -0
  62. package/dist/types/index.d.ts +2 -0
  63. package/dist/types/index.d.ts.map +1 -1
  64. package/dist/types/layout.d.ts +73 -22
  65. package/dist/types/layout.d.ts.map +1 -1
  66. package/dist/utils/index.d.ts +4 -0
  67. package/dist/utils/index.d.ts.map +1 -1
  68. package/dist/utils/layout.d.ts +17 -0
  69. package/dist/utils/layout.d.ts.map +1 -0
  70. package/dist/utils/rendererProvider.d.ts +10 -3
  71. package/dist/utils/rendererProvider.d.ts.map +1 -1
  72. package/package.json +2 -2
  73. package/dist/config/appConfig.d.ts +0 -29
  74. package/dist/config/appConfig.d.ts.map +0 -1
  75. package/dist/utils/colProvider.d.ts +0 -22
  76. package/dist/utils/colProvider.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/bridge/helpers.ts","../src/bridge/fieldBridge.ts","../src/bridge/formInstance.ts","../src/bridge/viewSchemaBridge.ts","../src/bridge/formBridge.ts","../src/context/formContext.ts","../src/context/fieldContext.ts","../src/context/configProviderContext.ts","../src/config/appConfig.ts","../src/utils/presetRuleProvider.ts","../src/utils/rendererProvider.ts","../src/config/vueConfig.ts","../src/config/defaultVueSchemaConfig.ts","../src/hooks/useForm.ts","../src/hooks/useField.ts","../src/hooks/useWatch.ts","../src/hooks/useDictionary.ts","../src/utils/equal.ts","../src/hooks/useStableRef.ts","../src/hooks/useViewSchemas.ts","../src/hooks/useFormSelector.ts","../src/utils/validation.ts","../src/utils/slot.ts","../src/utils/helpers.ts","../src/components/Field/slot.tsx","../src/components/Field/index.tsx","../src/components/Button/index.vue","../src/utils/colProvider.ts","../src/components/Col/index.tsx","../src/components/Group/slot.tsx","../src/components/Group/index.tsx","../src/components/Dynamic/index.tsx","../src/components/SchemaList/index.tsx","../src/form.vue","../src/form.ts","../src/hocs/withRemoteOptions.ts","../src/components/Wrapper/index.vue","../src/components/ConfigProvider/index.tsx"],"sourcesContent":["/**\n * Vue Runtime 使用的 Ref 和快照比较工具。\n *\n * @module vue/bridge/helpers\n */\n\nimport { shallowRef } from \"vue\"\nimport type { ShallowRef } from \"vue\"\n\nimport type { SnapshotSource } from \"@schemx/core/adapter\"\n\n/**\n * 创建类型为 `ShallowRef` 的 Vue 浅层 Ref。\n *\n * 运行时直接委托 Vue 的 `shallowRef`,类型断言用于保留 Runtime 对快照引用的控制。\n *\n * @typeParam TValue - Ref 中保存的值类型。\n * @param value - 要包装为 shallow Ref 的当前值。\n * @returns 包装后的 shallow Ref。\n *\n * @example\n * ```ts\n * const ready = createVueShallowRef(false)\n * ready.value = true\n * ```\n */\nexport function createVueShallowRef<TValue>(value: TValue): ShallowRef<TValue> {\n return shallowRef(value) as ShallowRef<TValue>\n}\n\n/**\n * 将 Core SnapshotSource 绑定为 Vue shallow Ref。\n *\n * SnapshotSource 的生命周期由所属 FormStateAdapter 统一管理;这里仅保留\n * 同步逻辑,避免每个 Form 级来源重复声明一套订阅函数。\n *\n * @param source - 提供快照和订阅能力的 Core Source。\n * @returns 与 Source 当前快照同步的 Vue shallow Ref。\n *\n * @example\n * ```ts\n * const values = bindSnapshotSource(stateAdapter.values)\n * ```\n */\nexport function bindSnapshotSource<TValue>(\n source: SnapshotSource<TValue>\n): ShallowRef<TValue> {\n const value = createVueShallowRef(source.getSnapshot())\n\n source.subscribe(() => {\n value.value = source.getSnapshot()\n })\n\n return value\n}\n\n/**\n * 比较两份错误消息列表,避免无变化时写入 Vue Ref。\n *\n * @param previous - 当前 Ref 中保存的错误消息列表。\n * @param next - SnapshotSource 返回的最新错误消息列表。\n * @returns 两个列表的长度和每一项都相同时返回 `true`。\n *\n * @example\n * ```ts\n * const changed = !areStringListsEqual(previous, next)\n * ```\n */\nexport function areStringListsEqual(\n previous: readonly string[],\n next: readonly string[]\n): boolean {\n return (\n previous.length === next.length &&\n previous.every((value, index) => value === next[index])\n )\n}\n","/**\n * 将 Core 字段快照投影为可共享的 Vue Ref。\n *\n * 字段投影只负责创建状态;来源订阅由所属 FormStateAdapter 统一回收。\n *\n * @module vue/bridge/fieldBridge\n */\n\nimport { areStringListsEqual, createVueShallowRef } from \"./helpers\"\n\nimport type { VueFieldState, VueFormResources } from \"./types\"\nimport type { FieldValue, NamePath, Values } from \"@schemx/core\"\n\n/**\n * 获取一个字段的共享 Vue 状态投影。\n *\n * FormStateAdapter 按规范化路径缓存 Source;Source 身份作为当前资源中的\n * 稳定 key,确保同一字段不会重复创建订阅。\n *\n * @typeParam TValues - 表单值类型。\n * @typeParam TName - 当前字段路径类型。\n * @param resources - 当前 Runtime 的响应式资源集合。\n * @param name - 要读取状态的字段路径。\n * @returns 当前字段的共享 Vue 状态投影。\n *\n * @example\n * ```ts\n * const state = getVueFieldState(resources, \"name\")\n * console.log(state.value.value)\n * ```\n */\nexport function getVueFieldState<\n TValues extends Values = Values,\n TName extends NamePath<TValues> = NamePath<TValues>,\n>(resources: VueFormResources<TValues>, name: TName): VueFieldState<TValues, TName> {\n const source = resources.stateAdapter.field(name)\n\n const cachedState = resources.fieldStates.get(source as object)\n\n if (cachedState) {\n return cachedState as VueFieldState<TValues, TName>\n }\n\n const snapshot = source.getSnapshot()\n\n const value = createVueShallowRef<FieldValue<TValues, TName> | undefined>(\n snapshot.value\n )\n\n const errors = createVueShallowRef<readonly string[]>(snapshot.errors)\n\n const touched = createVueShallowRef<boolean>(snapshot.touched)\n\n const pending = createVueShallowRef<boolean>(snapshot.pending)\n\n const updateFieldState = (): void => {\n const nextSnapshot = source.getSnapshot()\n\n if (!Object.is(value.value, nextSnapshot.value)) {\n value.value = nextSnapshot.value\n }\n\n if (!areStringListsEqual(errors.value, nextSnapshot.errors)) {\n errors.value = nextSnapshot.errors\n }\n\n if (touched.value !== nextSnapshot.touched) {\n touched.value = nextSnapshot.touched\n }\n\n if (pending.value !== nextSnapshot.pending) {\n pending.value = nextSnapshot.pending\n }\n }\n\n source.subscribe(updateFieldState)\n\n const fieldState: VueFieldState<TValues, TName> = {\n value,\n errors,\n touched,\n pending,\n }\n\n resources.fieldStates.set(source as object, fieldState as VueFieldState<TValues>)\n\n return fieldState\n}\n","/**\n * 创建保持 Core API 的 Vue Instance。\n *\n * Instance 只负责把读取动作转成 Runtime 依赖收集,资源缓存和生命周期\n * 由所属 VueFormRuntime 管理。\n *\n * @module vue/bridge/formInstance\n */\n\nimport type { VueFieldDependency, VueFormDependency, VueSchemxInstance } from \"./types\"\nimport type { NamePath, SchemxInstance, Values } from \"@schemx/core\"\n\n/**\n * 创建 Instance 所需的 Runtime 追踪能力。\n */\nexport interface VueFormInstanceDependencies<TValues extends Values> {\n /**\n * 追踪单个字段的指定状态依赖。\n */\n trackField<TName extends NamePath<TValues>>(\n name: TName,\n dependency: VueFieldDependency\n ): void\n /**\n * 追踪完整表单值或指定字段值。\n */\n trackFieldsValue(names?: NamePath<TValues>[]): void\n /**\n * 追踪 Form 级聚合状态。\n */\n trackForm(dependency: VueFormDependency): void\n /**\n * 销毁 Runtime 持有的响应式资源。\n */\n destroy(): void\n}\n\n/**\n * 为 Core Form 创建保持完整 API 的 Vue Instance。\n *\n * @param form - 要包装的原始 Core Form。\n * @param dependencies - 所属 Runtime 提供的依赖追踪与销毁能力。\n * @returns 可被 Vue effect 追踪的 Instance。\n *\n * @example\n * ```ts\n * const instance = createVueFormInstance(coreForm, runtimeDependencies)\n * ```\n */\nexport function createVueFormInstance<TValues extends Values>(\n form: SchemxInstance<TValues>,\n dependencies: VueFormInstanceDependencies<TValues>\n): VueSchemxInstance<TValues> {\n let destroyed = false\n\n const getFieldValue: SchemxInstance<TValues>[\"getFieldValue\"] = (name) => {\n if (!destroyed) {\n dependencies.trackField(name, \"value\")\n }\n\n return form.getFieldValue(name)\n }\n\n const getFieldErrors: SchemxInstance<TValues>[\"getFieldErrors\"] = (name) => {\n if (!destroyed) {\n dependencies.trackField(name, \"errors\")\n }\n\n return form.getFieldErrors(name)\n }\n\n const isFieldTouched: SchemxInstance<TValues>[\"isFieldTouched\"] = (name) => {\n if (!destroyed) {\n dependencies.trackField(name, \"touched\")\n }\n\n return form.isFieldTouched(name)\n }\n\n const isFieldPending: SchemxInstance<TValues>[\"isFieldPending\"] = (name) => {\n if (!destroyed) {\n dependencies.trackField(name, \"pending\")\n }\n\n return form.isFieldPending(name)\n }\n\n const getFieldsValue = ((names?: NamePath<TValues>[]) => {\n if (!destroyed) {\n dependencies.trackFieldsValue(names)\n }\n\n return form.getFieldsValue(names)\n }) as SchemxInstance<TValues>[\"getFieldsValue\"]\n\n const getTouchedFields: SchemxInstance<TValues>[\"getTouchedFields\"] = () => {\n if (!destroyed) {\n dependencies.trackForm(\"touchedFields\")\n }\n\n return form.getTouchedFields()\n }\n\n const getPendingFields: SchemxInstance<TValues>[\"getPendingFields\"] = () => {\n if (!destroyed) {\n dependencies.trackForm(\"pendingFields\")\n }\n\n return form.getPendingFields()\n }\n\n const isLoading: SchemxInstance<TValues>[\"isLoading\"] = () => {\n if (!destroyed) {\n dependencies.trackForm(\"loading\")\n }\n\n return form.isLoading()\n }\n\n const destroy: SchemxInstance<TValues>[\"destroy\"] = () => {\n if (destroyed) {\n return\n }\n\n destroyed = true\n dependencies.destroy()\n form.destroy()\n }\n\n return {\n ...form,\n getFieldValue,\n getFieldErrors,\n isFieldTouched,\n isFieldPending,\n getFieldsValue,\n getTouchedFields,\n getPendingFields,\n isLoading,\n destroy,\n }\n}\n","/**\n * 将 Core ViewSchema 列表投影为共享的 Vue 状态。\n *\n * @module vue/bridge/viewSchemaBridge\n */\n\nimport { computed, shallowRef } from \"vue\"\n\nimport { isViewDynamicSchema, isViewGroupSchema } from \"@schemx/core\"\n\nimport type { VueViewSchemaState } from \"./types\"\nimport type { SchemxInstance, SchemxViewSchema, Values } from \"@schemx/core\"\n\n/**\n * 创建一个 Form 的共享 ViewSchema 状态。\n *\n * @typeParam TValues - 表单值类型。\n * @param form - 要订阅 ViewSchema 的 Core Form。\n * @returns 当前 Form 的 ViewSchema 列表、索引和释放方法。\n *\n * @example\n * ```ts\n * const state = createVueViewSchemaState(form)\n * const current = state.viewSchemas.value\n * state.dispose()\n * ```\n */\nexport function createVueViewSchemaState<TValues extends Values>(\n form: SchemxInstance<TValues>\n): VueViewSchemaState<TValues> {\n const viewSchemas = shallowRef<readonly SchemxViewSchema<TValues>[]>(\n form.getViewSchemas()\n )\n\n const schemasByKey = computed<ReadonlyMap<string, SchemxViewSchema<TValues>>>(() => {\n return createViewSchemaIndex(viewSchemas.value)\n })\n\n const unsubscribe = form.subscribeViewSchemas((nextSchemas) => {\n viewSchemas.value = nextSchemas\n })\n\n let disposed = false\n\n const dispose = (): void => {\n if (disposed) {\n return\n }\n\n disposed = true\n unsubscribe()\n }\n\n return {\n schemasByKey,\n viewSchemas,\n dispose,\n }\n}\n\n/**\n * 递归索引顶层和分组内的 ViewSchema。\n *\n * @param viewSchemas - 待索引的 ViewSchema 列表。\n * @returns 按 key 建立的 ViewSchema 索引。\n */\nfunction createViewSchemaIndex<TValues extends Values>(\n viewSchemas: readonly SchemxViewSchema<TValues>[]\n): ReadonlyMap<string, SchemxViewSchema<TValues>> {\n const schemasByKey = new Map<string, SchemxViewSchema<TValues>>()\n\n /**\n * 递归写入当前层级及其嵌套子节点的 ViewSchema 索引。\n *\n * @param schemas - 当前层级的 ViewSchema 列表。\n */\n const appendSchemas = (schemas: readonly SchemxViewSchema<TValues>[]): void => {\n for (const schema of schemas) {\n schemasByKey.set(schema.key, schema)\n\n if (isViewGroupSchema(schema)) {\n appendSchemas(schema.children)\n } else if (isViewDynamicSchema(schema)) {\n for (const item of schema.items) {\n appendSchemas(item.children)\n }\n }\n }\n }\n\n appendSchemas(viewSchemas)\n\n return schemasByKey\n}\n","/**\n * Core Form 到 Vue 响应式状态的共享 Runtime。\n *\n * 每个 Core Form 只有一个稳定 Runtime 和一个 Vue Instance;响应式资源按\n * Vue owner 激活和释放,避免调用方同时管理 Runtime、Adapter 和订阅。\n *\n * @module vue/bridge/formBridge\n */\n\nimport { getCurrentScope, onScopeDispose } from \"vue\"\n\nimport { createFormStateAdapter } from \"@schemx/core/adapter\"\n\nimport { getVueFieldState } from \"./fieldBridge\"\nimport { createVueFormInstance } from \"./formInstance\"\nimport { bindSnapshotSource } from \"./helpers\"\nimport { createVueViewSchemaState } from \"./viewSchemaBridge\"\n\nimport type {\n VueFieldDependency,\n VueFieldState,\n VueFormDependency,\n VueFormResources,\n VueFormRuntime,\n VueSchemxInstance,\n} from \"./types\"\nimport type { NamePath, SchemxInstance, Values } from \"@schemx/core\"\n\n/**\n * 同一 Core Form 只创建一个稳定 Runtime。\n */\nconst runtimeCache = new WeakMap<object, VueFormRuntime<Values>>()\n\n/**\n * 在当前 Vue effect scope 中获取共享 Runtime。\n *\n * 每次调用都会为当前 scope 保留一个 Runtime owner,并在 scope 停止时自动\n * 释放该 owner;最后一个 owner 释放后,字段和表单级响应式资源才会回收。\n *\n * @typeParam TValues - 表单值类型。\n * @param form - 要桥接的 Core Form 或 Vue Form Instance。\n * @returns 当前 Form 对应的共享 Runtime。\n * @throws 当前没有活动的 Vue effect scope 时抛出错误。\n *\n * @example\n * ```ts\n * // 在 setup() 或其他活动的 Vue effect scope 中调用。\n * const runtime = useVueFormRuntime(form)\n * const values = runtime.getValuesRef()\n * ```\n */\nexport function useVueFormRuntime<TValues extends Values = Values>(\n form: SchemxInstance<TValues>\n): VueFormRuntime<TValues> {\n if (!getCurrentScope()) {\n throw new Error(\"[schemx] useVueFormRuntime() requires an active Vue scope.\")\n }\n\n const { runtime, release } = acquireVueFormRuntime(form)\n\n onScopeDispose(release)\n\n return runtime\n}\n\n/**\n * 获取并保留指定 Form 的共享 Runtime。\n *\n * 返回的 release 函数必须绑定到当前 owner 的 Vue scope;最后一个 owner\n * 释放后只销毁响应式资源,Runtime 和 Instance 身份保持稳定。\n *\n * @typeParam TValues - 表单值类型。\n * @param form - 要桥接的 Core Form 或 Vue Form Instance。\n * @returns 共享 Runtime 及与当前 owner 对应的释放函数。\n *\n * @example\n * ```ts\n * const { runtime, release } = acquireVueFormRuntime(form)\n * try {\n * runtime.getValuesRef()\n * } finally {\n * release()\n * }\n * ```\n */\nexport function acquireVueFormRuntime<TValues extends Values = Values>(\n form: SchemxInstance<TValues> | VueSchemxInstance<TValues>\n): {\n runtime: VueFormRuntime<TValues>\n release: () => void\n} {\n const runtime = getOrCreateVueFormRuntime(form)\n\n const release = runtime.retain()\n\n return {\n runtime,\n release,\n }\n}\n\n/**\n * 获取已有 Runtime,或为输入的 Core Form 创建 Runtime。\n *\n * Core Form 和桥接后的 Vue Instance 都会映射到同一个 Runtime,避免同一表单\n * 因不同入口重复创建状态订阅。\n *\n * @param form - 要查找或创建 Runtime 的 Form Instance。\n */\nfunction getOrCreateVueFormRuntime<TValues extends Values>(\n form: SchemxInstance<TValues> | VueSchemxInstance<TValues>\n): VueFormRuntime<TValues> {\n const cachedByCore = runtimeCache.get(form as object)\n\n if (cachedByCore) {\n return cachedByCore as VueFormRuntime<TValues>\n }\n\n const runtime = createVueFormRuntime(form as SchemxInstance<TValues>)\n\n runtimeCache.set(form as object, runtime as VueFormRuntime<Values>)\n runtimeCache.set(runtime.instance as object, runtime as VueFormRuntime<Values>)\n\n return runtime\n}\n\n/**\n * 创建单个 Core Form 的稳定 Runtime。\n *\n * Runtime 本身保持稳定;只有存在 owner 时才创建并保留 Vue 响应式资源。\n *\n * @param core - 要桥接的 Core Form。\n */\nfunction createVueFormRuntime<TValues extends Values>(\n core: SchemxInstance<TValues>\n): VueFormRuntime<TValues> {\n let resources: VueFormResources<TValues> | undefined\n\n let ownerCount = 0\n\n let destroyed = false\n\n const createResources = (): VueFormResources<TValues> => {\n const stateAdapter = createFormStateAdapter(core)\n\n const values = bindSnapshotSource(stateAdapter.values)\n\n const touchedFields = bindSnapshotSource(stateAdapter.touchedFields)\n\n const pendingFields = bindSnapshotSource(stateAdapter.pendingFields)\n\n const loading = bindSnapshotSource(stateAdapter.loading)\n\n const fieldStates = new Map<object, VueFieldState<TValues>>()\n\n let disposed = false\n\n const dispose = (): void => {\n if (disposed) {\n return\n }\n\n disposed = true\n\n currentResources.viewSchemaState?.dispose()\n fieldStates.clear()\n stateAdapter.dispose()\n }\n\n const currentResources: VueFormResources<TValues> = {\n stateAdapter,\n values,\n touchedFields,\n pendingFields,\n loading,\n fieldStates,\n dispose,\n }\n\n return currentResources\n }\n\n const ensureResources = (): VueFormResources<TValues> => {\n if (destroyed) {\n throw new Error(\"[schemx] Vue Form Runtime has been destroyed.\")\n }\n\n resources ??= createResources()\n\n return resources\n }\n\n const disposeResources = (): void => {\n const currentResources = resources\n\n if (!currentResources) {\n return\n }\n\n resources = undefined\n currentResources.dispose()\n }\n\n const retain = (): (() => void) => {\n if (destroyed) {\n return () => {}\n }\n\n ensureResources()\n ownerCount++\n\n let released = false\n\n return () => {\n if (released || destroyed) {\n return\n }\n\n released = true\n ownerCount--\n\n if (ownerCount === 0) {\n disposeResources()\n }\n }\n }\n\n const trackField = <TName extends NamePath<TValues>>(\n name: TName,\n dependency: VueFieldDependency\n ): void => {\n if (!resources) {\n return\n }\n\n const fieldState = getVueFieldState(resources, name)\n\n void fieldState[dependency].value\n }\n\n const trackFieldsValue = (names?: NamePath<TValues>[]): void => {\n if (!resources) {\n return\n }\n\n if (names === undefined) {\n void resources.values.value\n\n return\n }\n\n for (const name of names) {\n void getVueFieldState(resources, name).value.value\n }\n }\n\n const trackForm = (dependency: VueFormDependency): void => {\n if (!resources) {\n return\n }\n\n switch (dependency) {\n case \"values\":\n void resources.values.value\n break\n case \"touchedFields\":\n void resources.touchedFields.value\n break\n case \"pendingFields\":\n void resources.pendingFields.value\n break\n case \"loading\":\n void resources.loading.value\n break\n }\n }\n\n const getValuesRef = (): VueFormResources<TValues>[\"values\"] => {\n return ensureResources().values\n }\n\n const getFieldState = <TName extends NamePath<TValues>>(name: TName) => {\n return getVueFieldState(ensureResources(), name)\n }\n\n const getViewSchemaState = () => {\n const currentResources = ensureResources()\n\n const viewSchemaState = (currentResources.viewSchemaState ??=\n createVueViewSchemaState(core))\n\n return viewSchemaState\n }\n\n const destroy = (): void => {\n if (destroyed) {\n return\n }\n\n destroyed = true\n ownerCount = 0\n disposeResources()\n }\n\n const instance = createVueFormInstance(core, {\n trackField,\n trackFieldsValue,\n trackForm,\n destroy,\n })\n\n const runtime: VueFormRuntime<TValues> = {\n core,\n instance,\n retain,\n trackField,\n trackFieldsValue,\n trackForm,\n getValuesRef,\n getFieldState,\n getViewSchemaState,\n destroy,\n }\n\n return runtime\n}\n","/**\n * 具体表单的 Vue provide/inject 适配。\n *\n * 一个 Form Context 同时保存 Vue Form Instance 与该表单最终用于展示的\n * schemaConfig。ConfigProvider 的组件树级默认配置不属于此 Context。\n *\n * @module context/formContext\n */\n\nimport { inject, type InjectionKey, provide } from \"vue\"\n\nimport { useVueFormRuntime, type VueFormRuntime, type VueSchemxInstance } from \"../bridge\"\n\nimport type { SchemxInstance, SchemxSchemaConfig, Values } from \"@schemx/core\"\n\n// provide/inject 不在运行时固定具体表单值泛型,消费端再恢复 TValues。\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype ErasedFormContextValue = FormContextValue<any>\n\ntype LegacyFormContextInstance = VueSchemxInstance<any>\n\nconst SCHEMX_FORM_CONTEXT_KEY: InjectionKey<ErasedFormContextValue> =\n Symbol(\"schemx:form-context\")\n\nconst LEGACY_FORM_INSTANCE_KEY: InjectionKey<LegacyFormContextInstance> =\n Symbol(\"schemx:instance\")\n\nconst LEGACY_FORM_CONFIG_KEY: InjectionKey<FormConfigContextValue> =\n Symbol(\"schemx:form-config\")\n\n/** @internal 仅供迁移期测试注入旧 Context。 */\nexport const SCHEMX_FORM_INSTANCE_KEY = LEGACY_FORM_INSTANCE_KEY\n\n/** @internal 仅供迁移期测试注入旧 Context。 */\nexport const SCHEMX_FORM_CONFIG_KEY = LEGACY_FORM_CONFIG_KEY\n\n/**\n * 一个具体 Form 向后代暴露的运行上下文。\n */\nexport interface FormContextValue<TValues extends Values = Values> {\n /** 当前 Form 的 Vue 响应式实例。 */\n form: VueSchemxInstance<TValues>\n /** 当前 Form 已解析的展示配置。 */\n schemaConfig: Partial<SchemxSchemaConfig>\n}\n\n/**\n * 提供完整 Form Context 所需的输入。\n */\nexport interface ProvideFormContextOptions<TValues extends Values = Values> {\n /** Core Form 或已有 Vue Form Instance。 */\n form: SchemxInstance<TValues> | VueSchemxInstance<TValues>\n /** 当前 Form 已解析的展示配置。 */\n schemaConfig: Partial<SchemxSchemaConfig>\n}\n\n/**\n * 表单展示配置 Context 的兼容值类型。\n */\nexport interface FormConfigContextValue {\n schemaConfig: Partial<SchemxSchemaConfig>\n}\n\n/**\n * 旧名称的兼容类型。\n *\n * @deprecated 请使用 FormConfigContextValue。\n */\nexport type FormContextProps = FormConfigContextValue\n\n/**\n * 一次性向后代提供具体 Form 的实例与展示配置。\n */\nexport function provideFormContext<TValues extends Values = Values>(\n options: ProvideFormContextOptions<TValues>\n): VueSchemxInstance<TValues> {\n const runtime = useVueFormRuntime(options.form)\n\n const context: FormContextValue<TValues> = {\n form: runtime.instance,\n get schemaConfig() {\n return options.schemaConfig\n },\n }\n\n provide<ErasedFormContextValue>(\n SCHEMX_FORM_CONTEXT_KEY,\n context as ErasedFormContextValue\n )\n\n return runtime.instance\n}\n\n/**\n * 获取最近祖先提供的完整 Form Context。\n */\nexport function useFormContextValue<\n TValues extends Values = Values,\n>(): FormContextValue<TValues> {\n const context = inject<ErasedFormContextValue | null>(SCHEMX_FORM_CONTEXT_KEY, null)\n\n if (context) {\n return context as FormContextValue<TValues>\n }\n\n const form = inject<LegacyFormContextInstance | null>(LEGACY_FORM_INSTANCE_KEY, null)\n\n const config = inject<FormConfigContextValue | null>(LEGACY_FORM_CONFIG_KEY, null)\n\n if (form && config) {\n return {\n form: form as VueSchemxInstance<TValues>,\n schemaConfig: config.schemaConfig,\n }\n }\n\n throw new Error(\n \"[schemx] useFormContextValue() must be called inside a <SchemxForm> descendant. \" +\n \"Ensure provideFormContext({ form, schemaConfig }) is called synchronously during setup().\"\n )\n}\n\n/**\n * 向后代提供表单实例的兼容 API。\n *\n * @deprecated 请改用 provideFormContext({ form, schemaConfig })。\n */\nexport function createFormContext<TValues extends Values = Values>(\n instance: SchemxInstance<TValues> | VueSchemxInstance<TValues>\n): VueSchemxInstance<TValues> {\n const runtime = useVueFormRuntime(instance)\n\n provide<LegacyFormContextInstance>(\n LEGACY_FORM_INSTANCE_KEY,\n runtime.instance as LegacyFormContextInstance\n )\n\n return runtime.instance\n}\n\n/**\n * 获取最近祖先提供的 Vue Form Instance。\n *\n * 优先读取统一 Form Context,随后兼容旧的 createFormContext() Provider。\n */\nexport function useFormContext<\n TValues extends Values = Values,\n>(): VueSchemxInstance<TValues> {\n const context = inject<ErasedFormContextValue | null>(SCHEMX_FORM_CONTEXT_KEY, null)\n\n if (context) {\n return context.form as VueSchemxInstance<TValues>\n }\n\n const instance = inject<LegacyFormContextInstance | null>(\n LEGACY_FORM_INSTANCE_KEY,\n null\n )\n\n if (!instance) {\n throw new Error(\n \"[schemx] useFormContext() must be called inside a <SchemxForm> descendant. \" +\n \"Ensure createFormContext(form) is called synchronously during setup().\"\n )\n }\n\n return instance as VueSchemxInstance<TValues>\n}\n\n/**\n * 向后代提供表单展示配置的兼容 API。\n *\n * @deprecated 请改用 provideFormContext({ form, schemaConfig })。\n */\nexport function createFormConfigContext(props: FormConfigContextValue): void {\n provide<FormConfigContextValue>(LEGACY_FORM_CONFIG_KEY, props)\n}\n\n/**\n * 获取当前 Form 的展示配置。\n *\n * 优先读取统一 Form Context,随后兼容旧的 createFormConfigContext() Provider。\n */\nexport function useFormConfigContext(): FormConfigContextValue {\n const context = inject<ErasedFormContextValue | null>(SCHEMX_FORM_CONTEXT_KEY, null)\n\n if (context) {\n return context\n }\n\n const config = inject<FormConfigContextValue | null>(LEGACY_FORM_CONFIG_KEY, null)\n\n if (!config) {\n throw new Error(\n \"[schemx] useFormConfigContext() must be called inside a <SchemxForm> descendant. \" +\n \"Ensure createFormConfigContext(props) is called synchronously during setup().\"\n )\n }\n\n return config\n}\n\n/**\n * 获取当前表单的内部 Runtime。\n */\nexport function useFormRuntimeContext<\n TValues extends Values = Values,\n>(): VueFormRuntime<TValues> {\n return useVueFormRuntime(useFormContext<TValues>())\n}\n","/**\n * 当前字段实例的 Vue provide/inject 适配。\n *\n * @module context/fieldContext\n */\n\nimport { inject, type InjectionKey, provide } from \"vue\"\n\nimport type { FieldInstance } from \"../types/field\"\nimport type { Values } from \"@schemx/core\"\n\nconst SCHEMX_FIELD_CONTEXT_KEY: InjectionKey<FieldInstance<Values>> =\n Symbol(\"schemx:field\")\n\n/**\n * 向后代组件提供当前字段实例。\n */\nexport function createFieldContext<TValues extends Values = Values>(\n field: FieldInstance<TValues>\n): void {\n provide<FieldInstance<Values>>(SCHEMX_FIELD_CONTEXT_KEY, field as FieldInstance<Values>)\n}\n\n/**\n * 获取最近祖先组件提供的当前字段实例。\n */\nexport function useFieldContext(): FieldInstance<Values> {\n const field = inject<FieldInstance<Values> | null>(SCHEMX_FIELD_CONTEXT_KEY, null)\n\n if (!field) {\n throw new Error(\n \"[schemx] useFieldContext() must be called inside a component tree where \" +\n \"createFieldContext(field) has been called.\"\n )\n }\n\n return field\n}\n","/**\n * Vue 组件树级 Schemx 配置的 provide/inject 适配。\n *\n * @module context/configProviderContext\n */\n\nimport { computed, getCurrentInstance, inject, provide } from \"vue\"\nimport type { ComputedRef, InjectionKey } from \"vue\"\n\nimport { mergeSchemxConfig } from \"@schemx/core\"\n\nimport type { SchemxVueConfig } from \"../types\"\n\nconst SCHEMX_CONFIG_PROVIDER_KEY: InjectionKey<ComputedRef<SchemxVueConfig>> = Symbol(\n \"schemx:config-provider\"\n)\n\n/**\n * 创建并注入合并后的组件树级配置上下文。\n */\nexport function createConfigProviderContext(config: ComputedRef<SchemxVueConfig>): void {\n const parentConfig = inject(SCHEMX_CONFIG_PROVIDER_KEY, undefined)\n\n const mergedConfig = computed<SchemxVueConfig>(() => {\n const mergedCoreConfig = mergeSchemxConfig(config.value, parentConfig?.value ?? {})\n\n return {\n ...mergedCoreConfig,\n colComponent: config.value.colComponent ?? parentConfig?.value.colComponent,\n }\n })\n\n provide(SCHEMX_CONFIG_PROVIDER_KEY, mergedConfig)\n}\n\n/**\n * 获取最近祖先 ConfigProvider 的当前配置。\n */\nexport function useConfigProviderContext(): SchemxVueConfig | undefined {\n return useConfigProviderContextRef()?.value\n}\n\n/**\n * 获取最近祖先 ConfigProvider 的响应式配置引用。\n */\nexport function useConfigProviderContextRef(): ComputedRef<SchemxVueConfig> | undefined {\n if (getCurrentInstance() === null) {\n return undefined\n }\n\n return inject(SCHEMX_CONFIG_PROVIDER_KEY, undefined)\n}\n","/**\n * Vue App 级 Schemx 配置的 provide/inject 适配。\n *\n * 安装配置属于当前 Vue App,而不是 Core 模块级共享状态;该模块只在 Vue\n * 适配层内部保存和读取安装配置,不将注入 key 暴露为公共 API。\n *\n * @module config/appConfig\n */\n\nimport { type App, getCurrentInstance, inject, type InjectionKey } from \"vue\"\n\nimport type { SchemxVueConfig } from \"../types\"\nimport type { SchemxRendererPropsMap } from \"@schemx/core\"\n\n// Vue App 级配置在组件树中的私有注入 key。\nconst SCHEMX_APP_CONFIG_KEY: InjectionKey<SchemxVueConfig> = Symbol(\"schemx:app-config\")\n\n// 没有安装配置时使用的不可变空配置。\nconst EMPTY_SCHEMX_CONFIG: SchemxVueConfig = Object.freeze({\n schemaConfig: Object.freeze({}),\n validatorAdapters: Object.freeze([]),\n})\n\n/**\n * 将插件安装选项复制为可安全注入的 App 配置快照。\n *\n * Registry 保留其可变实例语义,使同一 App 内创建的多个 Form 继续共享注册结果;\n * Schema 配置和 adapter 列表则复制并冻结,避免安装后修改原对象影响 App 配置。\n *\n * @param config - 插件安装时传入的配置。\n * @returns 与调用方输入隔离的 App 配置快照。\n */\nfunction normalizeSchemxAppConfig(config: SchemxVueConfig): SchemxVueConfig {\n // 复制并冻结 App 级字段默认值,避免外部对象后续变更配置。\n const schemaConfig = Object.freeze({ ...(config.schemaConfig ?? {}) })\n\n // 复制并冻结 App 级 adapter 列表,保持列表与调用方数组相互独立。\n const validatorAdapters = Object.freeze([...(config.validatorAdapters ?? [])])\n\n return Object.freeze({\n schemaConfig,\n rendererProps: normalizeRendererProps(config.rendererProps),\n validatorAdapters,\n defaultRendererType: config.defaultRendererType,\n rendererRegistry: config.rendererRegistry,\n presetRuleRegistry: config.presetRuleRegistry,\n colComponent: config.colComponent,\n })\n}\n\n/**\n * 复制并冻结 Renderer Props Map 外层及每个 Renderer 的 Props 对象。\n *\n * @param source - 待标准化的 Renderer Props Map。\n * @returns 与输入隔离一层的只读 App 配置;任意嵌套 Prop 值仍保留原引用。\n */\nfunction normalizeRendererProps(\n source: SchemxRendererPropsMap | undefined\n): SchemxRendererPropsMap | undefined {\n if (source === undefined) {\n return undefined\n }\n\n // 每个 Renderer 的 Props 对象单独复制,避免安装后修改源对象影响当前 App。\n const entries = Object.entries(source).map(([type, props]) => {\n return [type, props === undefined ? undefined : Object.freeze({ ...props })]\n })\n\n return Object.freeze(Object.fromEntries(entries)) as SchemxRendererPropsMap\n}\n\n/**\n * 将 Schemx 安装配置绑定到指定 Vue App。\n *\n * @param app - 要安装 Schemx 的 Vue App 实例。\n * @param config - 当前 App 的默认配置。\n *\n * @example\n * ```ts\n * app.use(SchemxForm, { schemaConfig: { readonly: true } })\n * ```\n */\nexport function provideSchemxAppConfig(app: App, config: SchemxVueConfig = {}): void {\n // 当前 App 后续组件实例应读取的配置快照。\n const normalizedConfig = normalizeSchemxAppConfig(config)\n\n app.provide(SCHEMX_APP_CONFIG_KEY, normalizedConfig)\n}\n\n/**\n * 读取当前组件所属 Vue App 的 Schemx 安装配置。\n *\n * 在组件 setup() 之外调用时,Vue 没有可用的注入上下文;此时返回空配置,\n * 使 `useForm()` 仍可在独立 effect scope 中使用 Vue 模块级 Registry。\n *\n * @returns 当前 App 的安装配置,或无 App 上下文时的空配置。\n *\n * @example\n * ```ts\n * const appConfig = getSchemxAppConfig()\n * ```\n */\nexport function getSchemxAppConfig(): SchemxVueConfig {\n // 只有存在当前组件实例时才读取 Vue 注入上下文,避免 setup 外触发 Vue 警告。\n if (getCurrentInstance() === null) {\n return EMPTY_SCHEMX_CONFIG\n }\n\n // 当前组件树中最近的 App 级配置,未安装插件时回退到空配置。\n return inject(SCHEMX_APP_CONFIG_KEY, EMPTY_SCHEMX_CONFIG)\n}\n","/**\n * 全局预设规则注册实例\n *\n * 模块级单例,由 ES Module 保证全局唯一。\n * UI 适配层通过 import 后调用 register/registerAll 注册自定义规则,\n * useForm 内部自动使用此实例作为 fallback。\n *\n * @module utils/presetRuleProvider\n */\n\nimport { createPresetRuleRegistry, type PresetRuleRegistry } from \"@schemx/core\"\n\n/**\n * 全局预设规则注册实例\n *\n * @example\n * ```ts\n * // 注册自定义规则\n * import { presetRuleRegistry } from '@schemx/vue'\n * presetRuleRegistry.register('phone', phoneRule)\n *\n * // useForm 内部自动使用\n * // props 传入的 presetRuleRegistry 优先级更高\n * ```\n */\nexport const presetRuleRegistry: PresetRuleRegistry = createPresetRuleRegistry()\n","/**\n * 全局渲染器注册实例\n *\n * 模块级单例,由 ES Module 保证全局唯一。\n * vant 等 UI 适配层通过 import 后调用 registerAll 注册渲染器,\n * useForm 内部自动使用此实例作为 fallback。\n *\n * @module utils/rendererProvider\n */\n\nimport { createRendererRegistry, type RendererRegistry } from \"@schemx/core/adapter\"\n\nimport type { SchemxRendererKey } from \"@schemx/core\"\n\n/**\n * 全局渲染器注册实例\n *\n * @example\n * ```ts\n * // UI 适配层注册渲染器\n * import { rendererRegistry } from '@schemx/vue'\n * rendererRegistry.registerAll({ input: InputRenderer, ... })\n *\n * // useForm 内部自动使用\n * // props 传入的 rendererRegistry 优先级更高\n * ```\n */\nexport const rendererRegistry: RendererRegistry<SchemxRendererKey> =\n createRendererRegistry<SchemxRendererKey>(\"input\")\n","/**\n * Vue 层 Form 配置合并。\n *\n * @module config/vueConfig\n */\n\nimport { mergeSchemxConfig } from \"@schemx/core\"\n\nimport { useConfigProviderContext } from \"../context/configProviderContext\"\nimport { presetRuleRegistry as globalPresetRuleRegistry } from \"../utils/presetRuleProvider\"\nimport { rendererRegistry as globalRendererRegistry } from \"../utils/rendererProvider\"\n\nimport { getSchemxAppConfig } from \"./appConfig\"\n\nimport type { SchemxConfig, Values } from \"@schemx/core\"\n\n/**\n * 按 Vue 适配层优先级合并一个 Form 的显式配置。\n *\n * Core 模块级配置和内置默认值由后续 createForm() 继续处理。\n *\n * @param localConfig - 当前 Form 或 useForm() 的显式配置。\n * @param fallbackConfig - Vue 层更低优先级的回退配置。\n * @returns 已合并 Provider、App 和 Vue 默认 Registry 的配置。\n *\n * @example\n * ```ts\n * const config = mergeVueSchemxConfig({\n * schemaConfig: { readonly: true },\n * })\n * ```\n */\nexport function mergeVueSchemxConfig<TValues extends Values = Values>(\n localConfig: SchemxConfig<TValues>,\n fallbackConfig: SchemxConfig<TValues> = {}\n): SchemxConfig<TValues> {\n const providerConfig = useConfigProviderContext()\n\n return mergeSchemxConfig(\n localConfig,\n (providerConfig as SchemxConfig<TValues> | undefined) ?? {},\n getSchemxAppConfig() as SchemxConfig<TValues>,\n fallbackConfig,\n {\n rendererRegistry: globalRendererRegistry,\n presetRuleRegistry: globalPresetRuleRegistry,\n }\n )\n}\n","/**\n * Vue 适配层的字段展示默认值。\n *\n * Core 仍暂时保留同名默认配置作为兼容来源;新的 Vue 渲染路径优先使用这里的配置。\n */\nexport const defaultVueSchemaConfig = Object.freeze({\n /**\n * 表单级标签图标默认值。\n */\n labelIcon: \"\",\n /**\n * 表单级标签对齐默认值。\n */\n labelAlign: \"left\",\n /**\n * 表单级标签位置默认值。\n */\n labelPosition: \"left\",\n /**\n * 表单级标签宽度默认值。\n */\n labelWidth: \"auto\",\n /**\n * 表单级内容对齐默认值。\n */\n contentAlign: \"right\",\n /**\n * 表单级标签冒号默认值。\n */\n colon: true,\n /**\n * 表单级必填标记默认值。\n */\n showRequiredMark: undefined as boolean | undefined,\n} as const)\n\n/**\n * Vue 展示默认配置的键集合。\n */\nexport const defaultVueSchemaConfigKeys = Object.keys(\n defaultVueSchemaConfig\n) as (keyof typeof defaultVueSchemaConfig)[]\n","/**\n * useForm - Schemx 表单实例的 Vue 生命周期适配。\n *\n * 负责创建由当前 Vue effect scope 持有的 SchemxInstance,并在 scope 销毁时\n * 自动释放实例。该模块不负责 provide/inject;表单上下文统一由\n * createFormContext() 注册,避免外部传入 form 时跳过上下文注册。\n *\n * @module hooks/useForm\n */\nimport { onScopeDispose } from \"vue\"\n\nimport { createForm, type SchemxConfig } from \"@schemx/core\"\n\nimport { useVueFormRuntime, type VueSchemxInstance } from \"../bridge\"\nimport { mergeVueSchemxConfig } from \"../config\"\n\nimport type { CreateFormOptions, NamePath, Values } from \"@schemx/core\"\n\n/**\n * useForm 配置选项。\n *\n * 当前与 core 层 CreateFormOptions 保持一致,并在 Vue 层自动补充默认的\n * rendererRegistry 和 presetRuleRegistry。保留独立类型用于后续扩展\n * Vue 专属配置,而不污染 core 层接口。\n *\n * @typeParam TValues - 表单值类型\n */\nexport interface UseFormOptions<TValues extends Values> extends CreateFormOptions<\n TValues,\n NamePath<TValues>\n> {}\n\n/**\n * 创建由当前 Vue effect scope 持有的表单实例。\n *\n * useForm 只负责以下职责:\n * 1. 合并表单显式、组件树 Provider、App 安装和 Vue 层默认配置;\n * 2. 同步创建 SchemxInstance;\n * 3. 在当前 effect scope 销毁时调用 instance.destroy()。\n *\n * useForm 不再自动调用 provide()。需要向后代组件暴露实例时,应由\n * <SchemxForm> 或其他 Provider 组件显式调用 createFormContext(form)。\n * 这样无论实例是内部创建还是通过 props.form 外部传入,都能走同一条\n * 上下文注册路径,并保持清晰的实例所有权:谁创建,谁销毁。\n *\n * 该函数应在组件 setup() 或其他有效的 Vue effect scope 中同步调用。\n * 非 Vue 生命周期场景请直接使用 @schemx/core 的 createForm(),并自行销毁实例。\n *\n * @typeParam TValues - 表单值类型\n * @param options - 表单创建配置\n * @returns 当前 scope 持有的 SchemxInstance\n *\n * @example\n * ```ts\n * const form = useForm({\n * initialValues: {\n * name: \"\",\n * email: \"\",\n * },\n * onFinish: async (values) => {\n * await api.submit(values)\n * },\n * })\n *\n * form.setFieldValue(\"name\", \"Schemx\")\n * ```\n *\n * @example\n * ```ts\n * // Provider 组件中统一注册上下文。\n * const form = props.form ?? useForm(options)\n * createFormContext(form)\n * ```\n */\nexport function useForm<TValues extends Values = Values>(\n options: UseFormOptions<TValues> = {}\n): VueSchemxInstance<TValues> {\n // 按表单、App、Vue 包默认值的优先级解析可继承配置。\n const configuredOptions = mergeVueSchemxConfig<TValues>(getUseFormSchemxConfig(options))\n\n // 将已合并配置写入 Form 创建选项,避免 Core 再按较低优先级覆盖 Vue 结果。\n const mergedOptions: CreateFormOptions<TValues> = {\n ...options,\n ...configuredOptions,\n }\n\n // 表单实例是当前 scope 内的一次性资源,不需要使用 computed 包装。\n const instance = createForm<TValues>(mergedOptions)\n\n const form = useVueFormRuntime(instance).instance\n\n // useForm 创建的实例归当前 effect scope 所有,因此由当前 scope 负责销毁。\n onScopeDispose(() => {\n form.destroy()\n })\n\n return form\n}\n\n/**\n * 从 useForm 选项中提取需要参与 Vue 优先级计算的可继承配置。\n *\n * @param options - useForm 的完整创建选项。\n * @returns 仅包含调用方实际提供字段的 SchemxConfig。\n */\nfunction getUseFormSchemxConfig<TValues extends Values>(\n options: UseFormOptions<TValues>\n): SchemxConfig<TValues> {\n const {\n schemaConfig = {},\n rendererProps = undefined,\n validatorAdapters = [],\n defaultRendererType = undefined,\n rendererRegistry = undefined,\n presetRuleRegistry = undefined,\n } = options\n\n return {\n schemaConfig,\n rendererProps,\n defaultRendererType,\n rendererRegistry,\n presetRuleRegistry,\n validatorAdapters,\n }\n}\n","/**\n * useField - 字段控制 Hook。\n *\n * 复用共享 Vue Runtime 的字段 Ref,并将 Core 的字段写入、校验和规则操作\n * 保持在原始 `createField()` 实例上。\n *\n * @module hooks/useField\n */\n\nimport { computed } from \"vue\"\n\nimport { createField } from \"@schemx/core\"\n\nimport { type VueFieldState, type VueSchemxInstance } from \"../bridge\"\nimport { useFormContext, useFormRuntimeContext } from \"../context/formContext\"\n\nimport type { FieldInstance } from \"../types/field\"\nimport type { NamePath, SchemxInstance, Values } from \"@schemx/core\"\n\n/**\n * 创建一份字段控制器,并将所有读取状态投影到共享 Vue Field State。\n *\n * @typeParam TValues - 表单值类型。\n * @typeParam TName - 当前字段路径类型。\n * @param form - 当前 Vue Form Instance。\n * @param coreForm - 用于创建 Core 字段控制器的原始 Form。\n * @param name - 当前字段路径。\n * @param fieldState - 当前字段的共享 Vue 状态。\n * @returns 同时提供 Core 字段操作和 Vue Ref 状态的字段控制器。\n */\nfunction createFieldHook<\n TValues extends Values = Values,\n TName extends NamePath<TValues> = NamePath<TValues>,\n>(\n form: VueSchemxInstance<TValues>,\n coreForm: SchemxInstance<TValues>,\n name: TName,\n fieldState: VueFieldState<TValues, TName>\n): FieldInstance<TValues> {\n const coreField = createField<TValues>(coreForm, name)\n\n const errors = computed(() => fieldState.errors.value)\n\n const dirty = computed(() => fieldState.touched.value)\n\n const pending = computed(() => fieldState.pending.value)\n\n const getValue = (): ReturnType<typeof coreField.getValue> => fieldState.value.value\n\n const getErrors = (): ReturnType<typeof coreField.getErrors> => fieldState.errors.value\n\n const isTouched = (): boolean => fieldState.touched.value\n\n const isPending = (): boolean => fieldState.pending.value\n\n const getValues = (): Readonly<TValues> => form.getFieldsValue()\n\n return {\n ...coreField,\n name,\n value: fieldState.value,\n errors,\n dirty,\n pending,\n getValue,\n getErrors,\n isTouched,\n isPending,\n getValues,\n }\n}\n\n/**\n * 获取单个字段的控制能力。\n *\n * @typeParam TValues - 表单值类型。\n * @param name - 字段路径(支持嵌套字段)。\n * @returns 包含 Vue Ref 状态和 Core 字段操作的控制器。\n *\n * @example\n * ```ts\n * const field = useField(\"email\")\n * field.value.value = \"user@example.com\"\n * ```\n */\nexport const useField = <TValues extends Values = Values>(\n name: NamePath<TValues>\n): FieldInstance<TValues> => {\n const form = useFormContext<TValues>()\n\n const runtime = useFormRuntimeContext<TValues>()\n\n const fieldState = runtime.getFieldState(name)\n\n return createFieldHook(form, runtime.instance, name, fieldState)\n}\n\nexport default useField\n","/**\n * useWatch - 监听字段变化(Vue 组合式 API 版本)\n *\n * 基于 core 层的 {@link createWatch} 实现,\n * 自动通过 `useFormContext` 获取 formContext,\n * 并在 `onUnmounted` 时自动取消监听,无需手动管理生命周期。\n *\n * 提供三种监听模式:\n * - 全局监听:`useWatch(callback, options?)` — 监听表单中任意字段变化\n * - 单字段监听:`useWatch(name, callback, options?)` — 监听指定字段变化\n * - 多字段监听:`useWatch(names, callback, options?)` — 监听一组字段变化\n *\n * 同时提供语义化的便捷方法:\n * - {@link useWatchField} — 单字段监听\n * - {@link useWatchFields} — 多字段监听\n * - {@link useWatchAll} — 全局监听\n *\n * @module hooks/useWatch\n *\n * @example\n * ```ts\n * // 全局监听\n * useWatch((snapshot, payload) => {\n * console.log('form changed:', snapshot, payload)\n * })\n *\n * // 单字段监听\n * useWatch('username', (current, prev) => {\n * console.log('username changed:', prev, '->', current)\n * }, { immediate: true })\n *\n * // 多字段监听\n * useWatch(['firstName', 'lastName'], (currentValues, prevValues) => {\n * console.log('name changed:', currentValues)\n * }, { inequality: true })\n * ```\n */\n\nimport { onUnmounted } from \"vue\"\n\nimport { createWatch } from \"@schemx/core\"\n\nimport { useFormRuntimeContext } from \"../context/formContext\"\n\nimport type { NamePath, Values } from \"@schemx/core\"\nimport type {\n CreateWatchOptions,\n WatchAllCallback,\n WatchFieldCallback,\n WatchFieldsCallback,\n} from \"@schemx/core\"\n\n/**\n * 监听所有字段变化\n *\n * @typeParam TValues - 表单值类型。\n * @param callback - 全局变化回调;payload 为 `{ changedPaths, changedValues, prevValues }`\n * @param options - 监听选项\n * @returns 取消监听函数\n *\n * @example\n * ```ts\n * const dispose = useWatch((values, payload) => {\n * const { changedPaths, changedValues, prevValues } = payload\n * console.log(changedPaths, changedValues, prevValues, values)\n * })\n * ```\n */\nexport function useWatch<TValues extends Values>(\n callback: WatchAllCallback<TValues>,\n options?: CreateWatchOptions\n): () => void\n/**\n * 监听单个字段变化\n *\n * @typeParam TValues - 表单值类型。\n * @param name - 字段路径\n * @param callback - 单字段变化回调;payload 为 `{ value, prevValue }`\n * @param options - 监听选项\n * @returns 取消监听函数\n *\n * @example\n * ```ts\n * useWatch(\"email\", (_values, payload) => {\n * console.log(payload.prevValue, payload.value)\n * })\n * ```\n */\nexport function useWatch<TValues extends Values>(\n name: NamePath<TValues>,\n callback: WatchFieldCallback<TValues>,\n options?: CreateWatchOptions\n): () => void\n/**\n * 监听多个字段变化\n *\n * @typeParam TValues - 表单值类型。\n * @param names - 字段路径数组\n * @param callback - 多字段变化回调;payload 为 `{ changedPaths, changedValues, prevValues }`\n * @param options - 监听选项\n * @returns 取消监听函数\n *\n * @example\n * ```ts\n * useWatch([\"firstName\", \"lastName\"], (_values, payload) => {\n * console.log(payload.changedPaths, payload.changedValues, payload.prevValues)\n * })\n * ```\n */\nexport function useWatch<TValues extends Values>(\n names: NamePath<TValues>[],\n callback: WatchFieldsCallback<TValues>,\n options?: CreateWatchOptions\n): () => void\n/**\n * useWatch 实现 — 获取 form 实例后委托给 core 层的 createWatch\n *\n * @typeParam TValues - 表单值类型。\n */\nexport function useWatch<TValues extends Values>(\n nameOrNamesOrCallback:\n NamePath<TValues> | NamePath<TValues>[] | WatchAllCallback<TValues>,\n callbackOrOptions?:\n WatchFieldCallback<TValues> | WatchFieldsCallback<TValues> | CreateWatchOptions,\n maybeOptions?: CreateWatchOptions\n): () => void {\n const runtime = useFormRuntimeContext<TValues>()\n\n const dispose = (createWatch as any)(\n runtime.instance,\n nameOrNamesOrCallback,\n callbackOrOptions,\n maybeOptions\n )\n\n onUnmounted(dispose)\n\n return dispose\n}\n\n/**\n * 监听单个字段变化的便捷方法\n *\n * 等价于 `useWatch(name, callback, options)`,语义更明确。\n * 自动绑定 formContext 并在组件卸载时取消监听。\n *\n * @typeParam TValues - 表单值类型。\n * @param name - 要监听的字段路径\n * @param callback - 字段变化回调;payload 为 `{ value, prevValue }`\n * @param options - 可选配置\n * @returns 取消监听函数\n *\n * @example\n * ```ts\n * useWatchField(\"email\", (_values, payload) => {\n * const { value, prevValue } = payload\n * console.log(prevValue, value)\n * })\n * ```\n */\nexport function useWatchField<TValues extends Values = Values>(\n name: NamePath<TValues>,\n callback: WatchFieldCallback<TValues>,\n options?: CreateWatchOptions\n): () => void {\n return useWatch<TValues>(name, callback, options)\n}\n\n/**\n * 监听多个字段变化的便捷方法\n *\n * 等价于 `useWatch(names, callback, options)`,语义更明确。\n * 自动绑定 formContext 并在组件卸载时取消监听。\n *\n * @typeParam TValues - 表单值类型。\n * @param names - 要监听的字段路径数组\n * @param callback - 字段变化回调;payload 为 `{ changedPaths, changedValues, prevValues }`\n * @param options - 可选配置\n * @returns 取消监听函数\n *\n * @example\n * ```ts\n * useWatchFields([\"firstName\", \"lastName\"], (_values, payload) => {\n * const { changedPaths, changedValues, prevValues } = payload\n * console.log(changedPaths, changedValues, prevValues)\n * })\n * ```\n */\nexport function useWatchFields<TValues extends Values>(\n names: NamePath<TValues>[],\n callback: WatchFieldsCallback<TValues>,\n options?: CreateWatchOptions\n): () => void {\n return useWatch<TValues>(names, callback, options)\n}\n\n/**\n * 监听所有字段变化的便捷方法\n *\n * 等价于 `useWatch(callback, options)`,语义更明确。\n * 自动绑定 formContext 并在组件卸载时取消监听。\n *\n * @typeParam TValues - 表单值类型。\n * @param callback - 全局变化回调;payload 为 `{ changedPaths, changedValues, prevValues }`\n * @param options - 可选配置\n * @returns 取消监听函数\n *\n * @example\n * ```ts\n * useWatchAll((_values, payload) => {\n * const { changedPaths, changedValues, prevValues } = payload\n * console.log(changedPaths, changedValues, prevValues)\n * })\n * ```\n */\nexport function useWatchAll<TValues extends Values = Values>(\n callback: WatchAllCallback<TValues>,\n options?: CreateWatchOptions\n): () => void {\n return useWatch(callback, options)\n}\n\nexport default useWatch\n","/**\n * useDictionary - 字典选项 Hook\n *\n * 通过 api 函数加载字典选项,支持完整的表单值泛型推导。\n * 自动在组件挂载时加载,支持通过 dependsOn 声明依赖字段,\n * 当依赖字段变化时自动重新请求。\n *\n * @module hooks/useDictionary\n */\n\nimport { onMounted, onScopeDispose, Ref, ref, shallowRef } from \"vue\"\n\nimport type { SchemxDictionary } from \"@/types/dictionary\"\n\nimport { useFormContext } from \"../context/formContext\"\n\nimport { useWatchFields } from \"./useWatch\"\n\nimport type { NamePath, SchemxInstance, Values } from \"@schemx/core\"\n\nexport type { SchemxDictionary, SchemxWithDictionary } from \"@/types/dictionary\"\n\n/**\n * useDictionary 返回值。\n *\n * @typeParam TOption - 格式化后的字典选项类型。\n */\nexport interface UseDictionaryReturn<TOption = unknown> {\n /**\n * 远程加载的字典选项列表(响应式)\n */\n list: Ref<TOption[]>\n /**\n * 请求加载状态(响应式)\n */\n loading: Ref<boolean>\n /**\n * 请求错误信息(响应式)\n */\n error: Ref<Error | undefined>\n /**\n * 触发字典选项加载\n */\n loadDict: () => Promise<void>\n /**\n * 使用当前配置重新执行 api\n */\n refresh: () => Promise<void>\n /**\n * 直接修改 list 的值,不触发 api 调用\n */\n mutate: (data: TOption[]) => void\n}\n\n/**\n * useDictionary 返回值的旧类型别名。\n *\n * @deprecated 请使用 `UseDictionaryReturn`。\n * @typeParam TOption - 格式化后的字典选项类型。\n */\nexport type UseDictOptionsReturn<TOption = unknown> = UseDictionaryReturn<TOption>\n\n/**\n * 将未知抛出值规范化为 `Error` 实例\n *\n * @param err - 捕获的值(可能是任意类型)\n * @returns 包装原始值的 `Error` 对象\n *\n * @example\n * ```ts\n * const error = normalizeError(\"request failed\")\n * ```\n */\nexport function normalizeError(err: unknown): Error {\n if (err instanceof Error) return err\n\n return new Error(String(err))\n}\n\n/**\n * 加载字典选项\n *\n * 通过 api 函数获取数据,支持完整的表单值泛型推导。\n * 自动在组件挂载时加载,支持依赖字段联动、竞态控制、\n * 重试、错误处理等能力。\n *\n * @typeParam TValues - 表单值类型\n * @typeParam TName - 当前字段路径类型\n * @typeParam TResponse - api 的原始返回值类型\n * @typeParam TOption - 格式化后的字典选项类型\n * @param options - 字典配置选项\n * @param fieldName - 当前字段名,用于 resetOnDepsChange 时清空字段值\n * @returns `{ list, loading, error, loadDict, refresh, mutate }`:响应式选项、\n * 加载与错误状态,以及加载、刷新和本地更新方法\n *\n * @example\n * ```ts\n * // 基础用法\n * const { list, loading, error, loadDict, refresh, mutate } = useDictionary({\n * api: async () => {\n * const res = await fetch('/api/options')\n * return res.json()\n * },\n * })\n *\n * await loadDict() // 主动加载\n * await refresh() // 使用当前配置重新加载\n * mutate([{ label: \"手动选项\", value: \"manual\" }])\n * console.log(list.value, loading.value, error.value)\n *\n * // 依赖联动(带泛型)\n * const { list } = useDictionary<MyFormValues>({\n * api: async (values) => fetchCities(values.province),\n * dependsOn: ['province'],\n * shouldFetch: (values) => !!values.province,\n * resetOnDepsChange: true,\n * immediate: false,\n * }, 'city')\n * ```\n */\nexport const useDictionary = <\n TValues extends Values = Values,\n TName extends NamePath<TValues> = NamePath<TValues>,\n TResponse = unknown,\n TOption = unknown,\n>(\n options: SchemxDictionary<TValues, TResponse, TOption>,\n fieldName?: TName\n): UseDictionaryReturn<TOption> => {\n const instance = useFormContext<TValues>()\n\n const list = shallowRef<TOption[]>([])\n\n const loading = ref<boolean>(false)\n\n const error = ref<Error | undefined>(undefined)\n\n // 竞态控制:仅最新请求写入状态\n let requestCount = 0\n\n let activeController: AbortController | null = null\n\n /**\n * 使用配置的 formatter 格式化原始响应数据\n *\n * @param res - api 返回的原始数据。\n * @returns 可供 Renderer 使用的选项列表。\n */\n const format = async (res: Awaited<TResponse>): Promise<TOption[]> => {\n if (typeof options?.formatter === \"function\") {\n return await options.formatter(res, instance)\n }\n\n if (!Array.isArray(res)) {\n throw new Error(\n \"[schemx] Dictionary api must return an array when formatter is not provided.\"\n )\n }\n\n return res as TOption[]\n }\n\n /**\n * 带重试的执行\n *\n * @param formValues - 当前表单值快照。\n * @param signal - 用于中止当前请求或重试等待的信号。\n * @returns api 返回的原始数据。\n */\n const executeWithRetry = async (\n formValues: TValues,\n signal: AbortSignal\n ): Promise<Awaited<TResponse>> => {\n const maxRetries = options.retryCount ?? 0\n\n const retryDelay = options.retryInterval ?? 1000\n\n let lastError: Error = new Error(\"Unknown error\")\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n if (signal.aborted) {\n throw new Error(\"Dictionary request aborted\")\n }\n\n return await callDictionaryApi(formValues, instance, options.api, signal)\n } catch (err) {\n lastError = normalizeError(err)\n\n if (attempt < maxRetries) {\n await waitForRetry(retryDelay, signal)\n }\n }\n }\n\n throw lastError\n }\n\n /**\n * 执行 api 函数加载字典选项\n *\n * 只有最后一次请求可以写入响应式状态;组件卸载或新请求开始时,旧请求会被忽略。\n */\n const loadDict = async (): Promise<void> => {\n const currentCount = ++requestCount\n\n activeController?.abort()\n\n const controller = new AbortController()\n\n activeController = controller\n\n try {\n const formValues = instance.getFieldsSnapshot()\n\n // shouldFetch 检查\n if (typeof options.shouldFetch === \"function\" && !options.shouldFetch(formValues)) {\n list.value = []\n loading.value = false\n\n return\n }\n\n loading.value = true\n error.value = undefined\n\n const res = await executeWithRetry(formValues, controller.signal)\n\n // 竞态检查:丢弃过期响应\n if (currentCount !== requestCount || controller.signal.aborted) return\n\n const formatted = await format(res)\n\n // 格式化后再次竞态检查(格式化可能是异步的)\n if (currentCount !== requestCount || controller.signal.aborted) return\n\n list.value = formatted\n error.value = undefined\n\n // onSuccess 回调\n if (typeof options.onSuccess === \"function\") {\n options.onSuccess(formatted, instance)\n }\n\n loading.value = false\n } catch (err) {\n if (controller.signal.aborted || currentCount !== requestCount) {\n return\n }\n\n const normalized = normalizeError(err)\n\n error.value = normalized\n list.value = []\n loading.value = false\n\n if (typeof options.onError === \"function\") {\n options.onError(normalized, instance)\n }\n } finally {\n if (activeController === controller) {\n activeController = null\n }\n }\n }\n\n // 使用当前配置重新执行一次字典请求。\n const refresh = (): Promise<void> => loadDict()\n\n // 直接替换当前选项列表,不触发远程请求。\n const mutate = (data: TOption[]): void => {\n list.value = data\n }\n\n // ========== 依赖字段监听 ==========\n if (options.dependsOn?.length) {\n useWatchFields(\n options.dependsOn,\n (latestSnapshot, _payload) => {\n // 1. 触发 onDepsChange 回调\n if (typeof options.onDepsChange === \"function\") {\n options.onDepsChange(latestSnapshot as TValues, instance)\n }\n\n // 2. 清空当前字段值\n if (options.resetOnDepsChange && fieldName) {\n instance.setFieldValue(fieldName, undefined)\n }\n\n // 3. 重新执行 api\n void loadDict()\n },\n { inequality: true }\n )\n }\n\n // ========== 挂载行为 ==========\n const immediate = options.immediate ?? true\n\n onMounted(() => {\n if (immediate) {\n void loadDict()\n }\n })\n\n onScopeDispose(() => {\n requestCount += 1\n activeController?.abort()\n activeController = null\n })\n\n return { list, loading, error, loadDict, refresh, mutate }\n}\n\n/**\n * 可响应 AbortSignal 的重试等待。\n *\n * @param delay - 等待时长,单位为毫秒。\n * @param signal - 中止等待的 AbortSignal。\n * @returns 等待完成后 resolve;中止时 reject。\n */\nfunction waitForRetry(delay: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n let abort = (): void => {}\n\n const cleanup = (): void => {\n clearTimeout(timeoutId)\n signal.removeEventListener(\"abort\", abort)\n }\n\n const complete = (): void => {\n cleanup()\n resolve()\n }\n\n const timeoutId = setTimeout(complete, delay)\n\n abort = (): void => {\n cleanup()\n reject(new Error(\"Dictionary request aborted\"))\n }\n\n if (signal.aborted) {\n abort()\n\n return\n }\n\n signal.addEventListener(\"abort\", abort, { once: true })\n })\n}\n\n/**\n * 兼容旧的两参数字典 API;显式声明第三参数时才传入 AbortSignal。\n *\n * @param values - 当前表单值快照。\n * @param form - 当前表单实例。\n * @param api - 字典数据获取函数。\n * @param signal - 当前请求的 AbortSignal。\n * @returns api 的同步或异步返回值。\n */\nfunction callDictionaryApi<TValues extends Values, TResponse>(\n values: TValues,\n form: SchemxInstance<TValues>,\n api: SchemxDictionary<TValues, TResponse>[\"api\"],\n signal: AbortSignal\n): TResponse | Promise<TResponse> {\n if (api.length >= 3) {\n return api(values, form, signal)\n }\n\n return api(values, form)\n}\n\nexport default useDictionary\n","/**\n * 对象浅比较工具\n *\n * @module utils/equal\n */\n\n/**\n * 浅比较两个对象的自有属性值是否相同。\n *\n * 用于避免 computed / shallowRef 每次返回新对象引用导致子组件不必要的更新。\n * 仅比较第一层属性,函数引用通过 === 判断。\n *\n * @param a - 旧对象\n * @param b - 新对象\n *\n * @returns 两个对象浅相等时返回 true\n *\n * @example\n * isShallowEqual({ a: 1, b: 2 }, { a: 1, b: 2 }) // => true\n * isShallowEqual({ a: 1 }, { a: 1, b: 2 }) // => false\n */\nexport const isShallowEqual = (\n a: Record<string, any>,\n b: Record<string, any>\n): boolean => {\n const keysA = Object.keys(a)\n\n const keysB = Object.keys(b)\n\n if (keysA.length !== keysB.length) return false\n\n return keysA.every((key) => a[key] === b[key])\n}\n","/**\n * useStableRef - 引用稳定化的 shallowRef\n *\n * 封装 `shallowRef` + `watchEffect` + `isShallowEqual`,\n * 仅在工厂函数返回值与当前值浅不相等时才更新引用,\n * 避免下游组件因对象引用变化而不必要地重渲染。\n *\n * @module hooks/useStableRef\n *\n * @example\n * ```ts\n * import { useStableRef } from '@schemx/vue'\n *\n * const stableProps = useStableRef(() => ({\n * visible: visible.value,\n * disabled: disabled.value,\n * value: field.getValue(),\n * }))\n * ```\n */\n\nimport { type ShallowRef, shallowRef, watchEffect } from \"vue\"\n\nimport { isShallowEqual } from \"../utils/equal\"\n\n/**\n * 创建一个引用稳定的 shallowRef。\n *\n * 在 watchEffect 中执行工厂函数,自动追踪响应式依赖。\n * 仅当新旧值浅比较不相等时才替换 `.value`,保持引用稳定。\n *\n * @typeParam TValue - 需要保持引用稳定的对象类型\n *\n * @param factory - 返回目标对象的工厂函数,在 watchEffect 内执行\n *\n * @returns 只读的 ShallowRef,引用仅在属性值真正变化时更新\n *\n * @example\n * ```ts\n * const props = useStableRef(() => ({\n * value: field.getValue(),\n * onChange: handleChange,\n * }))\n *\n * // props.value 的引用在属性值未变时保持不变\n * h(Component, props.value)\n * ```\n */\nexport function useStableRef<TValue extends Record<string, any>>(\n factory: () => TValue\n): Readonly<ShallowRef<TValue>> {\n const stableRef = shallowRef({} as TValue) as ShallowRef<TValue>\n\n watchEffect(() => {\n const next = factory()\n\n if (!isShallowEqual(stableRef.value, next)) {\n stableRef.value = next\n }\n })\n\n return stableRef\n}\n\nexport default useStableRef\n","/**\n * useViewSchemas - Vue ViewSchema 状态读取。\n *\n * ViewSchema 投影由 Form Runtime 统一缓存和回收;Hook 只绑定当前 scope 的\n * Runtime owner。\n *\n * @module hooks/useViewSchemas\n */\n\nimport { computed } from \"vue\"\nimport type { ComputedRef, ShallowRef } from \"vue\"\n\nimport { useVueFormRuntime } from \"../bridge\"\n\nimport type { SchemxInstance, SchemxViewSchema, Values } from \"@schemx/core\"\n\n/**\n * 获取当前表单共享的 ViewSchema 列表。\n *\n * @typeParam TValues - 表单值类型。\n * @param form - 要读取 ViewSchema 的表单实例。\n * @returns 当前表单的响应式 ViewSchema 列表。\n *\n * @example\n * ```ts\n * const schemas = useViewSchemas(form)\n * console.log(schemas.value)\n * ```\n */\nexport function useViewSchemas<TValues extends Values = Values>(\n form: SchemxInstance<TValues>\n): ShallowRef<readonly SchemxViewSchema<TValues>[]> {\n const state = useVueFormRuntime(form).getViewSchemaState()\n\n return state.viewSchemas\n}\n\n/**\n * 获取当前 key 对应的共享 ViewSchema。\n *\n * @typeParam TValues - 表单值类型。\n * @param form - 要读取 ViewSchema 的表单实例。\n * @param getKey - 返回目标 ViewSchema key 的响应式函数。\n * @returns 当前 key 对应的 ViewSchema;不存在时为 `undefined`。\n *\n * @example\n * ```ts\n * const schema = useViewSchema(form, () => currentKey.value)\n * ```\n */\nexport function useViewSchema<TValues extends Values = Values>(\n form: SchemxInstance<TValues>,\n getKey: () => string\n): ComputedRef<SchemxViewSchema<TValues> | undefined> {\n const state = useVueFormRuntime(form).getViewSchemaState()\n\n const schema = computed(() => state.schemasByKey.value.get(getKey()))\n\n return schema\n}\n\nexport default useViewSchemas\n","/**\n * useFormSelector - Core 表单值的 Vue 响应式选择器桥接。\n *\n * @module hooks/useFormSelector\n */\n\nimport { readonly, shallowRef, watch } from \"vue\"\nimport type { ShallowRef } from \"vue\"\n\nimport { useVueFormRuntime } from \"../bridge\"\n\nimport type { SchemxInstance, Values } from \"@schemx/core\"\n\n/**\n * `useFormSelector` 的选中结果比较配置。\n */\nexport interface UseFormSelectorOptions<TSelected> {\n /**\n * 判断两次 selector 结果是否等价;返回 true 时保持当前 Ref 值。\n * 默认使用 `Object.is`。\n */\n equals?: (previous: TSelected, next: TSelected) => boolean\n\n /**\n * Vue watcher 的刷新时机;默认 `sync` 以保持现有表单同步语义。\n */\n flush?: \"sync\" | \"pre\" | \"post\"\n}\n\n/**\n * 将 Core 表单值按 selector 映射为 Vue 只读浅引用。\n *\n * selector 只应读取快照,不应通过快照修改表单值或调用表单写入方法。\n * `Readonly<TValues>` 仅表达顶层只读,嵌套字段应按不可变值使用;字段值需通过\n * `setFieldValue()` 或 `setFieldsValue()` 更新,才能触发后续计算。\n *\n * @typeParam TValues - 表单值类型。\n * @typeParam TSelected - selector 返回值类型。\n * @param form - 要订阅的表单实例。\n * @param selector - 从当前表单值快照派生结果的纯函数。\n * @param options - 选中结果的比较配置。\n * @returns selector 当前结果的 Vue 只读浅引用。\n *\n * @example\n * ```ts\n * const selectedName = useFormSelector(form, (values) => values.name)\n *\n * watchEffect(() => {\n * console.log(selectedName.value)\n * })\n * ```\n */\nexport function useFormSelector<TValues extends Values = Values, TSelected = unknown>(\n form: SchemxInstance<TValues>,\n selector: (values: Readonly<TValues>) => TSelected,\n options: UseFormSelectorOptions<TSelected> = {}\n): Readonly<ShallowRef<TSelected>> {\n const values = useVueFormRuntime(form).getValuesRef()\n\n const selected = shallowRef<TSelected>(selector(values.value))\n\n const equals = options.equals ?? Object.is\n\n /**\n * 根据完整快照重新计算 selector,并只在结果变化时更新 Ref。\n *\n * @param values - Runtime 发布的最新完整表单快照。\n */\n watch(\n values,\n (values) => {\n const next = selector(values)\n\n if (!equals(selected.value, next)) {\n selected.value = next\n }\n },\n { flush: options.flush ?? \"sync\" }\n )\n\n return readonly(selected) as Readonly<ShallowRef<TSelected>>\n}\n\nexport default useFormSelector\n","/**\n * 校验触发工具\n *\n * 提供校验触发时机的合并、归一化和匹配判断功能。\n *\n * @module utils/validation\n */\n\nimport type { ValidationTrigger } from \"@schemx/core\"\n\n/**\n * 触发时机类型(支持单个或数组)\n */\nexport type TriggerConfig = ValidationTrigger | ValidationTrigger[]\n\n/**\n * 归一化后的触发类型\n */\nexport type NormalizedTrigger = \"blur\" | \"change\" | \"submit\"\n\n/**\n * 判断触发时机配置是否有效。\n *\n * undefined 和空数组视为无效,其余值(包括单个字符串、非空数组)视为有效。\n *\n * @param v - 触发时机配置\n *\n * @returns 配置有效时返回 true\n */\nfunction isValidTrigger(v: TriggerConfig | undefined): v is TriggerConfig {\n if (v === undefined) return false\n if (Array.isArray(v) && v.length === 0) return false\n\n return true\n}\n\n/**\n * 合并校验触发时机配置。\n *\n * 按优先级从高到低取值:列级配置 > 表单上下文配置 > 默认值。\n * 跳过 undefined 和空数组,确保空数组不会意外覆盖后续配置。\n *\n * @param columnTrigger - 列级配置的触发时机\n * @param contextTrigger - 表单上下文配置的触发时机\n * @param defaultTrigger - 兜底默认值\n *\n * @returns 最终生效的触发时机\n *\n * @example\n * mergeTrigger(\"onBlur\", \"onChange\", \"onSubmit\") // => \"onBlur\"\n * mergeTrigger(undefined, \"onChange\", \"onSubmit\") // => \"onChange\"\n * mergeTrigger([], \"onChange\", \"onSubmit\") // => \"onChange\"\n * mergeTrigger(undefined, undefined, \"onSubmit\") // => \"onSubmit\"\n */\nexport function mergeTrigger(\n columnTrigger: TriggerConfig | undefined,\n contextTrigger: TriggerConfig | undefined,\n defaultTrigger: TriggerConfig\n): TriggerConfig {\n if (isValidTrigger(columnTrigger)) return columnTrigger\n\n if (isValidTrigger(contextTrigger)) return contextTrigger\n\n return defaultTrigger\n}\n\n/**\n * 归一化触发类型字符串。\n *\n * 将带 `on` 前缀的格式统一为短格式:\n * `\"onBlur\"` → `\"blur\"`、`\"onChange\"` → `\"change\"`、`\"onSubmit\"` → `\"submit\"`。\n *\n * @param t - 原始触发类型\n *\n * @returns 归一化后的触发类型\n */\nfunction normalizeTrigger(t: ValidationTrigger): NormalizedTrigger {\n const map: Record<ValidationTrigger, NormalizedTrigger> = {\n onBlur: \"blur\",\n onChange: \"change\",\n onSubmit: \"submit\",\n blur: \"blur\",\n change: \"change\",\n submit: \"submit\",\n }\n\n return map[t] ?? \"submit\"\n}\n\n/**\n * 判断当前事件是否应该触发校验。\n *\n * 将配置的触发时机归一化后,与当前事件类型进行匹配。\n *\n * @param event - 当前触发的事件类型\n * @param trigger - 配置的触发时机(支持单个或数组)\n *\n * @returns 是否应该触发校验\n *\n * @example\n * shouldValidateOn(\"change\", \"onChange\") // => true\n * shouldValidateOn(\"blur\", [\"onBlur\", \"onChange\"]) // => true\n * shouldValidateOn(\"change\", \"onSubmit\") // => false\n * shouldValidateOn(\"change\", undefined) // => false\n */\nexport function shouldValidateOn(\n event: NormalizedTrigger,\n trigger?: TriggerConfig\n): boolean {\n if (!trigger) return false\n const triggers = Array.isArray(trigger) ? trigger : [trigger]\n\n return triggers.some((t) => normalizeTrigger(t) === event)\n}\n","/**\n * 插槽解析与子插槽提取工具。\n *\n * 提供 camelCase / kebab-case 双向查找插槽,\n * 以及按字段名前缀提取子渲染器插槽。\n *\n * @module utils/slot\n */\n\n/**\n * 检查字符串是否包含大写字母(驼峰格式特征)。\n *\n * @param str - 待检测的字符串\n * @returns 是否包含大写字母\n */\nconst isCamelCase = (str: string): boolean => /[A-Z]/.test(str)\n\n/**\n * 检查字符串是否包含连字符(kebab-case 特征)。\n *\n * @param str - 待检测的字符串\n * @returns 是否包含连字符\n */\nconst isKebabCase = (str: string): boolean => str.includes(\"-\")\n\n/**\n * 将驼峰命名转换为连字符命名(kebab-case)。\n *\n * @param str - 驼峰格式的字符串\n * @returns 转换后的 kebab-case 字符串\n */\nconst camelToKebab = (str: string): string => {\n return str.replace(/([A-Z])/g, \"-$1\").toLowerCase()\n}\n\n/**\n * 将连字符命名转换为驼峰命名(camelCase)。\n *\n * @param str - kebab-case 格式的字符串\n * @returns 转换后的 camelCase 字符串\n */\nconst kebabToCamel = (str: string): string => {\n return str.replace(/-([a-z])/g, (_match, letter) => letter.toUpperCase())\n}\n\n/**\n * 将命名格式归一化为 kebab-case。\n *\n * @param str - 任意命名格式的字符串\n * @returns kebab-case 格式的字符串\n */\nconst normalizeToKebab = (str: string): string => {\n if (isCamelCase(str)) return camelToKebab(str)\n\n return str\n}\n\n/**\n * 将命名格式归一化为 camelCase。\n *\n * @param str - 任意命名格式的字符串\n * @returns camelCase 格式的字符串\n */\nconst normalizeToCamel = (str: string): string => {\n if (isKebabCase(str)) return kebabToCamel(str)\n\n return str\n}\n\n/**\n * 从插槽对象中按名称查找插槽,同时支持 camelCase 和 kebab-case。\n *\n * 优先查找原始名称,未找到时尝试另一种命名格式。\n * 例如传入 `userName` 时,先查 `userName`,再查 `user-name`;\n * 传入 `user-name` 时,先查 `user-name`,再查 `userName`。\n *\n * @param slots - Vue 插槽对象\n * @param name - 插槽名称(camelCase 或 kebab-case)\n *\n * @returns 匹配的插槽函数,未找到返回 undefined\n *\n * @example\n * ```typescript\n * // slots 中定义了 'user-name' 插槽\n * resolveSlot(slots, 'userName') // => 找到 'user-name' 插槽\n * resolveSlot(slots, 'user-name') // => 找到 'user-name' 插槽\n * ```\n */\nexport const resolveSlot = (\n slots: Record<string, any>,\n name: string\n): ((...args: any[]) => any) | undefined => {\n if (slots[name]) return slots[name]\n\n const alt = isCamelCase(name)\n ? camelToKebab(name)\n : isKebabCase(name)\n ? kebabToCamel(name)\n : undefined\n\n if (alt && slots[alt]) return slots[alt]\n\n return undefined\n}\n\n/**\n * 从父级插槽中提取子渲染器插槽。\n *\n * 按 `fieldName:slotName` 和 `fieldName:slot-name` 格式匹配,\n * 提取后去掉前缀作为子渲染器的插槽名。\n * 同时支持 camelCase 和 kebab-case 的 fieldName。\n *\n * @param fieldName - 字段名\n * @param allSlots - 父级全部插槽\n *\n * @returns 子渲染器的插槽对象\n *\n * @example\n * ```typescript\n * // 父级插槽: { 'userName:prefix': fn, 'userName:suffix': fn, 'userNameLabel': fn }\n * extractChildSlots('userName', slots)\n * // => { prefix: fn, suffix: fn }\n * ```\n */\nexport const extractChildSlots = (\n fieldName: string,\n allSlots: Record<string, any>\n): Record<string, any> => {\n const result: Record<string, any> = {}\n\n const camelPrefix = normalizeToCamel(String(fieldName)) + \":\"\n\n const kebabPrefix = normalizeToKebab(String(fieldName)) + \":\"\n\n for (const [key, value] of Object.entries(allSlots)) {\n if (key.startsWith(camelPrefix)) {\n result[key.slice(camelPrefix.length)] = value\n } else if (key.startsWith(kebabPrefix) && kebabPrefix !== camelPrefix) {\n result[key.slice(kebabPrefix.length)] = value\n }\n }\n\n return result\n}\n","/**\n * Vue 渲染层使用的 Schema 位置与 DOM key 辅助函数。\n *\n * @module utils/helpers\n */\n\nimport { isViewGroupSchema, SchemxViewSchema } from \"@schemx/core\"\n\n/**\n * 判断当前项是否为顶层可见普通字段所在区段的第一个或最后一个。\n *\n * 可见 Group 是区段边界;不可见字段和不可见 Group 不参与计算。\n *\n * 使用示例:\n *\n * const list = [\n * { key: 'group-1', children: [] },\n * { key: 'a' },\n * { key: 'b' },\n * { key: 'group-2', children: [] },\n * { key: 'c' },\n * ]\n *\n * getSectionPosition(list, 'a')\n * // => { found: true, isFirst: true, isLast: false }\n *\n * @param list - 当前层级的 ViewSchema 列表。\n * @param currentKey - 要定位的 ViewSchema key。\n * @returns 当前项是否存在以及它在所在区段中的首尾位置。\n */\nexport function getSectionPosition<TItem extends SchemxViewSchema>(\n list: TItem[],\n currentKey: string\n) {\n const currentIndex = list.findIndex((item) => item.key === currentKey)\n\n if (currentIndex === -1) {\n return {\n found: false,\n isFirst: false,\n isLast: false,\n }\n }\n\n const currentItem = list[currentIndex]\n\n if (!isPositionItem(currentItem)) {\n return {\n found: true,\n isFirst: false,\n isLast: false,\n }\n }\n\n return {\n found: true,\n isFirst: !hasPositionItemInSection(list, currentIndex, -1),\n isLast: !hasPositionItemInSection(list, currentIndex, 1),\n }\n}\n\n/**\n * 将 NamePath 转换为整体字段与 Renderer 子插槽使用的键。\n *\n * @param name - 字符串字段名或由路径片段组成的字段名。\n * @returns 使用点号连接的稳定字段键。\n *\n * @example\n * ```ts\n * normalizeNameKey([\"user\", \"name\"]) // \"user.name\"\n * ```\n */\nexport function normalizeNameKey(name: unknown): string {\n if (Array.isArray(name)) {\n return name.map((part) => String(part)).join(\".\")\n }\n\n return String(name)\n}\n\n/**\n * 将分组 key 转换为可用于 DOM ID 的安全字符串。\n *\n * @param key - Schema 或 Group 的原始 key。\n * @returns 仅包含字母、数字、下划线和连字符的字符串。\n *\n * @example\n * ```ts\n * normalizeId(\"address.city\") // \"address-city\"\n * ```\n */\nexport function normalizeId(key: string): string {\n return String(key).replace(/[^a-zA-Z0-9_-]/g, \"-\")\n}\n\n/**\n * 判断项是否为参与区段首尾计算的可见普通字段。\n *\n * @param item - 待判断的 ViewSchema。\n * @returns 项存在、可见且不是 Group 时返回 `true`。\n */\nfunction isPositionItem<TItem extends SchemxViewSchema>(item?: TItem) {\n return !!item && !isViewGroupSchema(item) && item.visible !== false\n}\n\n/**\n * 从当前项向指定方向查找同一区段内的可定位字段。\n *\n * @param list - 当前层级的 ViewSchema 列表。\n * @param startIndex - 当前项的索引。\n * @param step - 向前或向后查找的步长。\n * @returns 找到同一区段中的可见普通字段时返回 `true`。\n */\nfunction hasPositionItemInSection<TItem extends SchemxViewSchema>(\n list: TItem[],\n startIndex: number,\n step: 1 | -1\n): boolean {\n for (let index = startIndex + step; index >= 0 && index < list.length; index += step) {\n const item = list[index]\n\n if (item.visible === false) {\n continue\n }\n\n if (isViewGroupSchema(item)) {\n return false\n }\n\n if (isPositionItem(item)) {\n return true\n }\n }\n\n return false\n}\n","/**\n * Field 插槽渲染器。\n *\n * 集中处理字段各区域的插槽解析,保持 Field 仅负责字段状态和布局。\n *\n * @module components/Field/slot\n */\n\nimport { h } from \"vue\"\nimport type { ShallowRef, Slots, VNodeChild } from \"vue\"\n\nimport { extractChildSlots, normalizeNameKey, resolveSlot } from \"../../utils\"\n\nimport type { FormConfigContextValue } from \"../../context/formContext\"\nimport type { FieldInstance } from \"../../types/field\"\nimport type {\n SchemxComponentProps,\n SchemxInstance,\n SchemxViewFieldSchema,\n Values,\n} from \"@schemx/core\"\n\n/**\n * Field 插槽渲染所需的状态与依赖。\n */\ninterface FieldSlotRendererOptions<TValues extends Values = Values> {\n /**\n * 当前字段 ViewSchema。\n */\n schemaRef: Readonly<ShallowRef<SchemxViewFieldSchema<TValues>>>\n /**\n * 当前字段的响应式控制器。\n */\n field: FieldInstance<TValues>\n /**\n * 当前表单实例,用于解析 Renderer。\n */\n form: SchemxInstance<TValues>\n /**\n * 表单级展示配置。\n */\n formContext: FormConfigContextValue\n /**\n * 传给 Renderer 的稳定属性。\n */\n componentProps: Readonly<ShallowRef<SchemxComponentProps<TValues>>>\n /**\n * 父组件传入的所有具名插槽。\n */\n slots: Slots\n}\n\n/**\n * 创建 Field 各区域的插槽渲染函数。\n *\n * `Before`、`Content`、`After` 依次包裹 Renderer;`Error` 位于控件之后。\n *\n * @param options - Field 插槽渲染所需的响应式状态和 Vue 插槽集合。\n * @returns 各字段区域的插槽渲染函数及统一 Slot Props 构造器。\n *\n * @example\n * ```ts\n * const renderers = createFieldSlotRenderers(options)\n * renderers.renderContent()\n * ```\n */\nexport function createFieldSlotRenderers<TValues extends Values = Values>(\n options: FieldSlotRendererOptions<TValues>\n) {\n const { schemaRef, field, form, formContext, componentProps, slots } = options\n\n /**\n * 渲染 required 星号。\n *\n * `showRequiredMark` 未设置时回退到 `required`;该展示开关不参与校验逻辑。\n * 禁用或只读字段始终不显示星号。\n *\n * @returns 星号 VNode 或空片段\n */\n const renderRequired = (): VNodeChild => {\n const showRequiredMark =\n schemaRef.value.showRequiredMark ?? Boolean(schemaRef.value.required)\n\n if (!showRequiredMark || schemaRef.value.disabled || schemaRef.value.readonly) {\n return null\n }\n\n return <span class=\"schemx-field__required\">*</span>\n }\n\n /**\n * 构造各字段插槽共用的规范上下文参数。\n *\n * @param additionalProps - 当前插槽额外携带的属性。\n * @returns 传给字段插槽的统一上下文对象。\n */\n const createSlotProps = (additionalProps: Record<string, unknown> = {}) => {\n return {\n schema: schemaRef.value,\n componentProps: componentProps.value,\n value: field.value.value,\n field,\n form,\n ...additionalProps,\n }\n }\n\n /**\n * 渲染指定后缀的字段区域插槽。\n *\n * @param suffix - 字段插槽名称后缀,例如 `Before` 或 `After`。\n * @returns 匹配插槽生成的 VNode;未匹配时返回空内容。\n */\n const renderFieldSlot = (suffix: string): VNodeChild => {\n const slot = resolveSlot(slots, `${normalizeNameKey(schemaRef.value.name)}${suffix}`)\n\n return slot?.(createSlotProps()) ?? null\n }\n\n /**\n * 渲染标签区域,优先使用 `{name}Label` 插槽。\n */\n const renderLabel = (): VNodeChild => {\n const labelSlot = resolveSlot(slots, `${normalizeNameKey(schemaRef.value.name)}Label`)\n\n if (labelSlot) {\n return labelSlot(createSlotProps())\n }\n\n const labelAlign = schemaRef.value.labelAlign || formContext.schemaConfig.labelAlign\n\n const labelWidth = schemaRef.value.labelWidth || formContext.schemaConfig.labelWidth\n\n const colon = schemaRef.value.colon ?? formContext.schemaConfig.colon\n\n return (\n <label\n class=\"schemx-field__label\"\n style={{ width: labelWidth, textAlign: labelAlign }}\n >\n {renderRequired()}\n {schemaRef.value.labelIcon ? (\n <span class=\"schemx-field__label-icon\">{schemaRef.value.labelIcon}</span>\n ) : null}\n <span class=\"schemx-field__label-text\">\n {schemaRef.value.label}\n {colon ? \":\" : \"\"}\n </span>\n </label>\n )\n }\n\n /**\n * 渲染 Renderer 前的 `{name}Before` 插槽。\n */\n const renderBefore = (): VNodeChild => renderFieldSlot(\"Before\")\n\n /**\n * 渲染控件区域,优先使用 `{name}Content` 插槽。\n */\n const renderContent = (): VNodeChild => {\n const component = form.getRenderer(schemaRef.value.componentType)\n\n if (!component) {\n throw new Error(\n `[schemx] Can not find component renderer of \"${schemaRef.value.componentType}\".`\n )\n }\n\n const childSlots = extractChildSlots(normalizeNameKey(schemaRef.value.name), slots)\n\n const columnElement = h(component, componentProps.value, childSlots)\n\n const contentSlot = resolveSlot(\n slots,\n `${normalizeNameKey(schemaRef.value.name)}Content`\n )\n\n if (contentSlot) {\n return contentSlot(\n createSlotProps({\n columnElement,\n })\n )\n }\n\n return <div class=\"schemx-field__control\">{columnElement}</div>\n }\n\n /**\n * 渲染 Renderer 后的 `{name}After` 插槽。\n */\n const renderAfter = (): VNodeChild => renderFieldSlot(\"After\")\n\n /**\n * 渲染错误区域,优先使用 `{name}Error` 插槽。\n */\n const renderError = (): VNodeChild => {\n const errorSlot = resolveSlot(slots, `${normalizeNameKey(schemaRef.value.name)}Error`)\n\n if (errorSlot) {\n return errorSlot(\n createSlotProps({\n errors: field.errors.value,\n })\n )\n }\n\n if (field.errors.value.length === 0) {\n return null\n }\n\n return <div class=\"schemx-field__error\">{field.errors.value[0]}</div>\n }\n\n return {\n createSlotProps,\n renderAfter,\n renderBefore,\n renderContent,\n renderError,\n renderLabel,\n }\n}\n","/**\n * Field\n *\n * schemx 实际渲染字段的组件。\n * 动态属性已由 core 解析到 ViewSchema 中;这里只负责消费\n * 已解析字段 schema、创建字段实例、组装渲染器属性与插槽。\n *\n * @module components/Field\n */\n\n/* eslint-disable vue/one-component-per-file */\nimport { computed, defineComponent, PropType } from \"vue\"\nimport type { ClassValue, SlotsType, StyleValue, VNodeChild } from \"vue\"\n\nimport { isSchemxViewFieldSchema } from \"@schemx/core\"\nimport classnames from \"classnames\"\n\nimport type { TriggerConfig } from \"@/utils\"\n\nimport { createFieldContext, useFormContextValue } from \"../../context\"\nimport { useField, useStableRef } from \"../../hooks\"\nimport { useViewSchema } from \"../../hooks/useViewSchemas\"\nimport {\n mergeTrigger,\n normalizeNameKey,\n resolveSlot,\n shouldValidateOn,\n} from \"../../utils\"\n\nimport { createFieldSlotRenderers } from \"./slot\"\n\nimport type { SchemxFieldSlots } from \"../../types/field\"\nimport type {\n FieldValue,\n NamePath,\n SchemxComponentProps,\n SchemxViewFieldSchema,\n Values,\n} from \"@schemx/core\"\n\n/**\n * Field 属性。\n *\n * 提供待渲染的字段 ViewSchema。\n */\nexport interface SchemxFieldProps {\n /**\n * 当前字段的已解析 ViewSchema。\n */\n schema: unknown\n /**\n * 追加到字段外层包装器的 CSS 类名。\n */\n class?: ClassValue\n /**\n * 追加到字段外层包装器的内联样式。\n */\n style?: StyleValue\n}\n\nconst Field = defineComponent({\n name: \"SchemxField\",\n inheritAttrs: false,\n\n props: {\n schema: {\n type: Object as PropType<unknown>,\n required: true,\n },\n class: {\n type: [String, Object, Array, Boolean] as PropType<ClassValue>,\n required: false,\n default: undefined,\n },\n style: {\n type: [String, Object, Array] as PropType<StyleValue>,\n required: false,\n default: undefined,\n },\n },\n\n slots: Object as SlotsType<SchemxFieldSlots>,\n\n /**\n * 初始化字段上下文,并组合响应式 schema、校验处理器与插槽渲染器。\n *\n * @param props - 当前字段项的 schema 属性。\n * @param attrs - Vue setup 上下文提供的透传属性。\n * @param slots - Vue setup 上下文提供的插槽集合。\n */\n setup(props, { attrs, slots }) {\n const formContext = useFormContextValue<Values>()\n\n const form = formContext.form\n\n const inputSchema = computed<SchemxViewFieldSchema<Values>>(\n () => props.schema as SchemxViewFieldSchema<Values>\n )\n\n // 按 key 复用表单级 ViewSchema 订阅,避免每个 Field 建立独立 Core effect。\n const latestSchema = useViewSchema(form, () => inputSchema.value.key)\n\n // 优先使用桥接中的最新字段;首帧或字段暂不存在时回退到输入 schema。\n const schemaRef = computed<SchemxViewFieldSchema<Values>>(() => {\n return latestSchema.value && isSchemxViewFieldSchema(latestSchema.value)\n ? latestSchema.value\n : inputSchema.value\n })\n\n const field = useField(schemaRef.value.name)\n\n createFieldContext(field)\n\n const trigger = computed<TriggerConfig>(() =>\n mergeTrigger(\n schemaRef.value.validationTrigger,\n formContext.schemaConfig.validationTrigger,\n \"onChange\"\n )\n )\n\n /**\n * 是否需要进行校验。\n *\n * 当字段不可见、只读或禁用时,无需进行校验。\n */\n const canVerified = computed(() => {\n const isOperate =\n schemaRef.value.visible !== false &&\n !schemaRef.value.readonly &&\n !schemaRef.value.disabled\n\n const rules = schemaRef.value.rules\n\n const hasRules = Array.isArray(rules) ? rules?.length > 0 : !!schemaRef.value.rules\n\n return isOperate && (Boolean(schemaRef.value.required) || hasRules)\n })\n\n /**\n * 处理字段值变化,设置值后根据触发时机决定是否校验。\n *\n * @param v - 渲染器提交的最新字段值。\n */\n const handleChange = (v: FieldValue<Values, NamePath<Values>>) => {\n field.setValue(v)\n schemaRef.value.componentProps?.onChange?.(v)\n schemaRef.value.onChange?.(v, form)\n\n if (canVerified.value && shouldValidateOn(\"change\", trigger.value)) {\n field.validate()\n }\n }\n\n /**\n * 处理字段失焦,并根据触发时机决定是否校验。\n *\n * @param v - 触发失焦事件时对应的字段值。\n */\n const handleBlur = (v: FieldValue<Values, NamePath<Values>>) => {\n schemaRef.value.componentProps?.onBlur?.(v)\n schemaRef.value.onBlur?.(form)\n\n if (canVerified.value && shouldValidateOn(\"blur\", trigger.value)) {\n field.validate()\n }\n }\n\n /**\n * 处理组件的 v-model 更新,只同步字段值,不主动触发校验。\n *\n * @param v - 渲染器提交的最新字段值。\n */\n const updateValue = (v: FieldValue<Values, NamePath<Values>>) => {\n field.setValue(v)\n }\n\n // 使用 useStableRef 避免每次生成新对象引用\n const componentProps = useStableRef<SchemxComponentProps<Values>>(\n (): SchemxComponentProps<Values> => {\n const currentComponentProps = schemaRef.value.componentProps ?? {}\n\n return {\n ...currentComponentProps,\n align: schemaRef.value.readonly\n ? \"right\"\n : (currentComponentProps.align ?? schemaRef.value.contentAlign),\n readonly: schemaRef.value.readonly,\n disabled: schemaRef.value.disabled,\n placeholder: currentComponentProps.placeholder ?? schemaRef.value.placeholder,\n readonlyPlaceholder:\n currentComponentProps.readonlyPlaceholder ??\n schemaRef.value.readonlyPlaceholder,\n value: field.value.value,\n onChange: handleChange,\n onBlur: handleBlur,\n \"onUpdate:value\": updateValue,\n }\n }\n )\n\n const {\n createSlotProps,\n renderAfter,\n renderBefore,\n renderContent,\n renderError,\n renderLabel,\n } = createFieldSlotRenderers({\n schemaRef,\n field,\n form,\n formContext,\n componentProps,\n slots,\n })\n\n return (): VNodeChild => {\n if (schemaRef.value.visible === false) {\n return null\n }\n\n // 整体插槽替换默认内容,但保留稳定的 Field wrapper。\n const fieldSlot = resolveSlot(slots, normalizeNameKey(schemaRef.value.name))\n\n const labelPosition =\n schemaRef.value.labelPosition || formContext.schemaConfig.labelPosition\n\n const fieldContent = fieldSlot ? (\n fieldSlot(createSlotProps())\n ) : (\n <div\n class={classnames(\"schemx-field\", `schemx-field--label-${labelPosition}`, {\n \"is-readonly\": schemaRef.value.readonly,\n \"is-disabled\": schemaRef.value.disabled,\n })}\n >\n {renderLabel()}\n\n <div class=\"schemx-field__content\">\n {renderBefore()}\n {renderContent()}\n {renderAfter()}\n {renderError()}\n </div>\n </div>\n )\n\n return (\n <div\n {...attrs}\n class={classnames(\n \"schemx-field-wrapper\",\n props.class,\n attrs.class,\n schemaRef.value.class\n )}\n style={[attrs.style, props.style, schemaRef.value.style]}\n >\n {fieldContent}\n </div>\n )\n }\n },\n})\n\nexport default Field\n","<script setup lang=\"ts\">\n import { computed, useAttrs } from \"vue\"\n\n import type { SchemxButtonSize } from \"./types\"\n\n interface Props {\n /**\n * 是否显示加载状态;加载时按钮不可点击。\n */\n loading?: boolean\n /**\n * 加载状态下替换按钮内容的文本。\n */\n loadingText?: string\n /**\n * 是否禁用按钮。\n */\n disabled?: boolean\n /**\n * 按钮尺寸。\n */\n size?: SchemxButtonSize\n }\n\n defineOptions({ name: \"SchemxButton\", inheritAttrs: false })\n\n const props = withDefaults(defineProps<Props>(), {\n loading: false,\n loadingText: undefined,\n disabled: false,\n size: \"medium\",\n })\n\n // 透传给原生 button 的非组件 Props 属性。\n const attrs = useAttrs()\n\n // loading 或 disabled 任一为真时锁定按钮交互。\n const isDisabled = computed(() => props.disabled || props.loading)\n\n // 根据按钮尺寸生成内置样式类。\n const buttonClass = computed(() => [\"schemx-button\", `schemx-button--${props.size}`])\n</script>\n\n<template>\n <button\n v-bind=\"attrs\"\n :class=\"buttonClass\"\n :aria-busy=\"props.loading || undefined\"\n :data-loading=\"props.loading || undefined\"\n :disabled=\"isDisabled\"\n >\n <span v-if=\"$slots.prefix\" class=\"schemx-button__prefix\">\n <slot name=\"prefix\" />\n </span>\n <svg\n v-if=\"props.loading\"\n class=\"schemx-button__loading\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M12 2v4\" />\n <path d=\"m16.2 7.8 2.9-2.9\" />\n <path d=\"M18 12h4\" />\n <path d=\"m16.2 16.2 2.9 2.9\" />\n <path d=\"M12 18v4\" />\n <path d=\"m4.9 19.1 2.9-2.9\" />\n <path d=\"M2 12h4\" />\n <path d=\"m4.9 4.9 2.9 2.9\" />\n </svg>\n\n <template v-if=\"props.loading && props.loadingText\">\n {{ props.loadingText }}\n </template>\n <slot v-else />\n <span v-if=\"$slots.suffix\" class=\"schemx-button__suffix\">\n <slot name=\"suffix\" />\n </span>\n </button>\n</template>\n\n<style>\n .schemx-button {\n box-sizing: content-box;\n flex: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--schemx-padding-xs);\n min-width: 72px;\n height: 24px;\n padding: var(--schemx-padding-xs) var(--schemx-padding-md);\n border: 1px solid var(--schemx-border-color);\n border-radius: var(--schemx-border-radius-sm);\n background: var(--schemx-background-color);\n color: var(--schemx-text-color);\n cursor: pointer;\n transition:\n border-color 0.15s ease,\n background-color 0.15s ease,\n color 0.15s ease,\n transform 0.1s ease;\n }\n\n .schemx-button:not(:disabled):hover {\n opacity: 0.8;\n }\n\n .schemx-button:not(:disabled):active {\n transform: scale(0.98);\n }\n\n .schemx-button--small {\n min-width: 56px;\n height: 20px;\n padding: var(--schemx-padding-base) var(--schemx-padding-sm);\n font-size: var(--schemx-font-size-sm);\n }\n\n .schemx-button--large {\n min-width: 88px;\n height: 28px;\n padding: var(--schemx-padding-sm) var(--schemx-padding-lg);\n font-size: var(--schemx-font-size-lg);\n }\n\n .schemx-button__loading {\n display: inline-block;\n border-radius: 50%;\n vertical-align: -0.15em;\n animation: schemx-button-loading 0.8s linear infinite;\n }\n\n .schemx-actions-button--submit {\n border-color: var(--schemx-primary-color);\n background: var(--schemx-primary-color);\n color: #ffffff;\n }\n\n .schemx-actions-button--submit:not(:disabled):hover {\n filter: brightness(0.92);\n color: #ffffff;\n }\n\n .schemx-button:disabled {\n cursor: not-allowed;\n opacity: var(--schemx-disabled-opacity);\n }\n\n @keyframes schemx-button-loading {\n to {\n transform: rotate(360deg);\n }\n }\n</style>\n","/**\n * Vue 层全局 Col 组件注册。\n *\n * UI 适配包通过此模块注册其 Col 实现;Form、ConfigProvider 和单个 Form 的显式\n * 配置会在渲染时覆盖该全局回退组件。\n *\n * @module utils/colProvider\n */\n\nimport { shallowRef } from \"vue\"\n\nimport type { SchemxColComponent } from \"../types/layout\"\n\n/**\n * 当前全局注册的 Col 组件。\n */\nexport const registeredColComponent = shallowRef<SchemxColComponent>()\n\n/**\n * 注册全局 Col 组件。\n *\n * 后续注册会覆盖当前全局组件;App、ConfigProvider 和 Form 的局部配置拥有更高优先级。\n *\n * @param component - UI 组件库提供的 Col 组件。\n *\n * @example\n * ```ts\n * import { Col } from \"vant\"\n * import { registerCol } from \"@schemx/vue\"\n *\n * registerCol(Col)\n * ```\n */\nexport function registerCol(component: SchemxColComponent): void {\n registeredColComponent.value = component\n}\n","/**\n * Col - Schema 布局列包装组件。\n *\n * 将 Core 的静态 layout 元数据转换为已注册 UI 组件的 `span` 与 `offset` Props;\n * 未注册组件时保持透明渲染,避免改变未启用布局的表单 DOM。\n *\n * @module components/Col\n */\n\nimport { computed, defineComponent, h, markRaw, type PropType, toRaw } from \"vue\"\nimport type { ClassValue, StyleValue, VNodeChild } from \"vue\"\n\nimport { registeredColComponent } from \"../../utils/colProvider\"\n\nimport type { SchemxColComponent, SchemxVueLayout } from \"../../types/layout\"\n\nconst Col = defineComponent({\n name: \"SchemxCol\",\n inheritAttrs: false,\n\n props: {\n layout: {\n type: Object as PropType<SchemxVueLayout>,\n required: false,\n default: undefined,\n },\n component: {\n type: [Object, Function] as PropType<SchemxColComponent>,\n required: false,\n default: undefined,\n },\n },\n\n setup(props, { attrs, slots }) {\n const resolvedComponent = computed(() => {\n const component = props.component ?? registeredColComponent.value\n\n return component ? markRaw(toRaw(component)) : undefined\n })\n\n return (): VNodeChild => {\n const component = resolvedComponent.value\n\n if (!component) {\n return slots.default?.() ?? null\n }\n\n const layout = props.layout ?? {}\n\n const span = layout.block ? 24 : (layout.span ?? 24)\n\n const offset = layout.block ? 0 : (layout.offset ?? 0)\n\n const { class: attrsClass, style: attrsStyle, ...restAttrs } = attrs\n\n return h(\n component,\n {\n ...restAttrs,\n class: [\"schemx-col\", attrsClass as ClassValue],\n style: attrsStyle as StyleValue,\n span,\n offset,\n },\n slots\n )\n }\n },\n})\n\nexport default Col\n","/**\n * Group 插槽渲染器。\n *\n * 集中处理分组 Header、Label、Content 插槽的解析和默认内容,保持\n * Group 仅负责折叠状态、子节点分发和容器布局。\n *\n * @module components/Group/slot\n */\n\nimport type { Slots, VNodeChild } from \"vue\"\n\nimport classnames from \"classnames\"\n\nimport { resolveSlot } from \"../../utils\"\n\nimport type { SchemxGroupSlotProps } from \"../../types\"\nimport type { SchemxViewGroupSchema, Values } from \"@schemx/core\"\n\n/**\n * Group 插槽渲染所需的状态与依赖。\n */\ninterface GroupSlotRendererOptions<TValues extends Values = Values> {\n /**\n * 当前分组 ViewSchema。\n */\n schema: SchemxViewGroupSchema<TValues>\n /**\n * 当前是否收起。\n */\n collapsed: boolean\n /**\n * 当前分组是否可收起。\n */\n collapsible: boolean\n /**\n * 当前分组是否禁用。\n */\n disabled: boolean\n /**\n * 当前分组是否只读。\n */\n readonly: boolean\n /**\n * 切换分组收起状态。\n */\n toggle: () => void\n /**\n * 父组件传入的所有具名插槽。\n */\n slots: Slots\n /**\n * 默认子节点渲染函数。\n */\n renderChildren: () => VNodeChild\n}\n\n/**\n * 创建 Group 各区域的插槽渲染函数。\n *\n * `Header` 完全接管 Header 内部内容;`Label` 只替换默认标题;`Content`\n * 只替换 Body 内的默认子节点布局。\n *\n * @param options - Group 插槽渲染所需的状态、插槽和子节点渲染器。\n * @returns Group Header、Body 渲染函数及 Header 是否存在的标记。\n *\n * @example\n * ```ts\n * const renderers = createGroupSlotRenderers(options)\n * renderers.renderHeaderContent()\n * ```\n */\nexport function createGroupSlotRenderers<TValues extends Values = Values>(\n options: GroupSlotRendererOptions<TValues>\n) {\n const {\n schema,\n collapsed,\n collapsible,\n disabled,\n readonly,\n toggle,\n slots,\n renderChildren,\n } = options\n\n const slotKey = String(schema.key)\n\n const headerSlot = resolveSlot(slots, `${slotKey}Header`)\n\n const labelSlot = resolveSlot(slots, `${slotKey}Label`)\n\n const contentSlot = resolveSlot(slots, `${slotKey}Content`)\n\n const slotProps: SchemxGroupSlotProps<TValues> = {\n schema,\n collapsed,\n collapsible,\n disabled,\n readonly,\n toggle,\n }\n\n const renderHeaderContent = (): VNodeChild => {\n if (headerSlot) {\n return headerSlot(slotProps)\n }\n\n const label = labelSlot ? (\n labelSlot(slotProps)\n ) : (\n <span class=\"schemx-group__title\">{schema.label}</span>\n )\n\n if (!collapsible) {\n return label\n }\n\n return (\n <>\n {label}\n <span\n class={classnames(\"schemx-group__arrow\", {\n \"schemx-group__arrow--down\": !collapsed,\n })}\n />\n </>\n )\n }\n\n const renderBodyContent = (): VNodeChild => {\n if (contentSlot) {\n return contentSlot(slotProps)\n }\n\n return renderChildren()\n }\n\n return {\n hasHeader: Boolean(schema.label || headerSlot || labelSlot),\n renderBodyContent,\n renderHeaderContent,\n }\n}\n","/**\n * Group - 分组字段组件\n *\n * 用于渲染包含 children 的 Group ViewSchema。\n * 支持可折叠的分组容器,内部递归渲染子字段和子分组。\n *\n * @module components/Group\n */\n\nimport { computed, defineComponent, getCurrentInstance, PropType, ref, watch } from \"vue\"\nimport type { ClassValue, SlotsType, StyleValue, VNodeChild } from \"vue\"\n\nimport { isViewDynamicSchema, isViewGroupSchema } from \"@schemx/core\"\nimport classnames from \"classnames\"\n\nimport { normalizeId, normalizeNameKey } from \"../../utils\"\nimport Field from \"../Field\"\n\nimport { createGroupSlotRenderers } from \"./slot\"\n\nimport type { SchemxGroupSlots } from \"../../types/field\"\nimport type { SchemxViewGroupSchema, SchemxViewSchema } from \"@schemx/core\"\n\n/**\n * Group Props。\n */\nexport interface SchemxGroupProps {\n /**\n * 当前分组的已解析 ViewSchema。\n */\n schema: SchemxViewGroupSchema\n /**\n * 父级传入的 class,会与内部和 Schema class 合并。\n */\n class?: ClassValue\n /**\n * 父级传入的 style,会在 Schema style 之前合并。\n */\n style?: StyleValue\n /**\n * 内部 SchemaList 递归渲染子节点的回调;未提供时使用 Group 自身的兼容渲染器。\n */\n renderChildren?: (schemas: readonly SchemxViewSchema[]) => VNodeChild\n}\n\nconst Group = defineComponent({\n name: \"SchemxGroup\",\n inheritAttrs: false,\n\n props: {\n schema: {\n type: Object as PropType<SchemxViewGroupSchema>,\n required: true,\n },\n class: {\n type: [String, Object, Array, Boolean] as PropType<ClassValue>,\n required: false,\n default: undefined,\n },\n style: {\n type: [String, Object, Array] as PropType<StyleValue>,\n required: false,\n default: undefined,\n },\n renderChildren: {\n type: Function as PropType<SchemxGroupProps[\"renderChildren\"]>,\n required: false,\n default: undefined,\n },\n },\n\n slots: Object as SlotsType<SchemxGroupSlots>,\n\n setup(props, { attrs, slots }) {\n const internalCollapsed = ref(Boolean(props.schema.defaultCollapsed))\n\n const collapsed = computed(() => props.schema.collapsed ?? internalCollapsed.value)\n\n const componentId = getCurrentInstance()?.uid ?? 0\n\n watch(\n () => props.schema.collapsed,\n (nextCollapsed, previousCollapsed) => {\n if (nextCollapsed !== undefined) {\n internalCollapsed.value = nextCollapsed\n } else if (previousCollapsed !== undefined) {\n internalCollapsed.value = previousCollapsed\n }\n }\n )\n\n // 切换非受控 Group 的折叠状态,并通知受控回调。\n const toggle = () => {\n if (!props.schema.collapsible || props.schema.disabled) {\n return\n }\n\n const nextCollapsed = !collapsed.value\n\n if (props.schema.collapsed === undefined) {\n internalCollapsed.value = nextCollapsed\n }\n\n props.schema.onCollapsedChange?.(nextCollapsed)\n }\n\n return (): VNodeChild => {\n const schema = props.schema\n\n if (schema.visible === false) {\n return null\n }\n\n const collapsible = Boolean(schema.collapsible)\n\n const isCollapsed = collapsed.value\n\n const destroyOnCollapse = schema.destroyOnCollapse ?? true\n\n const uniqueId = schema.debug?.runtimeNodeId ?? `local-${componentId}`\n\n const idBase = `schemx-group-${uniqueId}-${normalizeId(schema.key)}`\n\n const headerId = `${idBase}-header`\n\n const bodyId = `${idBase}-body`\n\n /**\n * 递归渲染 Group 的子字段、子分组和 Dynamic。\n *\n * @param child - 当前 Group 的子 ViewSchema。\n * @returns 对应子节点的 VNode。\n */\n const renderChild = (child: SchemxViewSchema): VNodeChild => {\n if (isViewDynamicSchema(child)) {\n if (child.visible === false) {\n return null\n }\n\n return child.items.map((item) =>\n item.children.map((itemChild) => renderChild(itemChild))\n )\n }\n\n if (isViewGroupSchema(child)) {\n return (\n <Group\n key={child.key}\n schema={child as SchemxViewGroupSchema}\n class={props.class}\n style={props.style}\n v-slots={slots}\n />\n )\n }\n\n return (\n <Field\n key={`${child.key}:${normalizeNameKey(child.name)}`}\n schema={child}\n v-slots={slots}\n />\n )\n }\n\n const { hasHeader, renderBodyContent, renderHeaderContent } =\n createGroupSlotRenderers({\n schema,\n collapsed: isCollapsed,\n collapsible,\n disabled: Boolean(schema.disabled),\n readonly: Boolean(schema.readonly),\n toggle,\n slots,\n renderChildren: () =>\n props.renderChildren\n ? props.renderChildren(schema.children)\n : schema.children.map(renderChild),\n })\n\n const body = (\n <div\n id={bodyId}\n role=\"group\"\n aria-labelledby={schema.label ? headerId : undefined}\n aria-hidden={isCollapsed || undefined}\n class=\"schemx-group__body\"\n style={!destroyOnCollapse && isCollapsed ? { display: \"none\" } : undefined}\n >\n {renderBodyContent()}\n </div>\n )\n\n return (\n <div\n {...attrs}\n class={classnames(\n \"schemx-group-wrapper\",\n props.class,\n attrs.class,\n schema.class\n )}\n data-key={schema.key}\n aria-disabled={schema.disabled || undefined}\n style={[attrs.style, props.style, schema.style]}\n >\n <div\n class={classnames(\"schemx-group\", {\n \"schemx-group--collapsed\": isCollapsed,\n \"is-readonly\": schema.readonly,\n \"is-disabled\": schema.disabled,\n })}\n >\n {hasHeader && (\n <div\n id={headerId}\n role={collapsible ? \"button\" : undefined}\n tabindex={collapsible ? (schema.disabled ? -1 : 0) : undefined}\n aria-expanded={collapsible ? !isCollapsed : undefined}\n aria-controls={collapsible ? bodyId : undefined}\n aria-disabled={collapsible ? schema.disabled || undefined : undefined}\n class={classnames(\"schemx-group__header\", {\n \"schemx-group__header--clickable\": collapsible && !schema.disabled,\n })}\n onClick={toggle}\n onKeydown={(e: KeyboardEvent) => {\n if (!schema.disabled && (e.key === \"Enter\" || e.key === \" \")) {\n e.preventDefault()\n toggle()\n }\n }}\n >\n {renderHeaderContent()}\n </div>\n )}\n {destroyOnCollapse ? !isCollapsed && body : body}\n </div>\n </div>\n )\n }\n },\n})\n\nexport default Group\n","/**\n * Dynamic - 动态数组字段组件。\n *\n * 负责按 ViewSchema 的数组行边界展开 Dynamic,并将每行的 Group 与 Field\n * 委托给对应组件;字段插槽由父级 Form 透传到当前 Dynamic 子树。\n *\n * @module components/Dynamic\n */\n\n/* eslint-disable vue/one-component-per-file */\nimport { defineComponent, Fragment, PropType, VNodeChild } from \"vue\"\n\nimport { isViewGroupSchema } from \"@schemx/core\"\n\nimport { getSectionPosition, normalizeNameKey } from \"../../utils\"\nimport Field from \"../Field\"\nimport Group from \"../Group\"\n\nimport type {\n SchemxViewDynamicSchema,\n SchemxViewFieldSchema,\n SchemxViewSchema,\n} from \"@schemx/core\"\n\n/**\n * Dynamic 组件属性。\n */\nexport interface SchemxDynamicProps {\n /**\n * 当前 Dynamic 数组的 ViewSchema。\n */\n schema: SchemxViewDynamicSchema\n /**\n * 当前 Form 根级 ViewSchema,用于计算字段区段样式。\n */\n viewSchemas: readonly SchemxViewSchema[]\n /**\n * 内部 SchemaList 递归渲染数组行子节点的回调;未提供时使用 Dynamic 自身的兼容渲染器。\n */\n renderChildren?: (schemas: readonly SchemxViewSchema[]) => VNodeChild\n}\n\nconst Dynamic = defineComponent({\n name: \"SchemxDynamic\",\n inheritAttrs: false,\n\n props: {\n schema: {\n type: Object as PropType<SchemxViewDynamicSchema>,\n required: true,\n },\n viewSchemas: {\n type: Array as PropType<readonly SchemxViewSchema[]>,\n required: true,\n },\n renderChildren: {\n type: Function as PropType<SchemxDynamicProps[\"renderChildren\"]>,\n required: false,\n default: undefined,\n },\n },\n\n /**\n * 初始化 Dynamic 的行模板渲染器。\n *\n * @param props - 当前 Dynamic ViewSchema 与 Form 根级 ViewSchema。\n * @param slots - 父级透传的字段插槽。\n */\n setup(props, { slots }) {\n /**\n * 根据字段路径生成渲染 key,路径变化时重新绑定字段控制器。\n *\n * @param schema - 当前字段 ViewSchema。\n * @returns 包含 Schema key 和字段路径的渲染 key。\n */\n const getFieldRenderKey = (schema: SchemxViewFieldSchema): string =>\n `${schema.key}:${normalizeNameKey(schema.name)}`\n\n /**\n * 根据根级 ViewSchema 计算 Dynamic 字段的首尾样式类。\n *\n * @param schema - 当前 Dynamic 行中的 ViewSchema。\n * @returns 首尾字段对应的 CSS class 映射。\n */\n const getFieldClass = (schema: SchemxViewSchema) => {\n const { isFirst, isLast } = getSectionPosition(\n props.viewSchemas as SchemxViewSchema[],\n schema.key\n )\n\n return {\n \"schemx-field-wrapper--first\": isFirst,\n \"schemx-field-wrapper--last\": isLast,\n }\n }\n\n /**\n * 渲染单个 Dynamic 行模板节点。\n *\n * @param schema - 当前行模板中的 ViewSchema。\n * @returns Group 或 Field 的 VNode。\n */\n const renderItemSchema = (schema: SchemxViewSchema): VNodeChild => {\n if (isViewGroupSchema(schema)) {\n return <Group key={schema.key} schema={schema} v-slots={slots} />\n }\n\n const field = schema as SchemxViewFieldSchema\n\n return (\n <Field\n key={getFieldRenderKey(field)}\n schema={field}\n class={getFieldClass(field)}\n v-slots={slots}\n />\n )\n }\n\n return (): VNodeChild => {\n if (props.schema.visible === false) {\n return null\n }\n\n return props.schema.items.map((item) => {\n const children = props.renderChildren\n ? props.renderChildren(item.children)\n : item.children.map(renderItemSchema)\n\n return <Fragment key={item.key}>{children}</Fragment>\n })\n }\n },\n})\n\nexport default Dynamic\n","/**\n * SchemaList - 统一递归渲染 ViewSchema 列表。\n *\n * 负责在 Form、Group 和 Dynamic 的每个同级 Schema 列表上建立 Row,并将每个节点\n * 交给 Col 包装;未解析到 Col 组件时保持原有透明渲染。\n *\n * @module components/SchemaList\n */\n\nimport { defineComponent, h, type PropType } from \"vue\"\nimport type { ClassValue, VNodeChild } from \"vue\"\n\nimport {\n isSchemxViewFieldSchema,\n isViewDynamicSchema,\n isViewGroupSchema,\n} from \"@schemx/core\"\n\nimport { normalizeNameKey } from \"../../utils\"\nimport Col from \"../Col\"\nimport Dynamic from \"../Dynamic\"\nimport Field from \"../Field\"\nimport Group from \"../Group\"\n\nimport type { SchemxColComponent } from \"../../types/layout\"\nimport type { SchemxViewFieldSchema, SchemxViewSchema, Values } from \"@schemx/core\"\n\n/**\n * SchemaList 的公开属性。\n */\nexport interface SchemxSchemaListProps<TValues extends Values = Values> {\n /**\n * 当前同级 ViewSchema 列表。\n */\n schemas: readonly SchemxViewSchema<TValues>[]\n /**\n * 根级 ViewSchema 列表,供 Field 首尾样式计算。\n */\n viewSchemas: readonly SchemxViewSchema<TValues>[]\n /**\n * 当前 Form 解析出的 Col 实现;为空时不创建布局包装。\n */\n colComponent?: SchemxColComponent\n /**\n * 根级 Field wrapper 的 class 解析器。\n */\n fieldClassResolver?: (schema: SchemxViewSchema<TValues>) => ClassValue\n}\n\nconst SchemaList = defineComponent({\n name: \"SchemxSchemaList\",\n inheritAttrs: false,\n\n props: {\n schemas: {\n type: Array as PropType<readonly SchemxViewSchema[]>,\n required: true,\n },\n viewSchemas: {\n type: Array as PropType<readonly SchemxViewSchema[]>,\n required: true,\n },\n colComponent: {\n type: [Object, Function] as PropType<SchemxColComponent>,\n required: false,\n default: undefined,\n },\n fieldClassResolver: {\n type: Function as PropType<(schema: SchemxViewSchema) => ClassValue>,\n required: false,\n default: undefined,\n },\n },\n\n setup(props, { slots }) {\n /**\n * 根据字段路径生成稳定的 Field 渲染 key。\n *\n * @param schema - 当前字段 ViewSchema。\n * @returns 包含 Schema key 和字段路径的渲染 key。\n */\n const getFieldRenderKey = (schema: SchemxViewFieldSchema): string =>\n `${schema.key}:${normalizeNameKey(schema.name)}`\n\n /**\n * 根据节点类型生成稳定的 Schema 渲染 key。\n *\n * @param schema - 当前节点 ViewSchema。\n * @returns 用于 Col 或子组件的稳定渲染 key。\n */\n const getSchemaRenderKey = (schema: SchemxViewSchema): string => {\n if (isSchemxViewFieldSchema(schema)) {\n return getFieldRenderKey(schema)\n }\n\n return schema.key\n }\n\n /**\n * 递归创建子级 SchemaList,并复用当前 Form 的根级配置。\n *\n * @param schemas - 当前子级 ViewSchema 列表。\n * @returns 子级 SchemaList 的 VNode。\n */\n const renderChildren = (schemas: readonly SchemxViewSchema[]): VNodeChild => {\n return h(\n SchemaList,\n {\n schemas,\n viewSchemas: props.viewSchemas,\n colComponent: props.colComponent,\n },\n slots\n )\n }\n\n /**\n * 将单个 ViewSchema 渲染为 Field、Group、Dynamic 或 Col。\n *\n * @param schema - 当前待渲染的 ViewSchema。\n * @returns 当前 Schema 对应的 VNode。\n */\n const renderSchema = (schema: SchemxViewSchema): VNodeChild => {\n if (schema.visible === false) {\n return null\n }\n\n let content: VNodeChild\n\n if (isViewGroupSchema(schema)) {\n content = (\n <Group\n key={schema.key}\n schema={schema}\n renderChildren={renderChildren}\n v-slots={slots}\n />\n )\n } else if (isViewDynamicSchema(schema)) {\n content = (\n <Dynamic\n key={schema.key}\n schema={schema}\n viewSchemas={props.viewSchemas}\n renderChildren={renderChildren}\n v-slots={slots}\n />\n )\n } else {\n content = (\n <Field\n key={getFieldRenderKey(schema)}\n schema={schema}\n class={props.fieldClassResolver?.(schema)}\n v-slots={slots}\n />\n )\n }\n\n if (!props.colComponent) {\n return content\n }\n\n return (\n <Col\n key={getSchemaRenderKey(schema)}\n component={props.colComponent}\n layout={schema.layout}\n >\n {content}\n </Col>\n )\n }\n\n return (): VNodeChild => {\n const children = props.schemas.map(renderSchema)\n\n if (!props.colComponent) {\n return children\n }\n\n return <div class=\"schemx-row\">{children}</div>\n }\n },\n})\n\nexport default SchemaList\n","<!--\n schemx - 主组件\n\n 基于 Schema 配置的表单组件,使用 useForm Hook 管理状态。\n\n @module schemx\n-->\n\n<script lang=\"ts\" setup generic=\"TValues extends Values = Values\">\n import { computed, nextTick, toRaw, useSlots, watch } from \"vue\"\n\n import {\n defaultSchemxConfigKeys,\n getGlobalSchemxConfig,\n isSchemxSchemas,\n mergeSchemxConfig,\n resolveSchemxConfig,\n } from \"@schemx/core\"\n import { pick } from \"es-toolkit\"\n\n import Button from \"./components/Button\"\n import SchemaList from \"./components/SchemaList\"\n import { getSchemxAppConfig } from \"./config\"\n import {\n defaultVueSchemaConfig,\n defaultVueSchemaConfigKeys,\n } from \"./config/defaultVueSchemaConfig\"\n import { provideFormContext, useConfigProviderContextRef } from \"./context\"\n import { useForm, useFormSelector, useViewSchemas } from \"./hooks\"\n import { registeredColComponent } from \"./utils/colProvider\"\n import { getSectionPosition } from \"./utils/helpers\"\n\n import type { SchemxFormActionConfig, SchemxFormProps } from \"./types/index\"\n import type {\n SchemxConfig,\n SchemxInstance,\n SchemxSchemaConfig,\n SchemxViewSchema,\n Values,\n } from \"@schemx/core\"\n\n import \"./styles/index.css\"\n\n defineOptions({ name: \"SchemxForm\" })\n\n /**\n * 规范化表单组件的公开输入,并为未提供的可选项补充默认值。\n *\n * 具体字段语义由 `SchemxFormProps<TValues>` 定义;其中 `modelValue`、\n * `schemas` 和 `form` 共同决定表单数据与实例来源。\n */\n const props = withDefaults(defineProps<SchemxFormProps<TValues>>(), {\n modelValue: () => ({}) as TValues,\n initialValues: () => ({}) as TValues,\n form: undefined,\n schemas: () => [],\n class: \"\",\n style: () => ({}),\n onFinish: undefined,\n onFinishFailed: undefined,\n onReset: undefined,\n onLoadingChange: undefined,\n onValuesChange: undefined,\n onFieldsChange: undefined,\n loading: undefined,\n submitter: true,\n resetter: true,\n rendererProps: undefined,\n rendererRegistry: undefined,\n presetRuleRegistry: undefined,\n fieldRules: undefined,\n schedulerOptions: undefined,\n validationConcurrency: undefined,\n visible: undefined,\n validationTrigger: undefined,\n readonly: undefined,\n disabled: undefined,\n colon: undefined,\n showRequiredMark: undefined,\n colComponent: undefined,\n })\n\n /**\n * 定义表单 v-model 的同步事件。\n *\n * 仅在内部表单值变化且不是外部 `modelValue` 同步窗口时发出更新。\n */\n const emit = defineEmits<{\n \"update:modelValue\": [value: TValues]\n }>()\n\n /**\n * 读取组件保留操作区插槽,并据此决定是否渲染默认操作区。\n */\n const slots = useSlots()\n\n /**\n * Core 兼容键与 Vue 展示键的合并集合。\n */\n const schemaConfigKeys = [\n ...defaultSchemxConfigKeys,\n ...defaultVueSchemaConfigKeys,\n ] as (keyof SchemxSchemaConfig)[]\n\n /**\n * 提取需要同步到 Core 的表单级 schema 配置。\n */\n const pickSchemaConfig = (): Partial<SchemxSchemaConfig> => {\n // Vue 保留 `required` 对当前 TValues 的泛型约束;Core 的表单级配置使用\n // unknown 表示任意字段值。运行时该回调只会接收当前 Form 的字段值,因此在\n // Vue 到 Core 的适配边界收窄为 Core 配置类型。\n const schemaConfig = pick(props, schemaConfigKeys) as Partial<SchemxSchemaConfig>\n\n return Object.fromEntries(\n Object.entries(schemaConfig).filter(([, value]) => value !== undefined)\n ) as Partial<SchemxSchemaConfig>\n }\n\n // 是否由调用方传入并负责生命周期的外部 Form。\n const isExternalForm = props.form !== undefined\n\n // 当前组件显式传入的、待同步到 Core 的 schema 配置。\n const schemaConfigProps = computed(pickSchemaConfig)\n\n // 当前 Vue App 的安装级配置快照。\n const appConfig = getSchemxAppConfig()\n\n // 当前组件树中最近 Provider 的响应式配置。\n const providerConfig = useConfigProviderContextRef()\n\n /**\n * Core 全局配置只在内部 Form 创建时取快照,后续变更不影响已有实例。\n */\n const coreConfig = getGlobalSchemxConfig()\n\n /**\n * 保持 SchemxForm 既有默认行为、且允许 Provider/App 覆盖的最低优先级配置。\n */\n const formFallbackConfig: SchemxConfig<TValues> = {\n schemaConfig: {\n visible: true,\n validationTrigger: [\"blur\", \"change\"],\n },\n }\n\n /**\n * 合并配置来源;外部 Form 只接收组件显式配置与组件默认行为。\n */\n const mergedConfig = computed(() =>\n isExternalForm\n ? mergeSchemxConfig({ schemaConfig: schemaConfigProps.value }, formFallbackConfig)\n : mergeSchemxConfig(\n { schemaConfig: schemaConfigProps.value },\n (providerConfig?.value as SchemxConfig<TValues> | undefined) ?? {},\n appConfig as SchemxConfig<TValues>,\n formFallbackConfig,\n coreConfig as SchemxConfig<TValues>\n )\n )\n\n /**\n * 为后代 Field 补充 Vue 展示默认值。\n */\n const contextSchemaConfig = computed<Partial<SchemxSchemaConfig>>(() => ({\n ...defaultVueSchemaConfig,\n ...mergedConfig.value.schemaConfig,\n }))\n\n /**\n * 计算内部 Form 当前完整生效的配置,用于撤销局部覆盖和响应 Provider 变化。\n */\n const resolvedSchemaConfig = computed<SchemxSchemaConfig>(\n () => resolveSchemxConfig(mergedConfig.value).schemaConfig\n )\n\n /**\n * 判断配置对象是否显式包含指定 key。\n *\n * @param config - 待检查的配置对象。\n * @param key - 要检查的配置 key。\n * @returns 配置对象自身包含该 key 时返回 `true`。\n */\n const hasSchemaConfigKey = (\n config: Partial<SchemxSchemaConfig>,\n key: keyof SchemxSchemaConfig\n ): boolean => Object.prototype.hasOwnProperty.call(config, key)\n\n /**\n * 当前 Form 使用的 Col,按 Form、Provider、App、全局注册顺序解析。\n */\n const resolvedColComponent = computed(\n () =>\n props.colComponent ??\n providerConfig?.value.colComponent ??\n appConfig.colComponent ??\n registeredColComponent.value\n )\n\n /**\n * 获取或创建表单实例\n *\n * 优先使用外部传入的 form,否则内部通过 useForm 创建。\n * 必须在 setup 同步阶段调用,确保 provide 正确注入。\n */\n const providedForm = props.form\n ? props.form\n : useForm<TValues>({\n schemas: props.schemas,\n schemaConfig: resolvedSchemaConfig.value,\n initialValues:\n Object.keys(props.modelValue).length > 0\n ? props.modelValue\n : props.initialValues,\n\n rendererProps: props.rendererProps,\n rendererRegistry: props.rendererRegistry,\n defaultRendererType: props.defaultRendererType,\n presetRuleRegistry: props.presetRuleRegistry,\n fieldRules: props.fieldRules,\n validatorAdapters: props.validatorAdapters,\n schedulerOptions: props.schedulerOptions,\n validationConcurrency: props.validationConcurrency,\n\n /**\n * 转发提交成功回调。\n *\n * @param values - 提交成功时的完整表单快照。\n */\n onFinish: (values) => props.onFinish?.(values),\n /**\n * 转发提交失败回调。\n *\n * @param errors - 提交失败时的字段错误集合。\n */\n onFinishFailed: (errors) => props.onFinishFailed?.(errors),\n /**\n * 转发完整表单重置回调。\n */\n onReset: () => {\n props.onReset?.()\n },\n /**\n * 转发 Core 发出的提交 loading 状态。\n *\n * 外部传入 Form 时不会注入该回调,保持实例的创建期边界。\n *\n * @param loading - 当前是否处于提交流程中。\n */\n onLoadingChange: (loading) => {\n props.onLoadingChange?.(loading)\n },\n /**\n * 转发值变化回调。\n *\n * @param changedValues - 本次变更涉及的字段值。\n * @param latestSnapshot - 变更后的完整表单快照。\n */\n onValuesChange: (changedValues, latestSnapshot) => {\n props.onValuesChange?.(changedValues, latestSnapshot)\n },\n /**\n * 转发字段变化回调。\n *\n * @param changedPaths - 本次发生变化的字段路径。\n * @param allPaths - 当前已变更字段路径集合。\n */\n onFieldsChange: (changedPaths, allPaths) => {\n props.onFieldsChange?.(changedPaths, allPaths)\n },\n })\n\n /**\n * 注册表单上下文。\n *\n * 无论实例来自 props.form 还是 useForm,都必须同步注册,\n * 从而保证 Field、useField 等后代逻辑能够获取同一个实例。\n */\n const formInstance = provideFormContext({\n form: providedForm,\n get schemaConfig() {\n return contextSchemaConfig.value\n },\n })\n\n /**\n * 组件未受控时直接跟随 Core 提交状态;受控值仅覆盖操作区展示。\n */\n const effectiveLoading = computed(() => props.loading ?? formInstance.isLoading())\n\n /**\n * Form 根节点的 class 来源:组件内部标识与调用方自定义 class。\n */\n const formRootClass = computed(() => [\"schemx\", props.class])\n\n /**\n * Form 根节点的 style 来源;保留 Vue StyleValue 的对象/数组合并能力。\n */\n const formRootStyle = computed(() => props.style)\n\n /**\n * 归一化启用状态下的操作配置。\n *\n * @param action - 布尔开关或操作按钮配置。\n * @returns 可直接用于渲染按钮的配置对象。\n */\n const normalizeActionConfig = (\n action: SchemxFormProps<TValues>[\"submitter\"]\n ): SchemxFormActionConfig => (action === true ? {} : action || {})\n\n /**\n * 提交操作的归一化配置。\n */\n const submitterConfig = computed(() => normalizeActionConfig(props.submitter))\n\n /**\n * 重置操作的归一化配置。\n */\n const resetterConfig = computed(() => normalizeActionConfig(props.resetter))\n\n /**\n * 操作区必须保护内部事件和 button type,不接受运行时透传的同名属性。\n *\n * @param config - 当前操作按钮的配置。\n * @returns 过滤内部事件和 type 后的按钮属性。\n */\n const getButtonProps = (config: SchemxFormActionConfig) => {\n const buttonProps = Object.fromEntries(\n Object.entries(config.buttonProps ?? {}).filter(\n ([name]) => name !== \"type\" && name !== \"onClick\"\n )\n )\n\n return buttonProps\n }\n\n /**\n * 提交按钮可安全透传的原生属性。\n */\n const submitterButtonProps = computed(() => getButtonProps(submitterConfig.value))\n\n /**\n * 重置按钮可安全透传的原生属性。\n */\n const resetterButtonProps = computed(() => getButtonProps(resetterConfig.value))\n\n /**\n * 仅配置或提供对应插槽时展示提交操作。\n */\n const isSubmitterVisible = computed(\n () => props.submitter !== false && (props.submitter !== undefined || slots.submitter)\n )\n\n /**\n * 仅配置或提供对应插槽时展示重置操作。\n */\n const isResetterVisible = computed(\n () => props.resetter !== false && (props.resetter !== undefined || slots.resetter)\n )\n\n /**\n * 操作区的整体显示状态。\n */\n const isActionsVisible = computed(\n () => isSubmitterVisible.value || isResetterVisible.value\n )\n\n /**\n * 操作区保留插槽不能下传给字段,避免与同名字段插槽冲突。\n */\n const fieldSlots = computed(() =>\n Object.fromEntries(\n Object.entries(slots).filter(\n ([slotName]) => slotName !== \"submitter\" && slotName !== \"resetter\"\n )\n )\n )\n\n /**\n * 提交按钮在 loading 或显式 disabled 时不可点击。\n */\n const isSubmitterDisabled = computed(\n () => effectiveLoading.value || Boolean(submitterButtonProps.value.disabled)\n )\n\n /**\n * 重置按钮在 loading 或显式 disabled 时不可点击。\n */\n const isResetterDisabled = computed(\n () => effectiveLoading.value || Boolean(resetterButtonProps.value.disabled)\n )\n\n let syncingFromModel = false\n\n /**\n * 记录 Core 发出的、等待标准 v-model 回传的一次性快照身份。\n */\n const internalModelEchoes = new Set<TValues>()\n\n /**\n * 发出内部模型更新,并记录等待父级原样回传的快照。\n *\n * @param values - 要发出的最新表单值快照。\n */\n const emitModelValue = (values: TValues): void => {\n const rawValues = toRaw(values)\n\n internalModelEchoes.add(rawValues)\n emit(\"update:modelValue\", values)\n\n void nextTick(() => {\n internalModelEchoes.delete(rawValues)\n })\n }\n\n /**\n * 将外部 modelValue 同步到 Core,并标记窗口以阻止 v-model 回写。\n *\n * @param values - 外部传入的最新表单值。\n */\n watch(\n () => props.modelValue,\n (values) => {\n if (internalModelEchoes.delete(toRaw(values))) {\n return\n }\n\n syncingFromModel = true\n\n try {\n formInstance.setFieldsValue(values)\n } finally {\n syncingFromModel = false\n }\n },\n { deep: true, immediate: isExternalForm }\n )\n\n /**\n * 响应提交按钮点击,并返回 Core Promise 以让 Vue 处理异常。\n */\n const handleSubmit: SchemxInstance<TValues>[\"submit\"] = () => formInstance.submit()\n\n /**\n * 响应重置按钮点击。\n */\n const handleReset = (): void => {\n formInstance.reset()\n }\n\n /**\n * 通过共享 selector bridge 订阅完整快照,避免组件树重复注册 Core 监听。\n *\n * @param values - 当前表单的完整快照。\n */\n const formValues = useFormSelector(formInstance, (values) => values)\n\n /**\n * 将 Core 值同步回 v-model;外部 modelValue 写入期间跳过回写,避免循环。\n *\n * @param latestSnapshot - Core 发布的最新完整表单快照。\n */\n watch(\n formValues,\n (latestSnapshot) => {\n if (syncingFromModel) {\n return\n }\n\n emitModelValue(latestSnapshot)\n },\n { flush: \"sync\" }\n )\n\n /**\n * 将外部传入的原始 Schema 同步更新到 Core。\n *\n * @param schemas - 最新的 props.schemas 配置。\n */\n watch(\n () => props.schemas,\n (schemas) => {\n if (!isSchemxSchemas(schemas)) {\n formInstance.setSchemas(schemas)\n }\n },\n { immediate: isExternalForm }\n )\n\n // 当前 Form 的响应式 ViewSchema 列表。\n const viewSchemas = useViewSchemas(formInstance)\n\n /**\n * 根据 ViewSchema 在当前列表中的位置生成首尾样式类。\n *\n * @param schema - 当前需要计算样式的 ViewSchema。\n * @returns 用于包裹元素的首尾位置 class 映射。\n */\n const getFieldClass = (schema: SchemxViewSchema) => {\n const { isFirst, isLast } = getSectionPosition(\n viewSchemas.value as SchemxViewSchema[],\n schema.key\n )\n\n return {\n \"schemx-field-wrapper--first\": isFirst,\n \"schemx-field-wrapper--last\": isLast,\n }\n }\n\n /**\n * 将内部 Form 的完整配置同步到 Context 和 Core。\n *\n * @param nextSchemaConfig - 合并后的完整 schema 配置。\n */\n const syncInternalSchemaConfig = (nextSchemaConfig: SchemxSchemaConfig): void => {\n formInstance.updateSchemaConfig(nextSchemaConfig)\n }\n\n /**\n * 将外部 Form 的组件级配置增量同步到 Context 和 Core。\n *\n * @param nextSchemaConfig - 当前组件显式配置。\n * @param previousSchemaConfig - 上一次组件显式配置,用于清理已移除的 key。\n */\n const syncExternalSchemaConfig = (\n nextSchemaConfig: Partial<SchemxSchemaConfig>,\n previousSchemaConfig: Partial<SchemxSchemaConfig> | undefined\n ): void => {\n const patch: Partial<SchemxSchemaConfig> = { ...nextSchemaConfig }\n\n if (previousSchemaConfig !== undefined) {\n for (const key of schemaConfigKeys) {\n if (\n hasSchemaConfigKey(previousSchemaConfig, key) &&\n !hasSchemaConfigKey(nextSchemaConfig, key)\n ) {\n patch[key] = undefined\n }\n }\n }\n\n if (Object.keys(patch).length > 0) {\n formInstance.updateSchemaConfig(patch)\n }\n }\n\n if (isExternalForm) {\n watch(schemaConfigProps, syncExternalSchemaConfig, {\n deep: true,\n immediate: true,\n })\n } else {\n watch(resolvedSchemaConfig, syncInternalSchemaConfig, { deep: true })\n }\n\n /**\n * 暴露当前表单 Instance 的完整控制 API,供模板 ref 调用。\n */\n const exposed: SchemxInstance<TValues> = {\n ...formInstance,\n submit: handleSubmit,\n reset: handleReset,\n }\n\n defineExpose(exposed)\n</script>\n\n<template>\n <div :class=\"formRootClass\" :style=\"formRootStyle\">\n <SchemaList\n :schemas=\"viewSchemas as SchemxViewSchema[]\"\n :view-schemas=\"viewSchemas as SchemxViewSchema[]\"\n :col-component=\"resolvedColComponent\"\n :field-class-resolver=\"getFieldClass\"\n >\n <template v-for=\"(_, slotName) in fieldSlots\" #[slotName]=\"slotProps\">\n <slot :name=\"slotName\" v-bind=\"slotProps ?? {}\" />\n </template>\n </SchemaList>\n\n <div v-if=\"isActionsVisible\" class=\"schemx-actions\">\n <slot\n v-if=\"isResetterVisible && slots.resetter\"\n name=\"resetter\"\n :form=\"formInstance\"\n :loading=\"effectiveLoading\"\n :disabled=\"isResetterDisabled\"\n :reset=\"handleReset\"\n />\n <Button\n v-else-if=\"isResetterVisible\"\n v-bind=\"resetterButtonProps\"\n class=\"schemx-actions-button schemx-actions-button--reset\"\n type=\"button\"\n :disabled=\"isResetterDisabled\"\n @click=\"handleReset\"\n >\n {{ resetterConfig.text ?? \"重置\" }}\n </Button>\n <slot\n v-if=\"isSubmitterVisible && slots.submitter\"\n name=\"submitter\"\n :form=\"formInstance\"\n :loading=\"effectiveLoading\"\n :disabled=\"isSubmitterDisabled\"\n :submit=\"handleSubmit\"\n />\n <Button\n v-else-if=\"isSubmitterVisible\"\n v-bind=\"submitterButtonProps\"\n class=\"schemx-actions-button schemx-actions-button--submit\"\n type=\"button\"\n :loading=\"effectiveLoading\"\n :disabled=\"isSubmitterDisabled\"\n @click=\"handleSubmit\"\n >\n {{ submitterConfig.text ?? \"提交\" }}\n </Button>\n </div>\n </div>\n</template>\n","/**\n * schemx 组件导出\n *\n * 为 SchemxForm 组件挂载静态方法(install、Field、registerRequest 等),\n * 并作为默认导出。\n *\n * @module formExport\n */\n\nimport type { App } from \"vue\"\n\nimport Field from \"./components/Field\"\nimport { provideSchemxAppConfig } from \"./config\"\nimport SchemxForm from \"./formRuntime.js\"\n\nimport type { SchemxVueConfig } from \"./types/layout\"\n\n/**\n * SchemxForm 插件安装选项\n *\n * 在 `app.use(SchemxForm, options)` 时传入,用于配置当前 Vue App 的默认行为。\n * 安装配置不会写入 Core 的模块级全局配置,因此多个 Vue App 可以彼此隔离。\n *\n * @example\n * ```ts\n * import SchemxForm from '@schemx/vue'\n *\n * app.use(SchemxForm, {\n * schemaConfig: { readonly: true },\n * })\n * ```\n */\nexport interface SchemxInstallOptions extends SchemxVueConfig {}\n\n/**\n * 为组件挂载静态属性并保留原始类型\n *\n * @param comp - 原始组件\n * @param extra - 要挂载的静态属性\n * @typeParam TComponent - 原始组件类型。\n * @typeParam TExtras - 待挂载的静态属性类型。\n *\n * @example\n * ```ts\n * const Plugin = withInstall(Component, { install(app) { app.component(\"Demo\", Component) } })\n * ```\n */\nexport function withInstall<\n TComponent extends object,\n TExtras extends Record<string, unknown>,\n>(comp: TComponent, extra: TExtras) {\n return Object.assign(comp, extra) as TComponent & TExtras\n}\n\n/**\n * 挂载了 Vue 插件安装方法和 `Field` 子组件的 Form 组件类型。\n */\nexport type SchemxFormPlugin = typeof SchemxForm & {\n install: (app: App, options?: SchemxInstallOptions) => void\n Field: typeof Field\n}\n\nconst SchemxFormExport = withInstall(SchemxForm, {\n /**\n * Vue 插件安装方法\n */\n install(app: App, options: SchemxInstallOptions = {}) {\n provideSchemxAppConfig(app, options)\n app.component(\"SchemxForm\", SchemxForm)\n },\n /**\n * Field 子组件引用\n */\n Field,\n}) as unknown as SchemxFormPlugin\n\nexport default SchemxFormExport\n","/**\n * WithRemoteOptions - 选项高阶组件\n *\n * 包装任意渲染器组件,自动注入 useDictionary 的选项加载能力。\n * 被包装组件会额外收到 options、loading 两个 props,\n * 无需自行调用 useDictionary。\n *\n * @module hocs/withRemoteOptions\n */\n\nimport { Component, computed, defineComponent, h, PropType, SetupContext } from \"vue\"\n\nimport type { SchemxDictionary } from \"@/types/dictionary\"\n\nimport { useFieldContext } from \"../context/fieldContext\"\nimport { useDictionary } from \"../hooks/useDictionary\"\n\n/**\n * WithRemoteOptions 注入给被包装组件的额外 Props\n */\nexport interface RemoteOptionsInjectedProps {\n /**\n * 加载的选项列表\n */\n options: unknown[]\n /**\n * 加载状态\n */\n loading: boolean\n}\n\ntype SchemxDictionaryInput = SchemxDictionary | SchemxDictionary[\"api\"]\n\n/**\n * 将 api 简写规范化为完整的字典配置。\n *\n * @param dictionary - 完整字典配置或 api 函数简写。\n * @returns 规范化后的字典配置;未提供时返回 `undefined`。\n */\nfunction normalizeDictionary(\n dictionary: SchemxDictionaryInput | undefined\n): SchemxDictionary | undefined {\n if (typeof dictionary === \"function\") {\n return { api: dictionary }\n }\n\n return dictionary\n}\n\n/**\n * 选项高阶组件\n *\n * 包装一个渲染器组件,当 dict prop 存在时,\n * 调用 useDictionary 加载选项,并将结果作为 options prop 注入。\n *\n * 当组件自身已传入非空 options 且无 dict 时,优先使用静态 options。\n *\n * @param WrappedComponent - 被包装的渲染器组件\n * @returns 增强后的组件,自动具备选项加载能力\n *\n * @example\n * ```ts\n * import { WithRemoteOptions } from '@schemx/vue'\n * import MySelect from './MySelect.vue'\n *\n * const RemoteSelect = WithRemoteOptions(MySelect)\n *\n * // 在 schema 中使用\n * const schema = {\n * name: 'city',\n * label: '城市',\n * componentType: 'select',\n * componentProps: {\n * dict: {\n * api: async (values) => fetchCities(values.province),\n * dependsOn: ['province'],\n * shouldFetch: (values) => !!values.province,\n * resetOnDepsChange: true,\n * immediate: false,\n * },\n * },\n * }\n * ```\n */\nexport function WithRemoteOptions(WrappedComponent: Component): Component {\n return defineComponent({\n name: `WithRemoteOptions(${WrappedComponent.name || \"Anonymous\"})`,\n inheritAttrs: false,\n props: {\n dict: {\n type: [Object, Function] as PropType<SchemxDictionaryInput>,\n default: undefined,\n },\n },\n setup(props, { attrs, slots }: SetupContext) {\n const dictionary = normalizeDictionary(props.dict)\n\n // 内嵌于 Field 时自动从字段 Context 获取目标字段;显式 fieldName\n // 保留给脱离 Field 的独立使用场景。\n const fieldName = dictionary\n ? ((attrs.fieldName as string | undefined) ?? useFieldContext().name)\n : undefined\n\n const dictResult = dictionary ? useDictionary(dictionary, fieldName) : null\n\n const childrenProps = computed(() => {\n return {\n ...attrs,\n dict: dictionary,\n options: dictionary ? dictResult?.list.value : attrs.options,\n loading: dictionary ? dictResult?.loading.value : attrs.loading,\n }\n })\n\n return () => h(WrappedComponent, childrenProps.value, slots)\n },\n })\n}\n\nexport default WithRemoteOptions\n","<script setup lang=\"ts\">\n /**\n * Renderer 外层包装器。\n *\n * Wrapper 只负责 renderer 的外层属性、状态样式和 readonly 内容切换。\n * 具体控件布局与交互由 default 插槽中的子 renderer 负责。\n */\n import { computed, onMounted, ref, useAttrs, useSlots, watch } from \"vue\"\n\n interface Props {\n /**\n * 是否以只读插槽替换默认 Renderer 内容。\n */\n readonly?: boolean\n /**\n * 是否应用禁用状态样式。\n */\n disabled?: boolean\n }\n\n defineOptions({\n name: \"SchemxWrapper\",\n inheritAttrs: false,\n })\n\n const props = withDefaults(defineProps<Props>(), {\n readonly: false,\n disabled: false,\n })\n\n // 当前 Wrapper 的非组件属性。\n const attrs = useAttrs()\n\n // 用于判断是否提供只读插槽。\n const slots = useSlots()\n\n // 防止同一 Wrapper 在开发环境重复输出提示。\n const warnedReadonlySlot = ref(false)\n\n // 根据状态合并 Wrapper 根节点 class。\n const rootClass = computed(() => [\n \"schemx-wrapper\",\n attrs.class,\n props.readonly && \"schemx-wrapper--readonly\",\n props.disabled && \"schemx-wrapper--disabled\",\n ])\n\n // 转发给根节点但排除已单独处理的 class。\n const forwardedAttrs = computed(() => {\n const { class: _class, ...rest } = attrs\n\n return rest\n })\n\n /**\n * 在开发环境提示只读状态缺少 `#readonly` 插槽。\n *\n * @param readonly - 当前 Wrapper 是否处于只读状态。\n */\n const warnIfReadonlySlotIsMissing = (readonly: boolean): void => {\n if (!readonly || slots.readonly || warnedReadonlySlot.value || !import.meta.env.DEV) {\n return\n }\n\n warnedReadonlySlot.value = true\n console.warn(\"[schemx] SchemxWrapper is readonly but no #readonly slot was provided.\")\n }\n\n onMounted(() => warnIfReadonlySlotIsMissing(props.readonly))\n watch(() => props.readonly, warnIfReadonlySlotIsMissing)\n</script>\n\n<template>\n <div v-bind=\"forwardedAttrs\" :class=\"rootClass\">\n <template v-if=\"props.readonly\">\n <slot name=\"readonly\" :readonly=\"props.readonly\" :disabled=\"props.disabled\" />\n </template>\n <slot v-else :readonly=\"props.readonly\" :disabled=\"props.disabled\" />\n </div>\n</template>\n\n<style>\n .schemx-wrapper {\n box-sizing: border-box;\n width: 100%;\n }\n\n .schemx-wrapper--readonly {\n color: var(--schemx-wrapper-readonly-color, var(--schemx-readonly-color, #969799));\n cursor: default;\n }\n\n .schemx-wrapper--disabled {\n opacity: var(--schemx-disabled-opacity, 0.6);\n cursor: not-allowed;\n }\n\n .is-disabled .schemx-wrapper--disabled {\n opacity: 1;\n }\n</style>\n","/**\n * ConfigProvider - Vue 组件树级默认配置。\n *\n * 不渲染额外 DOM,只为后代 Form 提供 Vue 层配置。\n *\n * @module components/ConfigProvider\n */\n\nimport { computed, defineComponent, type PropType } from \"vue\"\n\nimport { createConfigProviderContext } from \"../../context\"\n\nimport type { SchemxColComponent, SchemxVueConfig } from \"../../types\"\nimport type {\n PresetRuleRegistry,\n RendererRegistry,\n SchemxRendererKey,\n SchemxRendererPropsMap,\n SchemxSchemaConfig,\n ValidationAdapterOption,\n Values,\n} from \"@schemx/core\"\n\n/**\n * ConfigProvider 的公开 Props。\n *\n * 配置会按组件树继承;子级 Provider 的非空配置覆盖父级同名配置。\n *\n * @typeParam TValues - 表单值类型。\n */\nexport type ConfigProviderProps<TValues extends Values = Values> =\n SchemxVueConfig<TValues>\n\nconst ConfigProvider = defineComponent({\n name: \"SchemxConfigProvider\",\n inheritAttrs: false,\n\n props: {\n schemaConfig: {\n type: Object as PropType<Partial<SchemxSchemaConfig>>,\n default: undefined,\n },\n rendererProps: {\n type: Object as PropType<SchemxRendererPropsMap>,\n default: undefined,\n },\n validatorAdapters: {\n type: Array as PropType<readonly ValidationAdapterOption[]>,\n default: undefined,\n },\n defaultRendererType: {\n type: String as PropType<SchemxRendererKey>,\n default: undefined,\n },\n rendererRegistry: {\n type: Object as PropType<RendererRegistry>,\n default: undefined,\n },\n presetRuleRegistry: {\n type: Object as PropType<PresetRuleRegistry>,\n default: undefined,\n },\n colComponent: {\n type: [Object, Function] as PropType<SchemxColComponent>,\n default: undefined,\n },\n },\n\n setup(props, { slots }) {\n const config = computed<SchemxVueConfig>(() => ({\n schemaConfig: props.schemaConfig,\n rendererProps: props.rendererProps,\n validatorAdapters: props.validatorAdapters,\n defaultRendererType: props.defaultRendererType,\n rendererRegistry: props.rendererRegistry,\n presetRuleRegistry: props.presetRuleRegistry,\n colComponent: props.colComponent,\n }))\n\n createConfigProviderContext(config)\n\n return () => slots.default?.()\n },\n})\n\nexport default ConfigProvider\n"],"names":["rendererRegistry","presetRuleRegistry","values","createFieldSlotRenderers","options","schemaRef","field","form","formContext","componentProps","slots","renderRequired","showRequiredMark","value","Boolean","required","disabled","readonly","_createVNode","_createTextVNode","createSlotProps","additionalProps","schema","renderFieldSlot","suffix","slot","resolveSlot","normalizeNameKey","name","renderLabel","labelSlot","labelAlign","schemaConfig","labelWidth","colon","width","textAlign","labelIcon","label","renderBefore","renderContent","component","getRenderer","componentType","Error","childSlots","extractChildSlots","columnElement","h","contentSlot","renderAfter","renderError","errorSlot","errors","length","Field","defineComponent","inheritAttrs","props","type","Object","class","String","Array","default","undefined","style","setup","attrs","useFormContextValue","inputSchema","computed","latestSchema","useViewSchema","key","isSchemxViewFieldSchema","useField","createFieldContext","trigger","mergeTrigger","validationTrigger","canVerified","isOperate","visible","rules","hasRules","isArray","handleChange","v","setValue","onChange","shouldValidateOn","validate","handleBlur","onBlur","updateValue","useStableRef","currentComponentProps","align","contentAlign","placeholder","readonlyPlaceholder","fieldSlot","labelPosition","fieldContent","classnames","_mergeProps","_createElementBlock","_unref","$slots","_openBlock","_renderSlot","_Fragment","_toDisplayString","Col","layout","Function","resolvedComponent","registeredColComponent","markRaw","toRaw","span","block","offset","attrsClass","attrsStyle","restAttrs","createGroupSlotRenderers","collapsed","collapsible","toggle","renderChildren","slotKey","headerSlot","slotProps","renderHeaderContent","renderBodyContent","hasHeader","Group","internalCollapsed","ref","defaultCollapsed","componentId","getCurrentInstance","uid","watch","nextCollapsed","previousCollapsed","onCollapsedChange","isCollapsed","destroyOnCollapse","uniqueId","debug","runtimeNodeId","idBase","normalizeId","headerId","bodyId","renderChild","child","isViewDynamicSchema","items","map","item","children","itemChild","isViewGroupSchema","body","display","e","preventDefault","Dynamic","viewSchemas","getFieldRenderKey","getFieldClass","isFirst","isLast","getSectionPosition","renderItemSchema","_isSlot","s","prototype","toString","call","_isVNode","SchemaList","schemas","colComponent","fieldClassResolver","getSchemaRenderKey","renderSchema","content","_withCtx","_normalizeProps","_guardReactiveProps","_createBlock","Button","SchemxForm","ConfigProvider","rendererProps","validatorAdapters","defaultRendererType","config","createConfigProviderContext"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/bridge/helpers.ts","../src/bridge/fieldBridge.ts","../src/bridge/formInstance.ts","../src/bridge/viewSchemaBridge.ts","../src/bridge/formBridge.ts","../src/context/formContext.ts","../src/context/fieldContext.ts","../src/context/configProviderContext.ts","../src/utils/presetRuleProvider.ts","../src/utils/rendererProvider.ts","../src/config/vueConfig.ts","../src/config/defaultVueSchemaConfig.ts","../src/hooks/useForm.ts","../src/hooks/useField.ts","../src/hooks/useWatch.ts","../src/hooks/useDictionary.ts","../src/utils/equal.ts","../src/hooks/useStableRef.ts","../src/hooks/useViewSchemas.ts","../src/hooks/useFormSelector.ts","../src/utils/validation.ts","../src/utils/slot.ts","../src/utils/helpers.ts","../src/utils/layout.ts","../src/components/Col/index.tsx","../src/components/Icon/index.tsx","../src/components/Field/slot.tsx","../src/components/Field/index.tsx","../src/components/Button/index.vue","../src/components/Dynamic/index.tsx","../src/components/Group/slot.tsx","../src/components/Group/index.tsx","../src/components/Row/index.tsx","../src/components/SchemaList/index.tsx","../src/form.vue","../src/form.ts","../src/hocs/withRemoteOptions.ts","../src/components/Wrapper/index.vue","../src/components/ConfigProvider/index.tsx"],"sourcesContent":["/**\n * Vue Runtime 使用的 Ref 和快照比较工具。\n *\n * @module vue/bridge/helpers\n */\n\nimport { shallowRef } from \"vue\"\nimport type { ShallowRef } from \"vue\"\n\nimport type { SnapshotSource } from \"@schemx/core/adapter\"\n\n/**\n * 创建类型为 `ShallowRef` 的 Vue 浅层 Ref。\n *\n * 运行时直接委托 Vue 的 `shallowRef`,类型断言用于保留 Runtime 对快照引用的控制。\n *\n * @typeParam TValue - Ref 中保存的值类型。\n * @param value - 要包装为 shallow Ref 的当前值。\n * @returns 包装后的 shallow Ref。\n *\n * @example\n * ```ts\n * const ready = createVueShallowRef(false)\n * ready.value = true\n * ```\n */\nexport function createVueShallowRef<TValue>(value: TValue): ShallowRef<TValue> {\n return shallowRef(value) as ShallowRef<TValue>\n}\n\n/**\n * 将 Core SnapshotSource 绑定为 Vue shallow Ref。\n *\n * SnapshotSource 的生命周期由所属 FormStateAdapter 统一管理;这里仅保留\n * 同步逻辑,避免每个 Form 级来源重复声明一套订阅函数。\n *\n * @param source - 提供快照和订阅能力的 Core Source。\n * @returns 与 Source 当前快照同步的 Vue shallow Ref。\n *\n * @example\n * ```ts\n * const values = bindSnapshotSource(stateAdapter.values)\n * ```\n */\nexport function bindSnapshotSource<TValue>(\n source: SnapshotSource<TValue>\n): ShallowRef<TValue> {\n const value = createVueShallowRef(source.getSnapshot())\n\n source.subscribe(() => {\n value.value = source.getSnapshot()\n })\n\n return value\n}\n\n/**\n * 比较两份错误消息列表,避免无变化时写入 Vue Ref。\n *\n * @param previous - 当前 Ref 中保存的错误消息列表。\n * @param next - SnapshotSource 返回的最新错误消息列表。\n * @returns 两个列表的长度和每一项都相同时返回 `true`。\n *\n * @example\n * ```ts\n * const changed = !areStringListsEqual(previous, next)\n * ```\n */\nexport function areStringListsEqual(\n previous: readonly string[],\n next: readonly string[]\n): boolean {\n return (\n previous.length === next.length &&\n previous.every((value, index) => value === next[index])\n )\n}\n","/**\n * 将 Core 字段快照投影为可共享的 Vue Ref。\n *\n * 字段投影只负责创建状态;来源订阅由所属 FormStateAdapter 统一回收。\n *\n * @module vue/bridge/fieldBridge\n */\n\nimport { areStringListsEqual, createVueShallowRef } from \"./helpers\"\n\nimport type { VueFieldState, VueFormResources } from \"./types\"\nimport type { FieldValue, NamePath, Values } from \"@schemx/core\"\n\n/**\n * 获取一个字段的共享 Vue 状态投影。\n *\n * FormStateAdapter 按规范化路径缓存 Source;Source 身份作为当前资源中的\n * 稳定 key,确保同一字段不会重复创建订阅。\n *\n * @typeParam TValues - 表单值类型。\n * @typeParam TName - 当前字段路径类型。\n * @param resources - 当前 Runtime 的响应式资源集合。\n * @param name - 要读取状态的字段路径。\n * @returns 当前字段的共享 Vue 状态投影。\n *\n * @example\n * ```ts\n * const state = getVueFieldState(resources, \"name\")\n * console.log(state.value.value)\n * ```\n */\nexport function getVueFieldState<\n TValues extends Values = Values,\n TName extends NamePath<TValues> = NamePath<TValues>,\n>(resources: VueFormResources<TValues>, name: TName): VueFieldState<TValues, TName> {\n const source = resources.stateAdapter.field(name)\n\n const cachedState = resources.fieldStates.get(source as object)\n\n if (cachedState) {\n return cachedState as VueFieldState<TValues, TName>\n }\n\n const snapshot = source.getSnapshot()\n\n const value = createVueShallowRef<FieldValue<TValues, TName> | undefined>(\n snapshot.value\n )\n\n const errors = createVueShallowRef<readonly string[]>(snapshot.errors)\n\n const touched = createVueShallowRef<boolean>(snapshot.touched)\n\n const pending = createVueShallowRef<boolean>(snapshot.pending)\n\n const updateFieldState = (): void => {\n const nextSnapshot = source.getSnapshot()\n\n if (!Object.is(value.value, nextSnapshot.value)) {\n value.value = nextSnapshot.value\n }\n\n if (!areStringListsEqual(errors.value, nextSnapshot.errors)) {\n errors.value = nextSnapshot.errors\n }\n\n if (touched.value !== nextSnapshot.touched) {\n touched.value = nextSnapshot.touched\n }\n\n if (pending.value !== nextSnapshot.pending) {\n pending.value = nextSnapshot.pending\n }\n }\n\n source.subscribe(updateFieldState)\n\n const fieldState: VueFieldState<TValues, TName> = {\n value,\n errors,\n touched,\n pending,\n }\n\n resources.fieldStates.set(source as object, fieldState as VueFieldState<TValues>)\n\n return fieldState\n}\n","/**\n * 创建保持 Core API 的 Vue Instance。\n *\n * Instance 只负责把读取动作转成 Runtime 依赖收集,资源缓存和生命周期\n * 由所属 VueFormRuntime 管理。\n *\n * @module vue/bridge/formInstance\n */\n\nimport type { VueFieldDependency, VueFormDependency } from \"./types\"\nimport type { NamePath, SchemxInstance, Values } from \"@schemx/core\"\n\n/**\n * 创建 Instance 所需的 Runtime 追踪能力。\n */\ninterface VueFormInstanceDependencies<TValues extends Values> {\n /**\n * 追踪单个字段的指定状态依赖。\n */\n trackField<TName extends NamePath<TValues>>(\n name: TName,\n dependency: VueFieldDependency\n ): void\n /**\n * 追踪完整表单值或指定字段值。\n */\n trackFieldsValue(names?: NamePath<TValues>[]): void\n /**\n * 追踪 Form 级聚合状态。\n */\n trackForm(dependency: VueFormDependency): void\n /**\n * 销毁 Runtime 持有的响应式资源。\n */\n destroy(): void\n}\n\n/**\n * 为 Core Form 创建保持完整 API 的 Vue Instance。\n *\n * @param form - 要包装的原始 Core Form。\n * @param dependencies - 所属 Runtime 提供的依赖追踪与销毁能力。\n * @returns 可被 Vue effect 追踪的 Instance。\n *\n * @example\n * ```ts\n * const instance = createVueFormInstance(coreForm, runtimeDependencies)\n * ```\n */\nexport function createVueFormInstance<TValues extends Values>(\n form: SchemxInstance<TValues>,\n dependencies: VueFormInstanceDependencies<TValues>\n): SchemxInstance<TValues> {\n let destroyed = false\n\n const getFieldValue: SchemxInstance<TValues>[\"getFieldValue\"] = (name) => {\n if (!destroyed) {\n dependencies.trackField(name, \"value\")\n }\n\n return form.getFieldValue(name)\n }\n\n const getFieldErrors: SchemxInstance<TValues>[\"getFieldErrors\"] = (name) => {\n if (!destroyed) {\n dependencies.trackField(name, \"errors\")\n }\n\n return form.getFieldErrors(name)\n }\n\n const isFieldTouched: SchemxInstance<TValues>[\"isFieldTouched\"] = (name) => {\n if (!destroyed) {\n dependencies.trackField(name, \"touched\")\n }\n\n return form.isFieldTouched(name)\n }\n\n const isFieldPending: SchemxInstance<TValues>[\"isFieldPending\"] = (name) => {\n if (!destroyed) {\n dependencies.trackField(name, \"pending\")\n }\n\n return form.isFieldPending(name)\n }\n\n const getFieldsValue = ((names?: NamePath<TValues>[]) => {\n if (!destroyed) {\n dependencies.trackFieldsValue(names)\n }\n\n return form.getFieldsValue(names)\n }) as SchemxInstance<TValues>[\"getFieldsValue\"]\n\n const getTouchedFields: SchemxInstance<TValues>[\"getTouchedFields\"] = () => {\n if (!destroyed) {\n dependencies.trackForm(\"touchedFields\")\n }\n\n return form.getTouchedFields()\n }\n\n const getPendingFields: SchemxInstance<TValues>[\"getPendingFields\"] = () => {\n if (!destroyed) {\n dependencies.trackForm(\"pendingFields\")\n }\n\n return form.getPendingFields()\n }\n\n const isLoading: SchemxInstance<TValues>[\"isLoading\"] = () => {\n if (!destroyed) {\n dependencies.trackForm(\"loading\")\n }\n\n return form.isLoading()\n }\n\n const destroy: SchemxInstance<TValues>[\"destroy\"] = () => {\n if (destroyed) {\n return\n }\n\n destroyed = true\n dependencies.destroy()\n form.destroy()\n }\n\n return {\n ...form,\n getFieldValue,\n getFieldErrors,\n isFieldTouched,\n isFieldPending,\n getFieldsValue,\n getTouchedFields,\n getPendingFields,\n isLoading,\n destroy,\n }\n}\n","/**\n * 将 Core ViewSchema 列表投影为共享的 Vue 状态。\n *\n * @module vue/bridge/viewSchemaBridge\n */\n\nimport { computed, shallowRef } from \"vue\"\n\nimport { isViewDynamicSchema, isViewGroupSchema } from \"@schemx/core\"\n\nimport type { VueViewSchemaState } from \"./types\"\nimport type { SchemxInstance, SchemxViewSchema, Values } from \"@schemx/core\"\n\n/**\n * 创建一个 Form 的共享 ViewSchema 状态。\n *\n * @typeParam TValues - 表单值类型。\n * @param form - 要订阅 ViewSchema 的 Core Form。\n * @returns 当前 Form 的 ViewSchema 列表、索引和释放方法。\n *\n * @example\n * ```ts\n * const state = createVueViewSchemaState(form)\n * const current = state.viewSchemas.value\n * state.dispose()\n * ```\n */\nexport function createVueViewSchemaState<TValues extends Values>(\n form: SchemxInstance<TValues>\n): VueViewSchemaState<TValues> {\n const viewSchemas = shallowRef<readonly SchemxViewSchema<TValues>[]>(\n form.getViewSchemas()\n )\n\n const schemasByKey = computed<ReadonlyMap<string, SchemxViewSchema<TValues>>>(() => {\n return createViewSchemaIndex(viewSchemas.value)\n })\n\n const unsubscribe = form.subscribeViewSchemas((nextSchemas) => {\n viewSchemas.value = nextSchemas\n })\n\n let disposed = false\n\n const dispose = (): void => {\n if (disposed) {\n return\n }\n\n disposed = true\n unsubscribe()\n }\n\n return {\n schemasByKey,\n viewSchemas,\n dispose,\n }\n}\n\n/**\n * 递归索引顶层和分组内的 ViewSchema。\n *\n * @param viewSchemas - 待索引的 ViewSchema 列表。\n * @returns 按 key 建立的 ViewSchema 索引。\n */\nfunction createViewSchemaIndex<TValues extends Values>(\n viewSchemas: readonly SchemxViewSchema<TValues>[]\n): ReadonlyMap<string, SchemxViewSchema<TValues>> {\n const schemasByKey = new Map<string, SchemxViewSchema<TValues>>()\n\n /**\n * 递归写入当前层级及其嵌套子节点的 ViewSchema 索引。\n *\n * @param schemas - 当前层级的 ViewSchema 列表。\n */\n const appendSchemas = (schemas: readonly SchemxViewSchema<TValues>[]): void => {\n for (const schema of schemas) {\n schemasByKey.set(schema.key, schema)\n\n if (isViewGroupSchema(schema)) {\n appendSchemas(schema.children)\n } else if (isViewDynamicSchema(schema)) {\n for (const item of schema.items) {\n appendSchemas(item.children)\n }\n }\n }\n }\n\n appendSchemas(viewSchemas)\n\n return schemasByKey\n}\n","/**\n * Core Form 到 Vue 响应式状态的共享 Runtime。\n *\n * 每个 Core Form 只有一个稳定 Runtime 和一个 Vue Instance;响应式资源按\n * Vue owner 激活和释放,避免调用方同时管理 Runtime、Adapter 和订阅。\n *\n * @module vue/bridge/formBridge\n */\n\nimport { getCurrentScope, onScopeDispose } from \"vue\"\n\nimport { createFormStateAdapter } from \"@schemx/core/adapter\"\n\nimport { getVueFieldState } from \"./fieldBridge\"\nimport { createVueFormInstance } from \"./formInstance\"\nimport { bindSnapshotSource } from \"./helpers\"\nimport { createVueViewSchemaState } from \"./viewSchemaBridge\"\n\nimport type {\n VueFieldDependency,\n VueFieldState,\n VueFormDependency,\n VueFormResources,\n VueFormRuntime,\n} from \"./types\"\nimport type { NamePath, SchemxInstance, Values } from \"@schemx/core\"\n\n/**\n * 同一 Core Form 只创建一个稳定 Runtime。\n */\nconst runtimeCache = new WeakMap<object, VueFormRuntime<Values>>()\n\n/**\n * 在当前 Vue effect scope 中获取共享 Runtime。\n *\n * 每次调用都会为当前 scope 保留一个 Runtime owner,并在 scope 停止时自动\n * 释放该 owner;最后一个 owner 释放后,字段和表单级响应式资源才会回收。\n *\n * @typeParam TValues - 表单值类型。\n * @param form - 要桥接或复用 Runtime 的表单实例。\n * @returns 当前 Form 对应的共享 Runtime。\n * @throws 当前没有活动的 Vue effect scope 时抛出错误。\n *\n * @example\n * ```ts\n * // 在 setup() 或其他活动的 Vue effect scope 中调用。\n * const runtime = useVueFormRuntime(form)\n * const values = runtime.getValuesRef()\n * ```\n */\nexport function useVueFormRuntime<TValues extends Values = Values>(\n form: SchemxInstance<TValues>\n): VueFormRuntime<TValues> {\n if (!getCurrentScope()) {\n throw new Error(\"[schemx] useVueFormRuntime() requires an active Vue scope.\")\n }\n\n const { runtime, release } = acquireVueFormRuntime(form)\n\n onScopeDispose(release)\n\n return runtime\n}\n\n/**\n * 获取并保留指定 Form 的共享 Runtime。\n *\n * 返回的 release 函数必须绑定到当前 owner 的 Vue scope;最后一个 owner\n * 释放后只销毁响应式资源,Runtime 和 Instance 身份保持稳定。\n *\n * @typeParam TValues - 表单值类型。\n * @param form - 要桥接或复用 Runtime 的表单实例。\n * @returns 共享 Runtime 及与当前 owner 对应的释放函数。\n *\n * @example\n * ```ts\n * const { runtime, release } = acquireVueFormRuntime(form)\n * try {\n * runtime.getValuesRef()\n * } finally {\n * release()\n * }\n * ```\n */\nexport function acquireVueFormRuntime<TValues extends Values = Values>(\n form: SchemxInstance<TValues>\n): {\n runtime: VueFormRuntime<TValues>\n release: () => void\n} {\n const runtime = getOrCreateVueFormRuntime(form)\n\n const release = runtime.retain()\n\n return {\n runtime,\n release,\n }\n}\n\n/**\n * 获取已有 Runtime,或为输入的 Core Form 创建 Runtime。\n *\n * 原始实例和桥接后的响应式实例都会映射到同一个 Runtime,避免同一表单因\n * 不同入口重复创建状态订阅。\n *\n * @param form - 要查找或创建 Runtime 的 Form Instance。\n */\nfunction getOrCreateVueFormRuntime<TValues extends Values>(\n form: SchemxInstance<TValues>\n): VueFormRuntime<TValues> {\n const cachedByCore = runtimeCache.get(form as object)\n\n if (cachedByCore) {\n return cachedByCore as VueFormRuntime<TValues>\n }\n\n const runtime = createVueFormRuntime(form)\n\n runtimeCache.set(form as object, runtime as VueFormRuntime<Values>)\n runtimeCache.set(runtime.instance as object, runtime as VueFormRuntime<Values>)\n\n return runtime\n}\n\n/**\n * 创建单个 Core Form 的稳定 Runtime。\n *\n * Runtime 本身保持稳定;只有存在 owner 时才创建并保留 Vue 响应式资源。\n *\n * @param core - 要桥接的 Core Form。\n */\nfunction createVueFormRuntime<TValues extends Values>(\n core: SchemxInstance<TValues>\n): VueFormRuntime<TValues> {\n let resources: VueFormResources<TValues> | undefined\n\n let ownerCount = 0\n\n let destroyed = false\n\n const createResources = (): VueFormResources<TValues> => {\n const stateAdapter = createFormStateAdapter(core)\n\n const values = bindSnapshotSource(stateAdapter.values)\n\n const touchedFields = bindSnapshotSource(stateAdapter.touchedFields)\n\n const pendingFields = bindSnapshotSource(stateAdapter.pendingFields)\n\n const loading = bindSnapshotSource(stateAdapter.loading)\n\n const fieldStates = new Map<object, VueFieldState<TValues>>()\n\n let disposed = false\n\n const dispose = (): void => {\n if (disposed) {\n return\n }\n\n disposed = true\n\n currentResources.viewSchemaState?.dispose()\n fieldStates.clear()\n stateAdapter.dispose()\n }\n\n const currentResources: VueFormResources<TValues> = {\n stateAdapter,\n values,\n touchedFields,\n pendingFields,\n loading,\n fieldStates,\n dispose,\n }\n\n return currentResources\n }\n\n const ensureResources = (): VueFormResources<TValues> => {\n if (destroyed) {\n throw new Error(\"[schemx] Vue Form Runtime has been destroyed.\")\n }\n\n resources ??= createResources()\n\n return resources\n }\n\n const disposeResources = (): void => {\n const currentResources = resources\n\n if (!currentResources) {\n return\n }\n\n resources = undefined\n currentResources.dispose()\n }\n\n const retain = (): (() => void) => {\n if (destroyed) {\n return () => {}\n }\n\n ensureResources()\n ownerCount++\n\n let released = false\n\n return () => {\n if (released || destroyed) {\n return\n }\n\n released = true\n ownerCount--\n\n if (ownerCount === 0) {\n disposeResources()\n }\n }\n }\n\n const trackField = <TName extends NamePath<TValues>>(\n name: TName,\n dependency: VueFieldDependency\n ): void => {\n if (!resources) {\n return\n }\n\n const fieldState = getVueFieldState(resources, name)\n\n void fieldState[dependency].value\n }\n\n const trackFieldsValue = (names?: NamePath<TValues>[]): void => {\n if (!resources) {\n return\n }\n\n if (names === undefined) {\n void resources.values.value\n\n return\n }\n\n for (const name of names) {\n void getVueFieldState(resources, name).value.value\n }\n }\n\n const trackForm = (dependency: VueFormDependency): void => {\n if (!resources) {\n return\n }\n\n switch (dependency) {\n case \"values\":\n void resources.values.value\n break\n case \"touchedFields\":\n void resources.touchedFields.value\n break\n case \"pendingFields\":\n void resources.pendingFields.value\n break\n case \"loading\":\n void resources.loading.value\n break\n }\n }\n\n const getValuesRef = (): VueFormResources<TValues>[\"values\"] => {\n return ensureResources().values\n }\n\n const getFieldState = <TName extends NamePath<TValues>>(name: TName) => {\n return getVueFieldState(ensureResources(), name)\n }\n\n const getViewSchemaState = () => {\n const currentResources = ensureResources()\n\n const viewSchemaState = (currentResources.viewSchemaState ??=\n createVueViewSchemaState(core))\n\n return viewSchemaState\n }\n\n const destroy = (): void => {\n if (destroyed) {\n return\n }\n\n destroyed = true\n ownerCount = 0\n disposeResources()\n }\n\n const instance = createVueFormInstance(core, {\n trackField,\n trackFieldsValue,\n trackForm,\n destroy,\n })\n\n const runtime: VueFormRuntime<TValues> = {\n core,\n instance,\n retain,\n trackField,\n trackFieldsValue,\n trackForm,\n getValuesRef,\n getFieldState,\n getViewSchemaState,\n destroy,\n }\n\n return runtime\n}\n","/**\n * 具体表单的 Vue provide/inject 适配。\n *\n * 一个 Form Context 同时保存 SchemxInstance 与该表单最终用于展示的\n * schemaConfig;其中包含从 ConfigProvider/App 继承的值,不保留 Provider 原始配置对象。\n *\n * @module context/formContext\n */\n\nimport { inject, type InjectionKey, provide } from \"vue\"\n\nimport { useVueFormRuntime, type VueFormRuntime } from \"../bridge\"\n\nimport type { SchemxIconComponent } from \"../types/icon\"\nimport type { SchemxColComponent, SchemxRowComponent } from \"../types/layout\"\nimport type { SchemxInstance, SchemxSchemaConfig, Values } from \"@schemx/core\"\n\n/**\n * 表单实例的注入键。\n *\n * @internal\n */\nexport const SCHEMX_FORM_INSTANCE_KEY: InjectionKey<SchemxInstance> =\n Symbol(\"schemx:instance\")\n\n/**\n * 表单展示配置的注入键。\n *\n * @internal\n */\nexport const SCHEMX_FORM_CONFIG_KEY: InjectionKey<FormConfigContextValue> =\n Symbol(\"schemx:form-config\")\n\n/**\n * 表单展示配置 Context。\n */\nexport interface FormConfigContextValue {\n /** 当前 Form 已解析的展示配置。 */\n schemaConfig: Partial<SchemxSchemaConfig>\n /** 当前 Form 使用的 Icon Adapter。 */\n iconComponent?: SchemxIconComponent\n /** 当前 Form 使用的 Row 组件。 */\n rowComponent?: SchemxRowComponent\n /** 当前 Form 使用的 Col 组件。 */\n colComponent?: SchemxColComponent\n}\n\n/**\n * 一个具体 Form 向后代暴露的运行上下文。\n */\nexport interface FormContextValue<\n TValues extends Values = Values,\n> extends FormConfigContextValue {\n /** 当前 Form 的响应式实例。 */\n form: SchemxInstance<TValues>\n}\n\n/**\n * 一次性向后代提供具体 Form 的实例与最终展示配置。\n *\n * @typeParam TValues - 表单值类型。\n * @param context - Form 实例、展示配置和可选的布局组件与 Icon Adapter。\n * @returns Vue Runtime 包装后的 Form 实例。\n *\n * @example\n * ```ts\n * setup() {\n * const form = useForm({ initialValues: { name: \"\" } })\n * provideFormContext({ form, schemaConfig: {} })\n * }\n * ```\n */\nexport function provideFormContext<TValues extends Values = Values>(\n context: FormContextValue<TValues>\n): SchemxInstance<TValues> {\n const form = useVueFormRuntime<TValues>(context.form).instance\n\n provide(SCHEMX_FORM_INSTANCE_KEY, form as SchemxInstance)\n provide(SCHEMX_FORM_CONFIG_KEY, context)\n\n return form\n}\n\n/**\n * 获取最近祖先提供的完整 Form Context。\n *\n * @typeParam TValues - 表单值类型。\n * @returns 最近的 Form 实例和最终展示配置。\n * @throws 当前组件树中没有 Form Context 时抛出错误。\n *\n * @example\n * ```ts\n * setup() {\n * const context = useFormContextValue()\n * context.form.submit()\n * }\n * ```\n */\nexport function useFormContextValue<\n TValues extends Values = Values,\n>(): FormContextValue<TValues> {\n const context = useOptionalFormContextValue<TValues>()\n\n if (context) {\n return context\n }\n\n throw new Error(\n \"[schemx] useFormContextValue() must be called inside a <SchemxForm> descendant. \" +\n \"Ensure provideFormContext({ form, schemaConfig }) is called synchronously during setup().\"\n )\n}\n\n/**\n * 尝试读取当前 Form Context。\n *\n * 供可直接挂载的 Group、Dynamic 等底层组件在存在 Form 上下文时消费展示配置;\n * 脱离 Form 时返回 `undefined`,由组件自身的兼容 Props 提供回退。\n *\n * @typeParam TValues - 表单值类型。\n * @returns 最近的 Form Context;未在 Form 后代中调用时返回 `undefined`。\n *\n * @example\n * ```ts\n * setup() {\n * const context = useOptionalFormContextValue()\n * return { rowComponent: context?.rowComponent }\n * }\n * ```\n */\nexport function useOptionalFormContextValue<TValues extends Values = Values>():\n FormContextValue<TValues> | undefined {\n const form = inject(SCHEMX_FORM_INSTANCE_KEY, null)\n\n const config = inject(SCHEMX_FORM_CONFIG_KEY, null)\n\n if (form && config) {\n return {\n form: form as SchemxInstance<TValues>,\n get schemaConfig() {\n return config.schemaConfig\n },\n get iconComponent() {\n return config.iconComponent\n },\n get rowComponent() {\n return config.rowComponent\n },\n get colComponent() {\n return config.colComponent\n },\n }\n }\n\n return undefined\n}\n\n/**\n * 向后代提供表单实例的兼容 API。\n *\n * @deprecated 请改用 {@link provideFormContext}({ form, schemaConfig })。\n *\n * @param instance - 要提供给后代组件的 SchemxInstance。\n * @returns Vue Runtime 包装后的 Form 实例。\n *\n * @example\n * ```ts\n * setup() {\n * const form = useForm()\n * provideFormContext({ form, schemaConfig: {} })\n * }\n * ```\n */\nexport function createFormContext<TValues extends Values = Values>(\n instance: SchemxInstance<TValues>\n): SchemxInstance<TValues> {\n const form = useVueFormRuntime<TValues>(instance).instance\n\n provide(SCHEMX_FORM_INSTANCE_KEY, form as SchemxInstance)\n\n return form\n}\n\n/**\n * 获取最近祖先提供的表单实例。\n *\n * @typeParam TValues - 表单值类型。\n * @returns 最近的 SchemxInstance。\n * @throws 当前组件树中没有 Form 实例时抛出错误。\n *\n * @example\n * ```ts\n * setup() {\n * const form = useFormContext()\n * form.getFieldsValue()\n * }\n * ```\n */\nexport function useFormContext<\n TValues extends Values = Values,\n>(): SchemxInstance<TValues> {\n const instance = inject(SCHEMX_FORM_INSTANCE_KEY, null)\n\n if (!instance) {\n throw new Error(\n \"[schemx] useFormContext() must be called inside a <SchemxForm> descendant. \" +\n \"Ensure provideFormContext({ form, schemaConfig }) is called synchronously during setup().\"\n )\n }\n\n return instance as SchemxInstance<TValues>\n}\n\n/**\n * 向后代提供表单展示配置的兼容 API。\n *\n * @deprecated 请改用 {@link provideFormContext}({ form, schemaConfig })。\n *\n * @param props - 要提供给后代的 Form 展示配置。\n *\n * @example\n * ```ts\n * setup() {\n * const form = useForm()\n * provideFormContext({ form, ...props })\n * }\n * ```\n */\nexport function createFormConfigContext(props: FormConfigContextValue): void {\n provide(SCHEMX_FORM_CONFIG_KEY, props)\n}\n\n/**\n * 获取当前 Form 的展示配置。\n *\n * @returns 最近 Form 提供的最终展示配置。\n * @throws 当前组件树中没有 Form Config Context 时抛出错误。\n *\n * @example\n * ```ts\n * setup() {\n * const { schemaConfig } = useFormConfigContext()\n * console.log(schemaConfig.readonly)\n * }\n * ```\n */\nexport function useFormConfigContext(): FormConfigContextValue {\n const config = inject(SCHEMX_FORM_CONFIG_KEY, null)\n\n if (!config) {\n throw new Error(\n \"[schemx] useFormConfigContext() must be called inside a <SchemxForm> descendant. \" +\n \"Ensure provideFormContext({ form, schemaConfig }) is called synchronously during setup().\"\n )\n }\n\n return config\n}\n\n/**\n * 获取当前表单的 Vue Runtime。\n *\n * @typeParam TValues - 表单值类型。\n * @returns 当前 Form 对应的 Vue Runtime。\n *\n * @example\n * ```ts\n * setup() {\n * const runtime = useFormRuntimeContext()\n * return { values: runtime.instance.getFieldsValue() }\n * }\n * ```\n */\nexport function useFormRuntimeContext<\n TValues extends Values = Values,\n>(): VueFormRuntime<TValues> {\n return useVueFormRuntime(useFormContext<TValues>())\n}\n","/**\n * 当前字段实例的 Vue provide/inject 适配。\n *\n * @module context/fieldContext\n */\n\nimport { inject, type InjectionKey, provide } from \"vue\"\n\nimport type { FieldInstance } from \"../types/field\"\nimport type { Values } from \"@schemx/core\"\n\nconst SCHEMX_FIELD_CONTEXT_KEY: InjectionKey<FieldInstance<Values>> =\n Symbol(\"schemx:field\")\n\n/**\n * 向后代组件提供当前字段实例。\n */\nexport function createFieldContext<TValues extends Values = Values>(\n field: FieldInstance<TValues>\n): void {\n provide<FieldInstance<Values>>(SCHEMX_FIELD_CONTEXT_KEY, field as FieldInstance<Values>)\n}\n\n/**\n * 获取最近祖先组件提供的当前字段实例。\n */\nexport function useFieldContext(): FieldInstance<Values> {\n const field = inject<FieldInstance<Values> | null>(SCHEMX_FIELD_CONTEXT_KEY, null)\n\n if (!field) {\n throw new Error(\n \"[schemx] useFieldContext() must be called inside a component tree where \" +\n \"createFieldContext(field) has been called.\"\n )\n }\n\n return field\n}\n","/**\n * Vue 组件树级 Schemx 配置的 provide/inject 适配。\n *\n * @module context/configProviderContext\n */\n\nimport { computed, getCurrentInstance, inject, provide } from \"vue\"\nimport type { App, ComputedRef, InjectionKey } from \"vue\"\n\nimport { mergeConfig } from \"@schemx/core\"\n\nimport type { SchemxConfig, SchemxRendererPropsMap } from \"@schemx/core\"\n\nconst SCHEMX_CONFIG_PROVIDER_KEY: InjectionKey<ComputedRef<SchemxConfig>> = Symbol(\n \"schemx:config-provider\"\n)\n\n/**\n * 复制并冻结 Core 配置的受管外层;扩展字段和 Registry 实例保留原引用。\n *\n * @param config - 当前 Vue App 的默认配置。\n * @returns 受管外层与调用方输入隔离的只读配置快照。\n */\nfunction normalizeSchemxAppConfig(config: SchemxConfig): SchemxConfig {\n const schemaConfig = Object.freeze({ ...(config.schemaConfig ?? {}) })\n\n const validatorAdapters = Object.freeze([...(config.validatorAdapters ?? [])])\n\n return Object.freeze({\n ...config,\n schemaConfig,\n rendererProps: normalizeRendererProps(config.rendererProps),\n validatorAdapters,\n })\n}\n\n/**\n * 浅复制 Renderer Props Map 外层及每个 Renderer 的 Props 对象。\n *\n * @param source - 待复制的 Renderer Props Map。\n * @returns 新的 Renderer Props Map;嵌套 Prop 值保留原引用。\n */\nfunction normalizeRendererProps(\n source: SchemxRendererPropsMap | undefined\n): SchemxRendererPropsMap | undefined {\n if (source === undefined) {\n return undefined\n }\n\n const entries = Object.entries(source).map(([type, props]) => {\n return [type, props === undefined ? undefined : Object.freeze({ ...props })]\n })\n\n return Object.freeze(Object.fromEntries(entries)) as SchemxRendererPropsMap\n}\n\n/**\n * 将安装配置作为当前 Vue App 的根配置上下文。\n *\n * `schemaConfig`、`rendererProps` 和 adapter 列表会复制并冻结受管层级。\n * 扩展字段与 Registry 实例保留原引用。\n *\n * @param app - 要提供配置的 Vue App。\n * @param config - 该 App 的默认 Schemx 配置。\n *\n * @example\n * ```ts\n * const app = createApp(App)\n * provideSchemxAppConfig(app, { schemaConfig: { readonly: true } })\n * app.mount(\"#app\")\n * ```\n */\nexport function provideSchemxAppConfig(app: App, config: SchemxConfig = {}): void {\n const normalizedConfig = normalizeSchemxAppConfig(config)\n\n app.provide(\n SCHEMX_CONFIG_PROVIDER_KEY,\n computed<SchemxConfig>(() => normalizedConfig)\n )\n}\n\n/**\n * 创建并注入合并后的组件树级配置上下文。\n *\n * 子级提供的配置优先于父级;省略的配置项沿用最近祖先的值。\n *\n * @param config - 当前 ConfigProvider 的响应式配置。\n *\n * @example\n * ```ts\n * setup() {\n * const config = computed(() => ({ schemaConfig: { readonly: true } }))\n * createConfigProviderContext(config)\n * }\n * ```\n */\nexport function createConfigProviderContext(config: ComputedRef<SchemxConfig>): void {\n const parentConfig = inject(SCHEMX_CONFIG_PROVIDER_KEY, undefined)\n\n const mergedConfig = computed<SchemxConfig>(() => {\n const mergedCoreConfig = mergeConfig(config.value, parentConfig?.value ?? {})\n\n const parentRow = parentConfig?.value.row\n\n const localRow = config.value.row\n\n return {\n ...mergedCoreConfig,\n colComponent: config.value.colComponent ?? parentConfig?.value.colComponent,\n rowComponent: config.value.rowComponent ?? parentConfig?.value.rowComponent,\n iconComponent: config.value.iconComponent ?? parentConfig?.value.iconComponent,\n row:\n localRow === undefined\n ? parentRow\n : {\n ...parentRow,\n ...localRow,\n },\n }\n })\n\n provide(SCHEMX_CONFIG_PROVIDER_KEY, mergedConfig)\n}\n\n/**\n * 获取最近祖先 ConfigProvider 的当前配置。\n *\n * @returns 最近 Provider 的配置;没有 Provider 时返回 `undefined`。\n *\n * @example\n * ```ts\n * setup() {\n * const config = useConfigProviderContext()\n * return { config }\n * }\n * ```\n */\nexport function useConfigProviderContext(): SchemxConfig | undefined {\n return useConfigProviderContextRef()?.value\n}\n\n/**\n * 获取最近祖先 ConfigProvider 的响应式配置引用。\n *\n * 只能在 Vue 组件实例中读取;其他调用位置返回 `undefined`。\n *\n * @returns 最近 Provider 的响应式配置;没有组件实例或 Provider 时返回 `undefined`。\n *\n * @example\n * ```ts\n * setup() {\n * const config = useConfigProviderContextRef()\n * return { config }\n * }\n * ```\n */\nexport function useConfigProviderContextRef(): ComputedRef<SchemxConfig> | undefined {\n if (getCurrentInstance() === null) {\n return undefined\n }\n\n return inject(SCHEMX_CONFIG_PROVIDER_KEY, undefined)\n}\n","/**\n * 全局预设规则注册实例\n *\n * 模块级单例,由 ES Module 保证全局唯一。\n * UI 适配层通过 import 后调用 register/registerAll 注册自定义规则,\n * useForm 内部自动使用此实例作为 fallback。\n *\n * @module utils/presetRuleProvider\n */\n\nimport { createPresetRuleRegistry, type PresetRuleRegistry } from \"@schemx/core\"\n\n/**\n * 全局预设规则注册实例\n *\n * @example\n * ```ts\n * // 注册自定义规则\n * import { presetRuleRegistry } from '@schemx/vue'\n * presetRuleRegistry.register('phone', phoneRule)\n *\n * // useForm 内部自动使用\n * // props 传入的 presetRuleRegistry 优先级更高\n * ```\n */\nexport const presetRuleRegistry: PresetRuleRegistry = createPresetRuleRegistry()\n","/**\n * 全局渲染器注册实例\n *\n * 模块级单例,由 ES Module 保证全局唯一。\n * vant 等 UI 适配层通过 import 后调用 registerAll 注册渲染器,\n * useForm 内部自动使用此实例作为 fallback。\n *\n * @module utils/rendererProvider\n */\n\nimport { createRendererRegistry } from \"@schemx/core/adapter\"\n\n/**\n * 全局渲染器注册实例\n *\n * @example\n * ```ts\n * // UI 适配层注册渲染器\n * import { rendererRegistry } from '@schemx/vue'\n * rendererRegistry.registerAll({ input: InputRenderer, ... })\n *\n * // useForm 内部自动使用\n * // props 传入的 rendererRegistry 优先级更高\n * ```\n */\nexport const rendererRegistry = createRendererRegistry(\"input\")\n","/**\n * Vue 层 Form 配置合并。\n *\n * @module config/vueConfig\n */\n\nimport { getGlobalSchemxConfig, mergeConfig } from \"@schemx/core\"\n\nimport { useConfigProviderContext } from \"../context/configProviderContext\"\nimport { presetRuleRegistry as globalPresetRuleRegistry } from \"../utils/presetRuleProvider\"\nimport { rendererRegistry as globalRendererRegistry } from \"../utils/rendererProvider\"\n\nimport type { SchemxConfig, Values } from \"@schemx/core\"\n\n/**\n * 按优先级合并一个 Form 的显式配置、Provider/App 配置和 Core 全局配置。\n *\n * Core 内置默认值由后续 `createForm()` 补齐。\n *\n * @typeParam TValues - 用于关联 Renderer Props 的表单值类型。\n * @param localConfig - 当前 Form 或 useForm() 的显式配置。\n * @param fallbackConfig - Vue 层更低优先级的回退配置。\n * @returns 已合并 Provider、App、Core 全局配置和 Vue 默认 Registry 的配置。\n *\n * @example\n * ```ts\n * setup() {\n * const config = mergeVueSchemxConfig({\n * schemaConfig: { readonly: true },\n * })\n * return { config }\n * }\n * ```\n */\nexport function mergeVueSchemxConfig<TValues extends Values = Values>(\n localConfig: SchemxConfig<TValues>,\n fallbackConfig: SchemxConfig<TValues> = {}\n): SchemxConfig<TValues> {\n const providerConfig = useConfigProviderContext()\n\n const coreConfig = getGlobalSchemxConfig() as SchemxConfig<TValues>\n\n return mergeConfig<TValues>(\n localConfig,\n (providerConfig as SchemxConfig<TValues> | undefined) ?? {},\n fallbackConfig,\n coreConfig,\n {\n rendererRegistry: globalRendererRegistry,\n presetRuleRegistry: globalPresetRuleRegistry,\n }\n )\n}\n","/**\n * Vue 适配层的字段展示默认值。\n *\n * Vue 层拥有字段展示与布局默认值;Core 只处理框架无关的字段状态和校验默认值。\n */\nexport const defaultVueSchemaConfig = Object.freeze({\n /**\n * 表单级标签图标默认值。\n */\n labelIcon: \"\",\n /**\n * 表单级标签对齐默认值。\n */\n labelAlign: \"right\",\n /**\n * 表单级标签位置默认值。\n */\n labelPosition: \"left\",\n /**\n * 表单级标签宽度默认值。\n */\n labelWidth: \"auto\",\n /**\n * 表单级内容对齐默认值。\n */\n contentAlign: \"left\",\n /**\n * 表单级校验错误对齐默认值。\n */\n errorAlign: \"left\",\n /**\n * 表单级标签冒号默认值。\n */\n colon: true,\n /**\n * 表单级必填标记默认值。\n */\n showRequiredMark: undefined as boolean | undefined,\n\n /**\n * 字段默认 Col 配置。\n */\n col: { span: 24 },\n\n /**\n * 旧版字段默认布局配置。\n *\n * @deprecated 请改用 {@link import(\"../types/layout\").SchemxColConfig} 与 `col` 字段。\n */\n layout: { span: 24 },\n\n /**\n * 是否在 field schema 后显示底部边框。\n */\n bordered: true,\n} as const)\n\n/**\n * Vue 展示默认配置的键集合。\n */\nexport const defaultVueSchemaConfigKeys = Object.keys(\n defaultVueSchemaConfig\n) as (keyof typeof defaultVueSchemaConfig)[]\n","/**\n * useForm - Schemx 表单实例的 Vue 生命周期适配。\n *\n * 负责创建由当前 Vue effect scope 持有的 SchemxInstance,并在 scope 销毁时\n * 自动释放实例。该模块不负责 provide/inject;表单上下文统一由\n * provideFormContext() 注册,避免外部传入 form 时跳过上下文注册。\n *\n * @module hooks/useForm\n */\nimport { onScopeDispose } from \"vue\"\n\nimport { createForm } from \"@schemx/core\"\n\nimport { useVueFormRuntime } from \"../bridge\"\nimport { mergeVueSchemxConfig } from \"../config\"\n\nimport type {\n CreateFormOptions,\n SchemxConfig,\n SchemxInstance,\n Values,\n} from \"@schemx/core\"\n\n/**\n * 创建由当前 Vue effect scope 持有的表单实例。\n *\n * useForm 只负责以下职责:\n * 1. 合并表单显式、组件树 Provider、App 安装和 Vue 层默认配置;\n * 2. 同步创建 SchemxInstance;\n * 3. 在当前 effect scope 销毁时调用 instance.destroy()。\n *\n * useForm 不再自动调用 provide()。需要向后代组件暴露实例时,应由\n * <SchemxForm> 或其他 Provider 组件显式调用 provideFormContext({ form, schemaConfig })。\n * 这样无论实例是内部创建还是通过 props.form 外部传入,都能走同一条\n * 上下文注册路径,并保持清晰的实例所有权:谁创建,谁销毁。\n *\n * 该函数应在组件 setup() 或其他有效的 Vue effect scope 中同步调用。\n * 非 Vue 生命周期场景请直接使用 @schemx/core 的 createForm(),并自行销毁实例。\n *\n * @typeParam TValues - 表单值类型\n * @param options - 表单创建配置\n * @returns 当前 scope 持有的 SchemxInstance\n *\n * @example\n * ```ts\n * const form = useForm({\n * initialValues: {\n * name: \"\",\n * email: \"\",\n * },\n * onFinish: async (values) => {\n * await api.submit(values)\n * },\n * })\n *\n * form.setFieldValue(\"name\", \"Schemx\")\n * ```\n *\n * @example\n * ```ts\n * // Provider 组件中统一注册上下文。\n * const form = props.form ?? useForm(options)\n * provideFormContext({ form, schemaConfig: {} })\n * ```\n */\nexport function useForm<TValues extends Values = Values>(\n options: CreateFormOptions<TValues> = {}\n): SchemxInstance<TValues> {\n // 按表单、App、Vue 包默认值的优先级解析可继承配置。\n const configuredOptions = mergeVueSchemxConfig<TValues>(\n getUseFormSchemxConfig(options),\n {}\n )\n\n // 将已合并配置写入 Form 创建选项,避免 Core 再按较低优先级覆盖 Vue 结果。\n const mergedOptions: CreateFormOptions<TValues> = {\n ...options,\n ...configuredOptions,\n }\n\n // 表单实例是当前 scope 内的一次性资源,不需要使用 computed 包装。\n const instance = createForm<TValues>(mergedOptions)\n\n const form = useVueFormRuntime(instance).instance\n\n // useForm 创建的实例归当前 effect scope 所有,因此由当前 scope 负责销毁。\n onScopeDispose(() => {\n form.destroy()\n })\n\n return form\n}\n\n/**\n * 从 useForm 选项中提取需要参与 Vue 优先级计算的可继承配置。\n *\n * @param options - useForm 的完整创建选项。\n * @returns 仅包含调用方实际提供字段的 SchemxConfig。\n */\nfunction getUseFormSchemxConfig<TValues extends Values>(\n options: CreateFormOptions<TValues>\n): SchemxConfig<TValues> {\n const {\n schemaConfig = {},\n rendererProps = undefined,\n validatorAdapters = [],\n defaultRendererType = undefined,\n rendererRegistry = undefined,\n presetRuleRegistry = undefined,\n } = options\n\n return {\n schemaConfig,\n rendererProps,\n defaultRendererType,\n rendererRegistry,\n presetRuleRegistry,\n validatorAdapters,\n }\n}\n","/**\n * useField - 字段控制 Hook。\n *\n * 复用共享 Vue Runtime 的字段 Ref,并将 Core 的字段写入、校验和规则操作\n * 保持在原始 `createField()` 实例上。\n *\n * @module hooks/useField\n */\n\nimport { computed } from \"vue\"\n\nimport { createField } from \"@schemx/core\"\n\nimport { useFormContext, useFormRuntimeContext } from \"../context/formContext\"\n\nimport type { VueFieldState } from \"../bridge\"\nimport type { FieldInstance } from \"../types/field\"\nimport type { NamePath, SchemxInstance, Values } from \"@schemx/core\"\n\n/**\n * 创建一份字段控制器,并将所有读取状态投影到共享 Vue Field State。\n *\n * @typeParam TValues - 表单值类型。\n * @typeParam TName - 当前字段路径类型。\n * @param form - 当前响应式表单实例。\n * @param coreForm - 用于创建 Core 字段控制器的原始 Form。\n * @param name - 当前字段路径。\n * @param fieldState - 当前字段的共享 Vue 状态。\n * @returns 同时提供 Core 字段操作和 Vue Ref 状态的字段控制器。\n */\nfunction createFieldHook<\n TValues extends Values = Values,\n TName extends NamePath<TValues> = NamePath<TValues>,\n>(\n form: SchemxInstance<TValues>,\n coreForm: SchemxInstance<TValues>,\n name: TName,\n fieldState: VueFieldState<TValues, TName>\n): FieldInstance<TValues> {\n const coreField = createField<TValues>(coreForm, name)\n\n const errors = computed(() => fieldState.errors.value)\n\n const dirty = computed(() => fieldState.touched.value)\n\n const pending = computed(() => fieldState.pending.value)\n\n const getValue = (): ReturnType<typeof coreField.getValue> => fieldState.value.value\n\n const getErrors = (): ReturnType<typeof coreField.getErrors> => fieldState.errors.value\n\n const isTouched = (): boolean => fieldState.touched.value\n\n const isPending = (): boolean => fieldState.pending.value\n\n const getValues = (): Readonly<TValues> => form.getFieldsValue()\n\n return {\n ...coreField,\n name,\n value: fieldState.value,\n errors,\n dirty,\n pending,\n getValue,\n getErrors,\n isTouched,\n isPending,\n getValues,\n }\n}\n\n/**\n * 获取单个字段的控制能力。\n *\n * @typeParam TValues - 表单值类型。\n * @param name - 字段路径(支持嵌套字段)。\n * @returns 包含 Vue Ref 状态和 Core 字段操作的控制器。\n *\n * @example\n * ```ts\n * const field = useField(\"email\")\n * field.value.value = \"user@example.com\"\n * ```\n */\nexport const useField = <TValues extends Values = Values>(\n name: NamePath<TValues>\n): FieldInstance<TValues> => {\n const form = useFormContext<TValues>()\n\n const runtime = useFormRuntimeContext<TValues>()\n\n const fieldState = runtime.getFieldState(name)\n\n return createFieldHook(form, runtime.instance, name, fieldState)\n}\n\nexport default useField\n","/**\n * useWatch - 监听字段变化(Vue 组合式 API 版本)\n *\n * 基于 core 层的 {@link createWatch} 实现,\n * 自动通过 `useFormContext` 获取 formContext,\n * 并在 `onUnmounted` 时自动取消监听,无需手动管理生命周期。\n *\n * 提供三种监听模式:\n * - 全局监听:`useWatch(callback, options?)` — 监听表单中任意字段变化\n * - 单字段监听:`useWatch(name, callback, options?)` — 监听指定字段变化\n * - 多字段监听:`useWatch(names, callback, options?)` — 监听一组字段变化\n *\n * 同时提供语义化的便捷方法:\n * - {@link useWatchField} — 单字段监听\n * - {@link useWatchFields} — 多字段监听\n * - {@link useWatchAll} — 全局监听\n *\n * @module hooks/useWatch\n *\n * @example\n * ```ts\n * // 全局监听\n * useWatch((snapshot, payload) => {\n * console.log('form changed:', snapshot, payload)\n * })\n *\n * // 单字段监听\n * useWatch('username', (current, prev) => {\n * console.log('username changed:', prev, '->', current)\n * }, { immediate: true })\n *\n * // 多字段监听\n * useWatch(['firstName', 'lastName'], (currentValues, prevValues) => {\n * console.log('name changed:', currentValues)\n * }, { inequality: true })\n * ```\n */\n\nimport { onUnmounted } from \"vue\"\n\nimport { createWatch } from \"@schemx/core\"\n\nimport { useFormRuntimeContext } from \"../context/formContext\"\n\nimport type { NamePath, Values } from \"@schemx/core\"\nimport type {\n CreateWatchOptions,\n WatchAllCallback,\n WatchFieldCallback,\n WatchFieldsCallback,\n} from \"@schemx/core\"\n\n/**\n * 监听所有字段变化\n *\n * @typeParam TValues - 表单值类型。\n * @param callback - 全局变化回调;payload 为 `{ changedPaths, changedValues, prevValues }`\n * @param options - 监听选项\n * @returns 取消监听函数\n *\n * @example\n * ```ts\n * const dispose = useWatch((values, payload) => {\n * const { changedPaths, changedValues, prevValues } = payload\n * console.log(changedPaths, changedValues, prevValues, values)\n * })\n * ```\n */\nexport function useWatch<TValues extends Values>(\n callback: WatchAllCallback<TValues>,\n options?: CreateWatchOptions\n): () => void\n/**\n * 监听单个字段变化\n *\n * @typeParam TValues - 表单值类型。\n * @param name - 字段路径\n * @param callback - 单字段变化回调;payload 为 `{ value, prevValue }`\n * @param options - 监听选项\n * @returns 取消监听函数\n *\n * @example\n * ```ts\n * useWatch(\"email\", (_values, payload) => {\n * console.log(payload.prevValue, payload.value)\n * })\n * ```\n */\nexport function useWatch<TValues extends Values>(\n name: NamePath<TValues>,\n callback: WatchFieldCallback<TValues>,\n options?: CreateWatchOptions\n): () => void\n/**\n * 监听多个字段变化\n *\n * @typeParam TValues - 表单值类型。\n * @param names - 字段路径数组\n * @param callback - 多字段变化回调;payload 为 `{ changedPaths, changedValues, prevValues }`\n * @param options - 监听选项\n * @returns 取消监听函数\n *\n * @example\n * ```ts\n * useWatch([\"firstName\", \"lastName\"], (_values, payload) => {\n * console.log(payload.changedPaths, payload.changedValues, payload.prevValues)\n * })\n * ```\n */\nexport function useWatch<TValues extends Values>(\n names: NamePath<TValues>[],\n callback: WatchFieldsCallback<TValues>,\n options?: CreateWatchOptions\n): () => void\n/**\n * useWatch 实现 — 获取 form 实例后委托给 core 层的 createWatch\n *\n * @typeParam TValues - 表单值类型。\n */\nexport function useWatch<TValues extends Values>(\n nameOrNamesOrCallback:\n NamePath<TValues> | NamePath<TValues>[] | WatchAllCallback<TValues>,\n callbackOrOptions?:\n WatchFieldCallback<TValues> | WatchFieldsCallback<TValues> | CreateWatchOptions,\n maybeOptions?: CreateWatchOptions\n): () => void {\n const runtime = useFormRuntimeContext<TValues>()\n\n const dispose = (createWatch as any)(\n runtime.instance,\n nameOrNamesOrCallback,\n callbackOrOptions,\n maybeOptions\n )\n\n onUnmounted(dispose)\n\n return dispose\n}\n\n/**\n * 监听单个字段变化的便捷方法\n *\n * 等价于 `useWatch(name, callback, options)`,语义更明确。\n * 自动绑定 formContext 并在组件卸载时取消监听。\n *\n * @typeParam TValues - 表单值类型。\n * @param name - 要监听的字段路径\n * @param callback - 字段变化回调;payload 为 `{ value, prevValue }`\n * @param options - 可选配置\n * @returns 取消监听函数\n *\n * @example\n * ```ts\n * useWatchField(\"email\", (_values, payload) => {\n * const { value, prevValue } = payload\n * console.log(prevValue, value)\n * })\n * ```\n */\nexport function useWatchField<TValues extends Values = Values>(\n name: NamePath<TValues>,\n callback: WatchFieldCallback<TValues>,\n options?: CreateWatchOptions\n): () => void {\n return useWatch<TValues>(name, callback, options)\n}\n\n/**\n * 监听多个字段变化的便捷方法\n *\n * 等价于 `useWatch(names, callback, options)`,语义更明确。\n * 自动绑定 formContext 并在组件卸载时取消监听。\n *\n * @typeParam TValues - 表单值类型。\n * @param names - 要监听的字段路径数组\n * @param callback - 字段变化回调;payload 为 `{ changedPaths, changedValues, prevValues }`\n * @param options - 可选配置\n * @returns 取消监听函数\n *\n * @example\n * ```ts\n * useWatchFields([\"firstName\", \"lastName\"], (_values, payload) => {\n * const { changedPaths, changedValues, prevValues } = payload\n * console.log(changedPaths, changedValues, prevValues)\n * })\n * ```\n */\nexport function useWatchFields<TValues extends Values>(\n names: NamePath<TValues>[],\n callback: WatchFieldsCallback<TValues>,\n options?: CreateWatchOptions\n): () => void {\n return useWatch<TValues>(names, callback, options)\n}\n\n/**\n * 监听所有字段变化的便捷方法\n *\n * 等价于 `useWatch(callback, options)`,语义更明确。\n * 自动绑定 formContext 并在组件卸载时取消监听。\n *\n * @typeParam TValues - 表单值类型。\n * @param callback - 全局变化回调;payload 为 `{ changedPaths, changedValues, prevValues }`\n * @param options - 可选配置\n * @returns 取消监听函数\n *\n * @example\n * ```ts\n * useWatchAll((_values, payload) => {\n * const { changedPaths, changedValues, prevValues } = payload\n * console.log(changedPaths, changedValues, prevValues)\n * })\n * ```\n */\nexport function useWatchAll<TValues extends Values = Values>(\n callback: WatchAllCallback<TValues>,\n options?: CreateWatchOptions\n): () => void {\n return useWatch(callback, options)\n}\n\nexport default useWatch\n","/**\n * useDictionary - 字典选项 Hook\n *\n * 通过 api 函数加载字典选项,支持完整的表单值泛型推导。\n * 自动在组件挂载时加载,支持通过 dependsOn 声明依赖字段,\n * 当依赖字段变化时自动重新请求。\n *\n * @module hooks/useDictionary\n */\n\nimport { onMounted, onScopeDispose, Ref, ref, shallowRef } from \"vue\"\n\nimport type { SchemxDictionary } from \"@/types/dictionary\"\n\nimport { useFormContext } from \"../context/formContext\"\n\nimport { useWatchFields } from \"./useWatch\"\n\nimport type { NamePath, SchemxInstance, Values } from \"@schemx/core\"\n\nexport type { SchemxDictionary, SchemxWithDictionary } from \"@/types/dictionary\"\n\n/**\n * useDictionary 返回值。\n *\n * @typeParam TOption - 格式化后的字典选项类型。\n */\nexport interface UseDictionaryReturn<TOption = unknown> {\n /**\n * 远程加载的字典选项列表(响应式)\n */\n list: Ref<TOption[]>\n /**\n * 请求加载状态(响应式)\n */\n loading: Ref<boolean>\n /**\n * 请求错误信息(响应式)\n */\n error: Ref<Error | undefined>\n /**\n * 触发字典选项加载\n */\n loadDict: () => Promise<void>\n /**\n * 使用当前配置重新执行 api\n */\n refresh: () => Promise<void>\n /**\n * 直接修改 list 的值,不触发 api 调用\n */\n mutate: (data: TOption[]) => void\n}\n\n/**\n * useDictionary 返回值的旧类型别名。\n *\n * @deprecated 请改用 {@link UseDictionaryReturn}。\n * @typeParam TOption - 格式化后的字典选项类型。\n */\nexport type UseDictOptionsReturn<TOption = unknown> = UseDictionaryReturn<TOption>\n\n/**\n * 将未知抛出值规范化为 `Error` 实例\n *\n * @param err - 捕获的值(可能是任意类型)\n * @returns 包装原始值的 `Error` 对象\n *\n * @example\n * ```ts\n * const error = normalizeError(\"request failed\")\n * ```\n */\nexport function normalizeError(err: unknown): Error {\n if (err instanceof Error) return err\n\n return new Error(String(err))\n}\n\n/**\n * 加载字典选项\n *\n * 通过 api 函数获取数据,支持完整的表单值泛型推导。\n * 自动在组件挂载时加载,支持依赖字段联动、竞态控制、\n * 重试、错误处理等能力。\n *\n * @typeParam TValues - 表单值类型\n * @typeParam TName - 当前字段路径类型\n * @typeParam TResponse - api 的原始返回值类型\n * @typeParam TOption - 格式化后的字典选项类型\n * @param options - 字典配置选项\n * @param fieldName - 当前字段名,用于 resetOnDepsChange 时清空字段值\n * @returns `{ list, loading, error, loadDict, refresh, mutate }`:响应式选项、\n * 加载与错误状态,以及加载、刷新和本地更新方法\n *\n * @example\n * ```ts\n * // 基础用法\n * const { list, loading, error, loadDict, refresh, mutate } = useDictionary({\n * api: async () => {\n * const res = await fetch('/api/options')\n * return res.json()\n * },\n * })\n *\n * await loadDict() // 主动加载\n * await refresh() // 使用当前配置重新加载\n * mutate([{ label: \"手动选项\", value: \"manual\" }])\n * console.log(list.value, loading.value, error.value)\n *\n * // 依赖联动(带泛型)\n * const { list } = useDictionary<MyFormValues>({\n * api: async (values) => fetchCities(values.province),\n * dependsOn: ['province'],\n * shouldFetch: (values) => !!values.province,\n * resetOnDepsChange: true,\n * immediate: false,\n * }, 'city')\n * ```\n */\nexport const useDictionary = <\n TValues extends Values = Values,\n TName extends NamePath<TValues> = NamePath<TValues>,\n TResponse = unknown,\n TOption = unknown,\n>(\n options: SchemxDictionary<TValues, TResponse, TOption>,\n fieldName?: TName\n): UseDictionaryReturn<TOption> => {\n const instance = useFormContext<TValues>()\n\n const list = shallowRef<TOption[]>([])\n\n const loading = ref<boolean>(false)\n\n const error = ref<Error | undefined>(undefined)\n\n // 竞态控制:仅最新请求写入状态\n let requestCount = 0\n\n let activeController: AbortController | null = null\n\n /**\n * 使用配置的 formatter 格式化原始响应数据\n *\n * @param res - api 返回的原始数据。\n * @returns 可供 Renderer 使用的选项列表。\n */\n const format = async (res: Awaited<TResponse>): Promise<TOption[]> => {\n if (typeof options?.formatter === \"function\") {\n return await options.formatter(res, instance)\n }\n\n if (!Array.isArray(res)) {\n throw new Error(\n \"[schemx] Dictionary api must return an array when formatter is not provided.\"\n )\n }\n\n return res as TOption[]\n }\n\n /**\n * 带重试的执行\n *\n * @param formValues - 当前表单值快照。\n * @param signal - 用于中止当前请求或重试等待的信号。\n * @returns api 返回的原始数据。\n */\n const executeWithRetry = async (\n formValues: TValues,\n signal: AbortSignal\n ): Promise<Awaited<TResponse>> => {\n const maxRetries = options.retryCount ?? 0\n\n const retryDelay = options.retryInterval ?? 1000\n\n let lastError: Error = new Error(\"Unknown error\")\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n if (signal.aborted) {\n throw new Error(\"Dictionary request aborted\")\n }\n\n return await callDictionaryApi(formValues, instance, options.api, signal)\n } catch (err) {\n lastError = normalizeError(err)\n\n if (attempt < maxRetries) {\n await waitForRetry(retryDelay, signal)\n }\n }\n }\n\n throw lastError\n }\n\n /**\n * 执行 api 函数加载字典选项\n *\n * 只有最后一次请求可以写入响应式状态;组件卸载或新请求开始时,旧请求会被忽略。\n */\n const loadDict = async (): Promise<void> => {\n const currentCount = ++requestCount\n\n activeController?.abort()\n\n const controller = new AbortController()\n\n activeController = controller\n\n try {\n const formValues = instance.getFieldsSnapshot()\n\n // shouldFetch 检查\n if (typeof options.shouldFetch === \"function\" && !options.shouldFetch(formValues)) {\n list.value = []\n loading.value = false\n\n return\n }\n\n loading.value = true\n error.value = undefined\n\n const res = await executeWithRetry(formValues, controller.signal)\n\n // 竞态检查:丢弃过期响应\n if (currentCount !== requestCount || controller.signal.aborted) return\n\n const formatted = await format(res)\n\n // 格式化后再次竞态检查(格式化可能是异步的)\n if (currentCount !== requestCount || controller.signal.aborted) return\n\n list.value = formatted\n error.value = undefined\n\n // onSuccess 回调\n if (typeof options.onSuccess === \"function\") {\n options.onSuccess(formatted, instance)\n }\n\n loading.value = false\n } catch (err) {\n if (controller.signal.aborted || currentCount !== requestCount) {\n return\n }\n\n const normalized = normalizeError(err)\n\n error.value = normalized\n list.value = []\n loading.value = false\n\n if (typeof options.onError === \"function\") {\n options.onError(normalized, instance)\n }\n } finally {\n if (activeController === controller) {\n activeController = null\n }\n }\n }\n\n // 使用当前配置重新执行一次字典请求。\n const refresh = (): Promise<void> => loadDict()\n\n // 直接替换当前选项列表,不触发远程请求。\n const mutate = (data: TOption[]): void => {\n list.value = data\n }\n\n // ========== 依赖字段监听 ==========\n if (options.dependsOn?.length) {\n useWatchFields(\n options.dependsOn,\n (latestSnapshot, _payload) => {\n // 1. 触发 onDepsChange 回调\n if (typeof options.onDepsChange === \"function\") {\n options.onDepsChange(latestSnapshot as TValues, instance)\n }\n\n // 2. 清空当前字段值\n if (options.resetOnDepsChange && fieldName) {\n instance.setFieldValue(fieldName, undefined)\n }\n\n // 3. 重新执行 api\n void loadDict()\n },\n { inequality: true }\n )\n }\n\n // ========== 挂载行为 ==========\n const immediate = options.immediate ?? true\n\n onMounted(() => {\n if (immediate) {\n void loadDict()\n }\n })\n\n onScopeDispose(() => {\n requestCount += 1\n activeController?.abort()\n activeController = null\n })\n\n return { list, loading, error, loadDict, refresh, mutate }\n}\n\n/**\n * 可响应 AbortSignal 的重试等待。\n *\n * @param delay - 等待时长,单位为毫秒。\n * @param signal - 中止等待的 AbortSignal。\n * @returns 等待完成后 resolve;中止时 reject。\n */\nfunction waitForRetry(delay: number, signal: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n let abort = (): void => {}\n\n const cleanup = (): void => {\n clearTimeout(timeoutId)\n signal.removeEventListener(\"abort\", abort)\n }\n\n const complete = (): void => {\n cleanup()\n resolve()\n }\n\n const timeoutId = setTimeout(complete, delay)\n\n abort = (): void => {\n cleanup()\n reject(new Error(\"Dictionary request aborted\"))\n }\n\n if (signal.aborted) {\n abort()\n\n return\n }\n\n signal.addEventListener(\"abort\", abort, { once: true })\n })\n}\n\n/**\n * 兼容旧的两参数字典 API;显式声明第三参数时才传入 AbortSignal。\n *\n * @param values - 当前表单值快照。\n * @param form - 当前表单实例。\n * @param api - 字典数据获取函数。\n * @param signal - 当前请求的 AbortSignal。\n * @returns api 的同步或异步返回值。\n */\nfunction callDictionaryApi<TValues extends Values, TResponse>(\n values: TValues,\n form: SchemxInstance<TValues>,\n api: SchemxDictionary<TValues, TResponse>[\"api\"],\n signal: AbortSignal\n): TResponse | Promise<TResponse> {\n if (api.length >= 3) {\n return api(values, form, signal)\n }\n\n return api(values, form)\n}\n\nexport default useDictionary\n","/**\n * 对象浅比较工具\n *\n * @module utils/equal\n */\n\n/**\n * 浅比较两个对象的自有属性值是否相同。\n *\n * 用于避免 computed / shallowRef 每次返回新对象引用导致子组件不必要的更新。\n * 仅比较第一层属性,函数引用通过 === 判断。\n *\n * @param a - 旧对象\n * @param b - 新对象\n *\n * @returns 两个对象浅相等时返回 true\n *\n * @example\n * isShallowEqual({ a: 1, b: 2 }, { a: 1, b: 2 }) // => true\n * isShallowEqual({ a: 1 }, { a: 1, b: 2 }) // => false\n */\nexport const isShallowEqual = (\n a: Record<string, any>,\n b: Record<string, any>\n): boolean => {\n const keysA = Object.keys(a)\n\n const keysB = Object.keys(b)\n\n if (keysA.length !== keysB.length) return false\n\n return keysA.every((key) => a[key] === b[key])\n}\n","/**\n * useStableRef - 引用稳定化的 shallowRef\n *\n * 封装 `shallowRef` + `watchEffect` + `isShallowEqual`,\n * 仅在工厂函数返回值与当前值浅不相等时才更新引用,\n * 避免下游组件因对象引用变化而不必要地重渲染。\n *\n * @module hooks/useStableRef\n *\n * @example\n * ```ts\n * import { useStableRef } from '@schemx/vue'\n *\n * const stableProps = useStableRef(() => ({\n * visible: visible.value,\n * disabled: disabled.value,\n * value: field.getValue(),\n * }))\n * ```\n */\n\nimport { type ShallowRef, shallowRef, watchEffect } from \"vue\"\n\nimport { isShallowEqual } from \"../utils/equal\"\n\n/**\n * 创建一个引用稳定的 shallowRef。\n *\n * 在 watchEffect 中执行工厂函数,自动追踪响应式依赖。\n * 仅当新旧值浅比较不相等时才替换 `.value`,保持引用稳定。\n *\n * @typeParam TValue - 需要保持引用稳定的对象类型\n *\n * @param factory - 返回目标对象的工厂函数,在 watchEffect 内执行\n *\n * @returns 只读的 ShallowRef,引用仅在属性值真正变化时更新\n *\n * @example\n * ```ts\n * const props = useStableRef(() => ({\n * value: field.getValue(),\n * onChange: handleChange,\n * }))\n *\n * // props.value 的引用在属性值未变时保持不变\n * h(Component, props.value)\n * ```\n */\nexport function useStableRef<TValue extends Record<string, any>>(\n factory: () => TValue\n): Readonly<ShallowRef<TValue>> {\n const stableRef = shallowRef({} as TValue) as ShallowRef<TValue>\n\n watchEffect(() => {\n const next = factory()\n\n if (!isShallowEqual(stableRef.value, next)) {\n stableRef.value = next\n }\n })\n\n return stableRef\n}\n\nexport default useStableRef\n","/**\n * useViewSchemas - Vue ViewSchema 状态读取。\n *\n * ViewSchema 投影由 Form Runtime 统一缓存和回收;Hook 只绑定当前 scope 的\n * Runtime owner。\n *\n * @module hooks/useViewSchemas\n */\n\nimport { computed } from \"vue\"\nimport type { ComputedRef, ShallowRef } from \"vue\"\n\nimport { useVueFormRuntime } from \"../bridge\"\n\nimport type { SchemxInstance, SchemxViewSchema, Values } from \"@schemx/core\"\n\n/**\n * 获取当前表单共享的 ViewSchema 列表。\n *\n * @typeParam TValues - 表单值类型。\n * @param form - 要读取 ViewSchema 的表单实例。\n * @returns 当前表单的响应式 ViewSchema 列表。\n *\n * @example\n * ```ts\n * const schemas = useViewSchemas(form)\n * console.log(schemas.value)\n * ```\n */\nexport function useViewSchemas<TValues extends Values = Values>(\n form: SchemxInstance<TValues>\n): ShallowRef<readonly SchemxViewSchema<TValues>[]> {\n const state = useVueFormRuntime(form).getViewSchemaState()\n\n return state.viewSchemas\n}\n\n/**\n * 获取当前 key 对应的共享 ViewSchema。\n *\n * @typeParam TValues - 表单值类型。\n * @param form - 要读取 ViewSchema 的表单实例。\n * @param getKey - 返回目标 ViewSchema key 的响应式函数。\n * @returns 当前 key 对应的 ViewSchema;不存在时为 `undefined`。\n *\n * @example\n * ```ts\n * const schema = useViewSchema(form, () => currentKey.value)\n * ```\n */\nexport function useViewSchema<TValues extends Values = Values>(\n form: SchemxInstance<TValues>,\n getKey: () => string\n): ComputedRef<SchemxViewSchema<TValues> | undefined> {\n const state = useVueFormRuntime(form).getViewSchemaState()\n\n const schema = computed(() => state.schemasByKey.value.get(getKey()))\n\n return schema\n}\n\nexport default useViewSchemas\n","/**\n * useFormSelector - Core 表单值的 Vue 响应式选择器桥接。\n *\n * @module hooks/useFormSelector\n */\n\nimport { readonly, shallowRef, watch } from \"vue\"\nimport type { ShallowRef } from \"vue\"\n\nimport { useVueFormRuntime } from \"../bridge\"\n\nimport type { SchemxInstance, Values } from \"@schemx/core\"\n\n/**\n * `useFormSelector` 的选中结果比较配置。\n */\nexport interface UseFormSelectorOptions<TSelected> {\n /**\n * 判断两次 selector 结果是否等价;返回 true 时保持当前 Ref 值。\n * 默认使用 `Object.is`。\n */\n equals?: (previous: TSelected, next: TSelected) => boolean\n\n /**\n * Vue watcher 的刷新时机;默认 `sync` 以保持现有表单同步语义。\n */\n flush?: \"sync\" | \"pre\" | \"post\"\n}\n\n/**\n * 将 Core 表单值按 selector 映射为 Vue 只读浅引用。\n *\n * selector 只应读取快照,不应通过快照修改表单值或调用表单写入方法。\n * `Readonly<TValues>` 仅表达顶层只读,嵌套字段应按不可变值使用;字段值需通过\n * `setFieldValue()` 或 `setFieldsValue()` 更新,才能触发后续计算。\n *\n * @typeParam TValues - 表单值类型。\n * @typeParam TSelected - selector 返回值类型。\n * @param form - 要订阅的表单实例。\n * @param selector - 从当前表单值快照派生结果的纯函数。\n * @param options - 选中结果的比较配置。\n * @returns selector 当前结果的 Vue 只读浅引用。\n *\n * @example\n * ```ts\n * const selectedName = useFormSelector(form, (values) => values.name)\n *\n * watchEffect(() => {\n * console.log(selectedName.value)\n * })\n * ```\n */\nexport function useFormSelector<TValues extends Values = Values, TSelected = unknown>(\n form: SchemxInstance<TValues>,\n selector: (values: Readonly<TValues>) => TSelected,\n options: UseFormSelectorOptions<TSelected> = {}\n): Readonly<ShallowRef<TSelected>> {\n const values = useVueFormRuntime(form).getValuesRef()\n\n const selected = shallowRef<TSelected>(selector(values.value))\n\n const equals = options.equals ?? Object.is\n\n /**\n * 根据完整快照重新计算 selector,并只在结果变化时更新 Ref。\n *\n * @param values - Runtime 发布的最新完整表单快照。\n */\n watch(\n values,\n (values) => {\n const next = selector(values)\n\n if (!equals(selected.value, next)) {\n selected.value = next\n }\n },\n { flush: options.flush ?? \"sync\" }\n )\n\n return readonly(selected) as Readonly<ShallowRef<TSelected>>\n}\n\nexport default useFormSelector\n","/**\n * 校验触发工具\n *\n * 提供校验触发时机的合并、归一化和匹配判断功能。\n *\n * @module utils/validation\n */\n\nimport type { ValidationTrigger } from \"@schemx/core\"\n\n/**\n * 触发时机类型(支持单个或数组)\n */\nexport type TriggerConfig = ValidationTrigger | ValidationTrigger[]\n\n/**\n * 归一化后的触发类型\n */\nexport type NormalizedTrigger = \"blur\" | \"change\" | \"submit\"\n\n/**\n * 判断触发时机配置是否有效。\n *\n * undefined 和空数组视为无效,其余值(包括单个字符串、非空数组)视为有效。\n *\n * @param v - 触发时机配置\n *\n * @returns 配置有效时返回 true\n */\nfunction isValidTrigger(v: TriggerConfig | undefined): v is TriggerConfig {\n if (v === undefined) return false\n if (Array.isArray(v) && v.length === 0) return false\n\n return true\n}\n\n/**\n * 合并校验触发时机配置。\n *\n * 按优先级从高到低取值:列级配置 > 表单上下文配置 > 默认值。\n * 跳过 undefined 和空数组,确保空数组不会意外覆盖后续配置。\n *\n * @param columnTrigger - 列级配置的触发时机\n * @param contextTrigger - 表单上下文配置的触发时机\n * @param defaultTrigger - 兜底默认值\n *\n * @returns 最终生效的触发时机\n *\n * @example\n * mergeTrigger(\"onBlur\", \"onChange\", \"onSubmit\") // => \"onBlur\"\n * mergeTrigger(undefined, \"onChange\", \"onSubmit\") // => \"onChange\"\n * mergeTrigger([], \"onChange\", \"onSubmit\") // => \"onChange\"\n * mergeTrigger(undefined, undefined, \"onSubmit\") // => \"onSubmit\"\n */\nexport function mergeTrigger(\n columnTrigger: TriggerConfig | undefined,\n contextTrigger: TriggerConfig | undefined,\n defaultTrigger: TriggerConfig\n): TriggerConfig {\n if (isValidTrigger(columnTrigger)) return columnTrigger\n\n if (isValidTrigger(contextTrigger)) return contextTrigger\n\n return defaultTrigger\n}\n\n/**\n * 归一化触发类型字符串。\n *\n * 将带 `on` 前缀的格式统一为短格式:\n * `\"onBlur\"` → `\"blur\"`、`\"onChange\"` → `\"change\"`、`\"onSubmit\"` → `\"submit\"`。\n *\n * @param t - 原始触发类型\n *\n * @returns 归一化后的触发类型\n */\nfunction normalizeTrigger(t: ValidationTrigger): NormalizedTrigger {\n const map: Record<ValidationTrigger, NormalizedTrigger> = {\n onBlur: \"blur\",\n onChange: \"change\",\n onSubmit: \"submit\",\n blur: \"blur\",\n change: \"change\",\n submit: \"submit\",\n }\n\n return map[t] ?? \"submit\"\n}\n\n/**\n * 判断当前事件是否应该触发校验。\n *\n * 将配置的触发时机归一化后,与当前事件类型进行匹配。\n *\n * @param event - 当前触发的事件类型\n * @param trigger - 配置的触发时机(支持单个或数组)\n *\n * @returns 是否应该触发校验\n *\n * @example\n * shouldValidateOn(\"change\", \"onChange\") // => true\n * shouldValidateOn(\"blur\", [\"onBlur\", \"onChange\"]) // => true\n * shouldValidateOn(\"change\", \"onSubmit\") // => false\n * shouldValidateOn(\"change\", undefined) // => false\n */\nexport function shouldValidateOn(\n event: NormalizedTrigger,\n trigger?: TriggerConfig\n): boolean {\n if (!trigger) return false\n const triggers = Array.isArray(trigger) ? trigger : [trigger]\n\n return triggers.some((t) => normalizeTrigger(t) === event)\n}\n","/**\n * 插槽解析与子插槽提取工具。\n *\n * 提供 camelCase / kebab-case 双向查找插槽,\n * 以及按字段名前缀提取子渲染器插槽。\n *\n * @module utils/slot\n */\n\n/**\n * 检查字符串是否包含大写字母(驼峰格式特征)。\n *\n * @param str - 待检测的字符串\n * @returns 是否包含大写字母\n */\nconst isCamelCase = (str: string): boolean => /[A-Z]/.test(str)\n\n/**\n * 检查字符串是否包含连字符(kebab-case 特征)。\n *\n * @param str - 待检测的字符串\n * @returns 是否包含连字符\n */\nconst isKebabCase = (str: string): boolean => str.includes(\"-\")\n\n/**\n * 将驼峰命名转换为连字符命名(kebab-case)。\n *\n * @param str - 驼峰格式的字符串\n * @returns 转换后的 kebab-case 字符串\n */\nconst camelToKebab = (str: string): string => {\n return str.replace(/([A-Z])/g, \"-$1\").toLowerCase()\n}\n\n/**\n * 将连字符命名转换为驼峰命名(camelCase)。\n *\n * @param str - kebab-case 格式的字符串\n * @returns 转换后的 camelCase 字符串\n */\nconst kebabToCamel = (str: string): string => {\n return str.replace(/-([a-z])/g, (_match, letter) => letter.toUpperCase())\n}\n\n/**\n * 将命名格式归一化为 kebab-case。\n *\n * @param str - 任意命名格式的字符串\n * @returns kebab-case 格式的字符串\n */\nconst normalizeToKebab = (str: string): string => {\n if (isCamelCase(str)) return camelToKebab(str)\n\n return str\n}\n\n/**\n * 将命名格式归一化为 camelCase。\n *\n * @param str - 任意命名格式的字符串\n * @returns camelCase 格式的字符串\n */\nconst normalizeToCamel = (str: string): string => {\n if (isKebabCase(str)) return kebabToCamel(str)\n\n return str\n}\n\n/**\n * 从插槽对象中按名称查找插槽,同时支持 camelCase 和 kebab-case。\n *\n * 优先查找原始名称,未找到时尝试另一种命名格式。\n * 例如传入 `userName` 时,先查 `userName`,再查 `user-name`;\n * 传入 `user-name` 时,先查 `user-name`,再查 `userName`。\n *\n * @param slots - Vue 插槽对象\n * @param name - 插槽名称(camelCase 或 kebab-case)\n *\n * @returns 匹配的插槽函数,未找到返回 undefined\n *\n * @example\n * ```typescript\n * // slots 中定义了 'user-name' 插槽\n * resolveSlot(slots, 'userName') // => 找到 'user-name' 插槽\n * resolveSlot(slots, 'user-name') // => 找到 'user-name' 插槽\n * ```\n */\nexport const resolveSlot = (\n slots: Record<string, any>,\n name: string\n): ((...args: any[]) => any) | undefined => {\n if (slots[name]) return slots[name]\n\n const alt = isCamelCase(name)\n ? camelToKebab(name)\n : isKebabCase(name)\n ? kebabToCamel(name)\n : undefined\n\n if (alt && slots[alt]) return slots[alt]\n\n return undefined\n}\n\n/**\n * 从父级插槽中提取子渲染器插槽。\n *\n * 按 `fieldName:slotName` 和 `fieldName:slot-name` 格式匹配,\n * 提取后去掉前缀作为子渲染器的插槽名。\n * 同时支持 camelCase 和 kebab-case 的 fieldName。\n *\n * @param fieldName - 字段名\n * @param allSlots - 父级全部插槽\n *\n * @returns 子渲染器的插槽对象\n *\n * @example\n * ```typescript\n * // 父级插槽: { 'userName:prefix': fn, 'userName:suffix': fn, 'userNameLabel': fn }\n * extractChildSlots('userName', slots)\n * // => { prefix: fn, suffix: fn }\n * ```\n */\nexport const extractChildSlots = (\n fieldName: string,\n allSlots: Record<string, any>\n): Record<string, any> => {\n const result: Record<string, any> = {}\n\n const camelPrefix = normalizeToCamel(String(fieldName)) + \":\"\n\n const kebabPrefix = normalizeToKebab(String(fieldName)) + \":\"\n\n for (const [key, value] of Object.entries(allSlots)) {\n if (key.startsWith(camelPrefix)) {\n result[key.slice(camelPrefix.length)] = value\n } else if (key.startsWith(kebabPrefix) && kebabPrefix !== camelPrefix) {\n result[key.slice(kebabPrefix.length)] = value\n }\n }\n\n return result\n}\n","/**\n * Vue 渲染层使用的 Schema 位置与 DOM key 辅助函数。\n *\n * @module utils/helpers\n */\n\nimport { isViewGroupSchema, SchemxViewSchema } from \"@schemx/core\"\n\n/**\n * 判断当前项是否为顶层可见普通字段所在区段的第一个或最后一个。\n *\n * 可见 Group 是区段边界;不可见字段和不可见 Group 不参与计算。\n *\n * 使用示例:\n *\n * const list = [\n * { key: 'group-1', children: [] },\n * { key: 'a' },\n * { key: 'b' },\n * { key: 'group-2', children: [] },\n * { key: 'c' },\n * ]\n *\n * getSectionPosition(list, 'a')\n * // => { found: true, isFirst: true, isLast: false }\n *\n * @param list - 当前层级的 ViewSchema 列表。\n * @param currentKey - 要定位的 ViewSchema key。\n * @returns 当前项是否存在以及它在所在区段中的首尾位置。\n */\nexport function getSectionPosition<TItem extends SchemxViewSchema>(\n list: TItem[],\n currentKey: string\n) {\n const currentIndex = list.findIndex((item) => item.key === currentKey)\n\n if (currentIndex === -1) {\n return {\n found: false,\n isFirst: false,\n isLast: false,\n }\n }\n\n const currentItem = list[currentIndex]\n\n if (!isPositionItem(currentItem)) {\n return {\n found: true,\n isFirst: false,\n isLast: false,\n }\n }\n\n return {\n found: true,\n isFirst: !hasPositionItemInSection(list, currentIndex, -1),\n isLast: !hasPositionItemInSection(list, currentIndex, 1),\n }\n}\n\n/**\n * 将 NamePath 转换为整体字段与 Renderer 子插槽使用的键。\n *\n * @param name - 字符串字段名或由路径片段组成的字段名。\n * @returns 使用点号连接的稳定字段键。\n *\n * @example\n * ```ts\n * normalizeNameKey([\"user\", \"name\"]) // \"user.name\"\n * ```\n */\nexport function normalizeNameKey(name: unknown): string {\n if (Array.isArray(name)) {\n return name.map((part) => String(part)).join(\".\")\n }\n\n return String(name)\n}\n\n/**\n * 将分组 key 转换为可用于 DOM ID 的安全字符串。\n *\n * @param key - Schema 或 Group 的原始 key。\n * @returns 仅包含字母、数字、下划线和连字符的字符串。\n *\n * @example\n * ```ts\n * normalizeId(\"address.city\") // \"address-city\"\n * ```\n */\nexport function normalizeId(key: string): string {\n return String(key).replace(/[^a-zA-Z0-9_-]/g, \"-\")\n}\n\n/**\n * 判断项是否为参与区段首尾计算的可见普通字段。\n *\n * @param item - 待判断的 ViewSchema。\n * @returns 项存在、可见且不是 Group 时返回 `true`。\n */\nfunction isPositionItem<TItem extends SchemxViewSchema>(item?: TItem) {\n return !!item && !isViewGroupSchema(item) && item.visible !== false\n}\n\n/**\n * 从当前项向指定方向查找同一区段内的可定位字段。\n *\n * @param list - 当前层级的 ViewSchema 列表。\n * @param startIndex - 当前项的索引。\n * @param step - 向前或向后查找的步长。\n * @returns 找到同一区段中的可见普通字段时返回 `true`。\n */\nfunction hasPositionItemInSection<TItem extends SchemxViewSchema>(\n list: TItem[],\n startIndex: number,\n step: 1 | -1\n): boolean {\n for (let index = startIndex + step; index >= 0 && index < list.length; index += step) {\n const item = list[index]\n\n if (item.visible === false) {\n continue\n }\n\n if (isViewGroupSchema(item)) {\n return false\n }\n\n if (isPositionItem(item)) {\n return true\n }\n }\n\n return false\n}\n","/**\n * Vue 布局间距工具。\n *\n * @module utils/layout\n */\n\nimport type { SchemxGutter } from \"../types/layout\"\n\n/** 归一化后的上、右、下、左间距。 */\nexport type SchemxNormalizedGutter = readonly [number, number, number, number]\n\n/**\n * 将 CSS padding shorthand 形式的 gutter 归一化为四边值。\n *\n * @param gutter - 单值、上下/左右二元组或上/右/下/左四元组。\n * @returns 上、右、下、左四边值。\n *\n * @example\n * ```ts\n * normalizeSchemxGutter(8) // => [8, 8, 8, 8]\n * normalizeSchemxGutter([4, 12]) // => [4, 12, 4, 12]\n * ```\n */\nexport function normalizeSchemxGutter(\n gutter: SchemxGutter | undefined\n): SchemxNormalizedGutter {\n if (gutter === undefined) {\n return [0, 0, 0, 0]\n }\n\n if (typeof gutter === \"number\") {\n return [gutter, gutter, gutter, gutter]\n }\n\n if (gutter.length === 2) {\n const [vertical, horizontal] = gutter\n\n return [vertical, horizontal, vertical, horizontal]\n }\n\n return gutter\n}\n","/**\n * Col - Schema 布局列包装组件。\n *\n * 将 Field 的静态 col 元数据转换为配置 UI 组件的 `span` 与 `offset` Props;\n * 未传入组件时使用 Vue 层内置的 24 栅格 Col 实现。\n *\n * @module components/Col\n */\n\nimport { computed, defineComponent, h, markRaw, type PropType, toRaw } from \"vue\"\nimport type { ClassValue, StyleValue, VNodeChild } from \"vue\"\n\nimport { useOptionalFormContextValue } from \"../../context/formContext\"\n\nimport type {\n SchemxColComponent,\n SchemxColConfig,\n SchemxLayout,\n} from \"../../types/layout\"\n\nconst Col = defineComponent({\n name: \"SchemxCol\",\n inheritAttrs: false,\n\n props: {\n col: {\n type: Object as PropType<SchemxColConfig>,\n required: false,\n default: undefined,\n },\n /**\n * @deprecated 请在 Form 或 ConfigProvider 的 `colComponent` 中配置实现,见 {@link import(\"@schemx/core\").SchemxConfig}。\n */\n component: {\n type: [Object, Function] as PropType<SchemxColComponent>,\n required: false,\n default: undefined,\n },\n /**\n * @deprecated 请改用 {@link import(\"../../types/layout\").SchemxColProps.col}。\n */\n layout: {\n type: Object as PropType<SchemxLayout>,\n required: false,\n default: undefined,\n },\n },\n\n /**\n * 根据 Col 配置和当前 Form Context 创建列组件。\n *\n * @param props - 列配置及兼容期的组件覆写属性。\n * @param setupContext - 父级透传属性与默认插槽。\n */\n setup(props, setupContext) {\n const { attrs, slots } = setupContext\n\n const formContext = useOptionalFormContextValue()\n\n const resolvedComponent = computed(() => {\n const component = props.component ?? formContext?.colComponent\n\n return component ? markRaw(toRaw(component)) : undefined\n })\n\n return (): VNodeChild => {\n const component = resolvedComponent.value\n\n const col = props.col ?? props.layout ?? {}\n\n const {\n block,\n span: configuredSpan,\n offset: configuredOffset,\n ...extensionProps\n } = col\n\n const span = block ? 24 : (configuredSpan ?? 24)\n\n const offset = block ? 0 : (configuredOffset ?? 0)\n\n const { class: attrsClass, style: attrsStyle, ...restAttrs } = attrs\n\n if (!component) {\n const width = `${(span / 24) * 100}%`\n\n const marginLeft = `${(offset / 24) * 100}%`\n\n return h(\n \"div\",\n {\n ...restAttrs,\n class: [\"schemx-col\", attrsClass as ClassValue],\n style: [\n attrsStyle as StyleValue,\n {\n flex: `0 0 ${width}`,\n maxWidth: width,\n marginLeft,\n paddingTop: \"var(--schemx-gutter-top, 0px)\",\n paddingRight: \"var(--schemx-gutter-right, 0px)\",\n paddingBottom: \"var(--schemx-gutter-bottom, 0px)\",\n paddingLeft: \"var(--schemx-gutter-left, 0px)\",\n },\n ],\n },\n slots\n )\n }\n\n return h(\n component,\n {\n ...extensionProps,\n ...restAttrs,\n class: [\"schemx-col\", attrsClass as ClassValue],\n style: attrsStyle as StyleValue,\n span,\n offset,\n },\n slots\n )\n }\n },\n})\n\nexport default Col\n","/**\n * Icon 包装组件。\n *\n * 它允许 Schema 使用可序列化的字符串图标名称,也允许 Form 配置传入 Vue 组件。\n *\n * @module components/Icon\n */\n\nimport { defineComponent, h, markRaw, toRaw, useAttrs } from \"vue\"\nimport type { PropType } from \"vue\"\n\nimport type { SchemxIconComponent, SchemxIconValue } from \"../../types/icon\"\n\nconst Icon = defineComponent({\n name: \"SchemxIcon\",\n inheritAttrs: false,\n\n props: {\n icon: {\n type: [String, Object, Function] as PropType<SchemxIconValue>,\n required: true,\n },\n component: {\n type: [Object, Function] as PropType<SchemxIconComponent>,\n required: false,\n default: undefined,\n },\n },\n\n /**\n * 渲染直接传入的组件,或将字符串名称交给 Icon Adapter。\n *\n * @param props - 当前图标值及可选的 Adapter 组件。\n */\n setup(props) {\n const attrs = useAttrs()\n\n return () => {\n if (typeof props.icon !== \"string\") {\n return h(markRaw(toRaw(props.icon)) as SchemxIconComponent, attrs)\n }\n\n const adapter = props.component\n\n if (adapter === undefined) {\n return h(\n \"span\",\n { ...attrs, class: [\"schemx-icon-text\", attrs.class] },\n props.icon\n )\n }\n\n return h(markRaw(toRaw(adapter)), { ...attrs, icon: props.icon })\n }\n },\n})\n\nexport default Icon\n","/**\n * Field 插槽渲染器。\n *\n * 集中处理字段各区域的插槽解析,保持 Field 仅负责字段状态和布局。\n *\n * @module components/Field/slot\n */\n\nimport { computed, h } from \"vue\"\nimport type { Component, ShallowRef, Slots, VNodeChild } from \"vue\"\n\nimport classnames from \"classnames\"\n\nimport { extractChildSlots, normalizeNameKey, resolveSlot } from \"../../utils\"\nimport Icon from \"../Icon\"\n\nimport type { FormConfigContextValue } from \"../../context/formContext\"\nimport type { FieldInstance } from \"../../types/field\"\nimport type {\n SchemxComponentProps,\n SchemxInstance,\n SchemxViewFieldSchema,\n Values,\n} from \"@schemx/core\"\n\n/**\n * Field 插槽渲染所需的状态与依赖。\n */\ninterface FieldSlotRendererOptions<TValues extends Values = Values> {\n /**\n * 当前字段 ViewSchema。\n */\n schemaRef: Readonly<ShallowRef<SchemxViewFieldSchema<TValues>>>\n /**\n * 当前字段的响应式控制器。\n */\n field: FieldInstance<TValues>\n /**\n * 当前表单实例,用于解析 Renderer。\n */\n form: SchemxInstance<TValues>\n /**\n * 表单级展示配置。\n */\n formContext: FormConfigContextValue\n /**\n * 传给 Renderer 的稳定属性。\n */\n componentProps: Readonly<ShallowRef<SchemxComponentProps<TValues>>>\n /**\n * 父组件传入的所有具名插槽。\n */\n slots: Slots\n}\n\n/**\n * 创建 Field 各区域的插槽渲染函数。\n *\n * 字段依次渲染 Before、主体(Label + Content)、Error、After。\n * Label 和 Error 插槽只替换各自容器内的内容。\n *\n * @param options - Field 插槽渲染所需的响应式状态和 Vue 插槽集合。\n * @returns 各字段区域的插槽渲染函数及统一 Slot Props 构造器。\n *\n * @example\n * ```ts\n * const renderers = createFieldSlotRenderers(options)\n * renderers.renderContent()\n * ```\n */\nexport function createFieldSlotRenderers<TValues extends Values = Values>(\n options: FieldSlotRendererOptions<TValues>\n) {\n const { schemaRef, field, form, formContext, componentProps, slots } = options\n\n const labelWidth = computed(() => {\n if (schemaRef.value.labelPosition === \"top\") {\n return \"100%\"\n }\n\n // 数值和纯数字字符串使用 px,保留带单位的 CSS 宽度。\n const width = schemaRef.value.labelWidth ?? \"auto\"\n\n return /^\\d+(?:\\.\\d+)?$/.test(String(width)) ? `${width}px` : width\n })\n\n const labelAlign = computed(() => {\n if (schemaRef.value.labelPosition === \"top\") {\n return \"left\"\n }\n\n return schemaRef.value.labelAlign\n })\n\n /**\n * 构造各字段插槽共用的规范上下文参数。\n *\n * @param additionalProps - 当前插槽额外携带的属性。\n * @returns 传给字段插槽的统一上下文对象。\n */\n const createSlotProps = (additionalProps: Record<string, unknown> = {}) => {\n return {\n schema: schemaRef.value,\n componentProps: componentProps.value,\n value: field.value.value,\n field,\n form,\n ...additionalProps,\n }\n }\n\n /**\n * 渲染指定后缀的字段区域插槽。\n *\n * @param suffix - 字段插槽名称后缀,例如 `Before` 或 `After`。\n * @returns 匹配插槽生成的 VNode;未匹配时返回空内容。\n */\n const renderFieldSlot = (suffix: string): VNodeChild => {\n const slot = resolveSlot(slots, `${normalizeNameKey(schemaRef.value.name)}${suffix}`)\n\n return slot?.(createSlotProps()) ?? null\n }\n\n /**\n * 渲染标签区域,优先使用 `{name}Label` 插槽。\n */\n const renderLabel = (): VNodeChild => {\n const labelSlot = resolveSlot(slots, `${normalizeNameKey(schemaRef.value.name)}Label`)\n\n const colon = schemaRef.value.colon ?? formContext.schemaConfig.colon\n\n // 必填标记使用 label-text 的伪类渲染,不再额外创建 DOM 节点。\n const showRequiredMark =\n (schemaRef.value.showRequiredMark ?? Boolean(schemaRef.value.required)) &&\n !schemaRef.value.disabled &&\n !schemaRef.value.readonly\n\n return (\n <label\n class=\"schemx-field__label\"\n style={{\n width: labelWidth.value,\n textAlign: labelAlign.value,\n marginLeft: labelAlign.value === \"right\" ? \"auto\" : \"\",\n }}\n >\n {labelSlot ? (\n labelSlot(createSlotProps())\n ) : (\n <>\n {schemaRef.value.labelIcon && (\n <span class=\"schemx-field__label-icon\">\n <Icon\n icon={schemaRef.value.labelIcon}\n component={formContext.iconComponent}\n />\n </span>\n )}\n <span\n class={classnames(\"schemx-field__label-text\", {\n \"is-required\": showRequiredMark,\n })}\n >\n {schemaRef.value.label}\n {colon ? \":\" : \"\"}\n </span>\n </>\n )}\n </label>\n )\n }\n\n /**\n * 渲染字段主体前的 `{name}Before` 插槽。\n */\n const renderBefore = (): VNodeChild => renderFieldSlot(\"Before\")\n\n /**\n * 渲染控件区域,优先使用 `{name}Content` 插槽。\n */\n const renderContent = (): VNodeChild => {\n const rendererEntry = form.getRendererEntry(schemaRef.value.componentType)\n\n if (!rendererEntry) {\n throw new Error(\n `[schemx] Can not find component renderer of \"${schemaRef.value.componentType}\".`\n )\n }\n\n const childSlots = extractChildSlots(normalizeNameKey(schemaRef.value.name), slots)\n\n const transformedProps = rendererEntry.transformProps\n ? rendererEntry.transformProps(componentProps.value, {\n schema: schemaRef.value,\n form,\n })\n : componentProps.value\n\n const columnElement = h(\n rendererEntry.component as Component,\n transformedProps,\n childSlots\n )\n\n const contentSlot = resolveSlot(\n slots,\n `${normalizeNameKey(schemaRef.value.name)}Content`\n )\n\n return (\n <div\n class=\"schemx-field__content\"\n style={{ textAlign: schemaRef.value.contentAlign }}\n >\n {contentSlot\n ? contentSlot(\n createSlotProps({\n columnElement,\n })\n )\n : columnElement}\n </div>\n )\n }\n\n /**\n * 渲染字段错误区域后的 `{name}After` 插槽。\n */\n const renderAfter = (): VNodeChild => renderFieldSlot(\"After\")\n\n /**\n * 渲染错误区域,优先使用 `{name}Error` 插槽。\n */\n const renderError = (): VNodeChild => {\n const errorSlot = resolveSlot(slots, `${normalizeNameKey(schemaRef.value.name)}Error`)\n\n if (!errorSlot && field.errors.value.length === 0) {\n return null\n }\n\n return (\n <div\n class=\"schemx-field__error\"\n style={{\n marginLeft:\n schemaRef.value?.labelPosition === \"top\"\n ? \"8px\"\n : `calc(${labelWidth.value} + var(--schemx-field-gap))`,\n }}\n >\n {errorSlot\n ? errorSlot(createSlotProps({ errors: field.errors.value }))\n : field.errors.value[0]}\n </div>\n )\n }\n\n return {\n createSlotProps,\n renderAfter,\n renderBefore,\n renderContent,\n renderError,\n renderLabel,\n }\n}\n","/**\n * Field\n *\n * schemx 实际渲染字段的组件。\n * 动态属性已由 core 解析到 ViewSchema 中;这里只负责消费\n * 已解析字段 schema、创建字段实例、组装渲染器属性与插槽。\n *\n * @module components/Field\n */\n\n/* eslint-disable vue/one-component-per-file */\nimport { computed, defineComponent, PropType } from \"vue\"\nimport type { ClassValue, SlotsType, StyleValue, VNodeChild } from \"vue\"\n\nimport { isSchemxViewFieldSchema } from \"@schemx/core\"\nimport classnames from \"classnames\"\n\nimport type { TriggerConfig } from \"@/utils\"\n\nimport { createFieldContext, useFormContextValue } from \"../../context\"\nimport { useField, useStableRef } from \"../../hooks\"\nimport { useViewSchema } from \"../../hooks/useViewSchemas\"\nimport {\n mergeTrigger,\n normalizeNameKey,\n resolveSlot,\n shouldValidateOn,\n} from \"../../utils\"\nimport Col from \"../Col\"\n\nimport { createFieldSlotRenderers } from \"./slot\"\n\nimport type { SchemxFieldSlots } from \"../../types/field\"\nimport type {\n FieldValue,\n NamePath,\n SchemxComponentProps,\n SchemxViewFieldSchema,\n Values,\n} from \"@schemx/core\"\n\n/**\n * Field 属性。\n *\n * 提供待渲染的字段 ViewSchema。\n */\nexport interface SchemxFieldProps {\n /**\n * 当前字段的已解析 ViewSchema。\n */\n schema: unknown\n /**\n * 追加到字段外层包装器的 CSS 类名。\n */\n class?: ClassValue\n /**\n * 追加到字段外层包装器的内联样式。\n */\n style?: StyleValue\n}\n\nconst Field = defineComponent({\n name: \"SchemxField\",\n inheritAttrs: false,\n\n props: {\n schema: {\n type: Object as PropType<unknown>,\n required: true,\n },\n class: {\n type: [String, Object, Array, Boolean] as PropType<ClassValue>,\n required: false,\n default: undefined,\n },\n style: {\n type: [String, Object, Array] as PropType<StyleValue>,\n required: false,\n default: undefined,\n },\n },\n\n slots: Object as SlotsType<SchemxFieldSlots>,\n\n /**\n * 初始化字段上下文,并组合响应式 schema、校验处理器与插槽渲染器。\n *\n * @param props - 当前字段项的 Schema、class 和 style。\n * @param setupContext - Vue setup 上下文,包含透传属性和字段插槽。\n */\n setup(props, setupContext) {\n const { attrs, slots } = setupContext\n\n const formContext = useFormContextValue<Values>()\n\n const form = formContext.form\n\n const inputSchema = computed<SchemxViewFieldSchema<Values>>(\n () => props.schema as SchemxViewFieldSchema<Values>\n )\n\n // 按 key 复用表单级 ViewSchema 订阅,避免每个 Field 建立独立 Core effect。\n const latestSchema = useViewSchema(form, () => inputSchema.value.key)\n\n // 优先使用桥接中的最新字段;首帧或字段暂不存在时回退到输入 schema。\n const schemaRef = computed<SchemxViewFieldSchema<Values>>(() => {\n return latestSchema.value && isSchemxViewFieldSchema(latestSchema.value)\n ? latestSchema.value\n : inputSchema.value\n })\n\n const field = useField(schemaRef.value.name)\n\n createFieldContext(field)\n\n const trigger = computed<TriggerConfig>(() =>\n mergeTrigger(\n schemaRef.value.validationTrigger,\n formContext.schemaConfig.validationTrigger,\n \"onChange\"\n )\n )\n\n /**\n * 是否需要进行校验。\n *\n * 当字段不可见、只读或禁用时,无需进行校验。\n */\n const canVerified = computed(() => {\n const isOperate =\n schemaRef.value.visible !== false &&\n !schemaRef.value.readonly &&\n !schemaRef.value.disabled\n\n // Core 负责判断当前字段是否有 Schema、兜底或手动规则;ViewSchema\n // 只包含声明规则,不能据此判断 fieldRules/setFieldRules 的存在。\n return isOperate\n })\n\n /**\n * 处理字段值变化,设置值后根据触发时机决定是否校验。\n *\n * @param v - 渲染器提交的最新字段值。\n */\n const handleChange = (v: FieldValue<Values, NamePath<Values>>) => {\n field.setValue(v)\n schemaRef.value.componentProps?.onChange?.(v)\n schemaRef.value.onChange?.(v, form)\n\n if (canVerified.value && shouldValidateOn(\"change\", trigger.value)) {\n field.validate()\n }\n }\n\n /**\n * 处理字段失焦,并根据触发时机决定是否校验。\n *\n * @param v - 触发失焦事件时对应的字段值。\n */\n const handleBlur = (v: FieldValue<Values, NamePath<Values>>) => {\n schemaRef.value.componentProps?.onBlur?.(v)\n schemaRef.value.onBlur?.(form)\n\n if (canVerified.value && shouldValidateOn(\"blur\", trigger.value)) {\n field.validate()\n }\n }\n\n /**\n * 处理组件的 v-model 更新,只同步字段值,不主动触发校验。\n *\n * @param v - 渲染器提交的最新字段值。\n */\n const updateValue = (v: FieldValue<Values, NamePath<Values>>) => {\n field.setValue(v)\n }\n\n // 使用 useStableRef 避免每次生成新对象引用\n const componentProps = useStableRef<SchemxComponentProps<Values>>(\n (): SchemxComponentProps<Values> => {\n const currentComponentProps = schemaRef.value.componentProps ?? {}\n\n return {\n ...currentComponentProps,\n value: field.value.value,\n onChange: handleChange,\n onBlur: handleBlur,\n \"onUpdate:value\": updateValue,\n }\n }\n )\n\n const {\n createSlotProps,\n renderAfter,\n renderBefore,\n renderContent,\n renderError,\n renderLabel,\n } = createFieldSlotRenderers({\n schemaRef,\n field,\n form,\n formContext,\n componentProps,\n slots,\n })\n\n return (): VNodeChild => {\n if (schemaRef.value.visible === false) {\n return null\n }\n\n // 整体插槽只替换标签和控件主体,Before、Error、After 仍由 wrapper 渲染。\n const fieldSlot = resolveSlot(slots, normalizeNameKey(schemaRef.value.name))\n\n const labelPosition = schemaRef.value.labelPosition\n\n const fieldContent = fieldSlot ? (\n fieldSlot(createSlotProps())\n ) : (\n <div\n class={classnames(\"schemx-field\", `schemx-field--label-${labelPosition}`, {\n \"is-readonly\": schemaRef.value.readonly,\n \"is-disabled\": schemaRef.value.disabled,\n })}\n >\n {renderLabel()}\n {renderContent()}\n </div>\n )\n\n const fieldWrapper = (\n <div\n {...attrs}\n class={classnames(\n \"schemx-field-wrapper\",\n props.class,\n attrs.class,\n schemaRef.value.class,\n schemaRef.value.bordered ? \"is-bordered\" : \"\"\n )}\n style={[\n attrs.style,\n props.style,\n schemaRef.value.style,\n {\n \"--schemx-content-align\": schemaRef.value.contentAlign,\n \"--schemx-error-align\":\n schemaRef.value.errorAlign ??\n formContext.schemaConfig.errorAlign ??\n \"left\",\n },\n ]}\n >\n {renderBefore()}\n {fieldContent}\n {renderError()}\n {renderAfter()}\n </div>\n )\n\n return <Col col={schemaRef.value.col ?? schemaRef.value.layout}>{fieldWrapper}</Col>\n }\n },\n})\n\nexport default Field\n","<script setup lang=\"ts\">\n import { computed, useAttrs } from \"vue\"\n\n import type { SchemxButtonSize } from \"./types\"\n\n interface Props {\n /**\n * 是否显示加载状态;加载时按钮不可点击。\n */\n loading?: boolean\n /**\n * 加载状态下替换按钮内容的文本。\n */\n loadingText?: string\n /**\n * 是否禁用按钮。\n */\n disabled?: boolean\n /**\n * 按钮尺寸。\n */\n size?: SchemxButtonSize\n }\n\n defineOptions({ name: \"SchemxButton\", inheritAttrs: false })\n\n const props = withDefaults(defineProps<Props>(), {\n loading: false,\n loadingText: undefined,\n disabled: false,\n size: \"medium\",\n })\n\n // 透传给原生 button 的非组件 Props 属性。\n const attrs = useAttrs()\n\n // loading 或 disabled 任一为真时锁定按钮交互。\n const isDisabled = computed(() => props.disabled || props.loading)\n\n // 根据按钮尺寸生成内置样式类。\n const buttonClass = computed(() => [\"schemx-button\", `schemx-button--${props.size}`])\n</script>\n\n<template>\n <button\n v-bind=\"attrs\"\n :class=\"buttonClass\"\n :aria-busy=\"props.loading || undefined\"\n :data-loading=\"props.loading || undefined\"\n :disabled=\"isDisabled\"\n >\n <span v-if=\"$slots.prefix\" class=\"schemx-button__prefix\">\n <slot name=\"prefix\" />\n </span>\n <svg\n v-if=\"props.loading\"\n class=\"schemx-button__loading\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"M12 2v4\" />\n <path d=\"m16.2 7.8 2.9-2.9\" />\n <path d=\"M18 12h4\" />\n <path d=\"m16.2 16.2 2.9 2.9\" />\n <path d=\"M12 18v4\" />\n <path d=\"m4.9 19.1 2.9-2.9\" />\n <path d=\"M2 12h4\" />\n <path d=\"m4.9 4.9 2.9 2.9\" />\n </svg>\n\n <template v-if=\"props.loading && props.loadingText\">\n {{ props.loadingText }}\n </template>\n <slot v-else />\n <span v-if=\"$slots.suffix\" class=\"schemx-button__suffix\">\n <slot name=\"suffix\" />\n </span>\n </button>\n</template>\n\n<style>\n .schemx-button {\n box-sizing: content-box;\n flex: 1;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--schemx-padding-xs);\n min-width: 72px;\n height: 24px;\n padding: var(--schemx-padding-xs) var(--schemx-padding-md);\n border: 1px solid var(--schemx-border-color);\n border-radius: var(--schemx-border-radius-sm);\n background: var(--schemx-background-color);\n color: var(--schemx-text-color);\n cursor: pointer;\n transition:\n border-color 0.15s ease,\n background-color 0.15s ease,\n color 0.15s ease,\n transform 0.1s ease;\n }\n\n .schemx-button:not(:disabled):hover {\n opacity: 0.8;\n }\n\n .schemx-button:not(:disabled):active {\n transform: scale(0.98);\n }\n\n .schemx-button--small {\n min-width: 56px;\n height: 20px;\n padding: var(--schemx-padding-base) var(--schemx-padding-sm);\n font-size: var(--schemx-font-size-sm);\n }\n\n .schemx-button--large {\n min-width: 88px;\n height: 28px;\n padding: var(--schemx-padding-sm) var(--schemx-padding-lg);\n font-size: var(--schemx-font-size-lg);\n }\n\n .schemx-button__loading {\n display: inline-block;\n border-radius: 50%;\n vertical-align: -0.15em;\n animation: schemx-button-loading 0.8s linear infinite;\n }\n\n .schemx-actions-button--submit {\n border-color: var(--schemx-primary-color);\n background: var(--schemx-primary-color);\n color: #ffffff;\n }\n\n .schemx-actions-button--submit:not(:disabled):hover {\n filter: brightness(0.92);\n color: #ffffff;\n }\n\n .schemx-button:disabled {\n cursor: not-allowed;\n opacity: var(--schemx-disabled-opacity);\n }\n\n @keyframes schemx-button-loading {\n to {\n transform: rotate(360deg);\n }\n }\n</style>\n","/**\n * Dynamic - 动态数组字段组件。\n *\n * 负责按 ViewSchema 的数组行边界展开 Dynamic,并将每行的 Row 配置传给 SchemaList;\n * 子节点具体渲染委托给 SchemaList,字段插槽由父级 Form 透传到当前 Dynamic 子树。\n *\n * @module components/Dynamic\n */\n\n/* eslint-disable vue/one-component-per-file */\nimport { defineComponent, Fragment } from \"vue\"\nimport type { PropType, VNodeChild } from \"vue\"\n\nimport Col from \"../Col\"\n\nimport type { SchemxRowConfig } from \"../../types/layout\"\nimport type { SchemxViewDynamicSchema, SchemxViewSchema } from \"@schemx/core\"\n\n/**\n * Dynamic 组件属性。\n */\nexport interface SchemxDynamicProps {\n /**\n * 当前 Dynamic 数组的 ViewSchema。\n */\n schema: SchemxViewDynamicSchema\n /**\n * 从 Form 或父级 Schema 继承的 Row 配置。\n */\n rowConfig?: SchemxRowConfig\n /**\n * 由 SchemaList 提供的子级 Schema 渲染回调。\n *\n * @param schemas - 当前数组项的子级 ViewSchema。\n * @param rowConfig - 当前数组项继承到的 Row 配置。\n */\n renderChildren: (\n schemas: readonly SchemxViewSchema[],\n rowConfig?: SchemxRowConfig\n ) => VNodeChild\n}\n\nconst Dynamic = defineComponent({\n name: \"SchemxDynamic\",\n inheritAttrs: false,\n\n props: {\n schema: {\n type: Object as PropType<SchemxViewDynamicSchema>,\n required: true,\n },\n rowConfig: {\n type: Object as PropType<SchemxRowConfig>,\n required: false,\n default: undefined,\n },\n renderChildren: {\n type: Function as PropType<SchemxDynamicProps[\"renderChildren\"]>,\n required: true,\n },\n },\n\n /**\n * 初始化 Dynamic 的行模板渲染器。\n *\n * @param props - 当前 Dynamic ViewSchema、继承的 Row 配置和子级渲染回调。\n */\n setup(props) {\n return (): VNodeChild => {\n if (props.schema.visible === false) {\n return null\n }\n\n const rowConfig =\n props.rowConfig || props.schema.row\n ? { ...props.rowConfig, ...props.schema.row }\n : undefined\n\n const items = props.schema.items.map((item) => {\n const children =\n rowConfig === undefined\n ? props.renderChildren(item.children)\n : props.renderChildren(item.children, rowConfig)\n\n return <Fragment key={item.key}>{children}</Fragment>\n })\n\n if (!props.schema.layout) {\n return items\n }\n\n return <Col col={props.schema.layout}>{items}</Col>\n }\n },\n})\n\nexport default Dynamic\n","/**\n * Group 插槽渲染器。\n *\n * 集中处理分组 Header、Label、Content 插槽的解析和默认内容,保持\n * Group 仅负责折叠状态、子节点分发和容器布局。\n *\n * @module components/Group/slot\n */\n\nimport type { Slots, VNodeChild } from \"vue\"\n\nimport classnames from \"classnames\"\n\nimport { resolveSlot } from \"../../utils\"\n\nimport type { SchemxGroupSlotProps } from \"../../types\"\nimport type { SchemxViewGroupSchema, Values } from \"@schemx/core\"\n\n/**\n * Group 插槽渲染所需的状态与依赖。\n */\ninterface GroupSlotRendererOptions<TValues extends Values = Values> {\n /**\n * 当前分组 ViewSchema。\n */\n schema: SchemxViewGroupSchema<TValues>\n /**\n * 当前是否收起。\n */\n collapsed: boolean\n /**\n * 当前分组是否可收起。\n */\n collapsible: boolean\n /**\n * 当前分组是否禁用。\n */\n disabled: boolean\n /**\n * 当前分组是否只读。\n */\n readonly: boolean\n /**\n * 切换分组收起状态。\n */\n toggle: () => void\n /**\n * 父组件传入的所有具名插槽。\n */\n slots: Slots\n /**\n * 默认子节点渲染函数。\n */\n renderChildren: () => VNodeChild\n}\n\n/**\n * 创建 Group 各区域的插槽渲染函数。\n *\n * `Header` 完全接管 Header 内部内容;`Label` 只替换默认标题;`Content`\n * 只替换 Body 内的默认子节点布局。\n *\n * @param options - Group 插槽渲染所需的状态、插槽和子节点渲染器。\n * @returns Group Header、Body 渲染函数及 Header 是否存在的标记。\n *\n * @example\n * ```ts\n * const renderers = createGroupSlotRenderers(options)\n * renderers.renderHeaderContent()\n * ```\n */\nexport function createGroupSlotRenderers<TValues extends Values = Values>(\n options: GroupSlotRendererOptions<TValues>\n) {\n const {\n schema,\n collapsed,\n collapsible,\n disabled,\n readonly,\n toggle,\n slots,\n renderChildren,\n } = options\n\n const slotKey = String(schema.key)\n\n const headerSlot = resolveSlot(slots, `${slotKey}Header`)\n\n const labelSlot = resolveSlot(slots, `${slotKey}Label`)\n\n const contentSlot = resolveSlot(slots, `${slotKey}Content`)\n\n const slotProps: SchemxGroupSlotProps<TValues> = {\n schema,\n collapsed,\n collapsible,\n disabled,\n readonly,\n toggle,\n }\n\n const renderHeaderContent = (): VNodeChild => {\n if (headerSlot) {\n return headerSlot(slotProps)\n }\n\n const label = labelSlot ? (\n labelSlot(slotProps)\n ) : (\n <span class=\"schemx-group__title\">{schema.label}</span>\n )\n\n if (!collapsible) {\n return label\n }\n\n return (\n <>\n {label}\n <span\n class={classnames(\"schemx-group__arrow\", {\n \"schemx-group__arrow--down\": !collapsed,\n })}\n />\n </>\n )\n }\n\n const renderBodyContent = (): VNodeChild => {\n if (contentSlot) {\n return contentSlot(slotProps)\n }\n\n return renderChildren()\n }\n\n return {\n hasHeader: Boolean(schema.label || headerSlot || labelSlot),\n renderBodyContent,\n renderHeaderContent,\n }\n}\n","/**\n * Group - 分组字段组件\n *\n * 用于渲染包含 children 的 Group ViewSchema。\n * 支持可折叠的分组容器,并将子级 Row 配置传给 SchemaList。\n *\n * @module components/Group\n */\n\nimport { computed, defineComponent, getCurrentInstance, ref, watch } from \"vue\"\nimport type { ClassValue, PropType, SlotsType, StyleValue, VNodeChild } from \"vue\"\n\nimport { isViewDynamicSchema, isViewGroupSchema } from \"@schemx/core\"\nimport classnames from \"classnames\"\n\nimport { normalizeId, normalizeNameKey } from \"../../utils\"\nimport Col from \"../Col\"\nimport Field from \"../Field\"\n\nimport { createGroupSlotRenderers } from \"./slot\"\n\nimport type { SchemxGroupSlots } from \"../../types/field\"\nimport type { SchemxRowConfig } from \"../../types/layout\"\nimport type { SchemxViewGroupSchema, SchemxViewSchema } from \"@schemx/core\"\n\n/**\n * Group Props。\n */\nexport interface SchemxGroupProps {\n /**\n * 当前分组的已解析 ViewSchema。\n */\n schema: SchemxViewGroupSchema\n /**\n * 从 Form 或父级 Schema 继承的 Row 配置。\n */\n rowConfig?: SchemxRowConfig\n /**\n * 父级传入的 class,会与内部和 Schema class 合并。\n */\n class?: ClassValue\n /**\n * 父级传入的 style,会在 Schema style 之前合并。\n */\n style?: StyleValue\n /**\n * 可选的子级 Schema 渲染回调;省略时 Group 递归渲染默认子级。\n *\n * @param schemas - 当前 Group 的子级 ViewSchema。\n * @param rowConfig - 当前 Group 子级使用的合并 Row 配置。\n */\n renderChildren?: (\n schemas: readonly SchemxViewSchema[],\n rowConfig?: SchemxRowConfig\n ) => VNodeChild\n}\n\nconst Group = defineComponent({\n name: \"SchemxGroup\",\n inheritAttrs: false,\n\n props: {\n schema: {\n type: Object as PropType<SchemxViewGroupSchema>,\n required: true,\n },\n rowConfig: {\n type: Object as PropType<SchemxRowConfig>,\n required: false,\n default: undefined,\n },\n class: {\n type: [String, Object, Array, Boolean] as PropType<ClassValue>,\n required: false,\n default: undefined,\n },\n style: {\n type: [String, Object, Array] as PropType<StyleValue>,\n required: false,\n default: undefined,\n },\n renderChildren: {\n type: Function as PropType<SchemxGroupProps[\"renderChildren\"]>,\n required: false,\n default: undefined,\n },\n },\n\n slots: Object as SlotsType<SchemxGroupSlots>,\n\n /**\n * 组合 Group 的折叠状态、子级渲染和插槽内容。\n *\n * @param props - 当前 Group Schema、布局和兼容渲染回调。\n * @param setupContext - 父级透传属性与 Group 插槽。\n */\n setup(props, setupContext) {\n const { attrs, slots } = setupContext\n\n const internalCollapsed = ref(Boolean(props.schema.defaultCollapsed))\n\n const collapsed = computed(() => props.schema.collapsed ?? internalCollapsed.value)\n\n const componentId = getCurrentInstance()?.uid ?? 0\n\n watch(\n () => props.schema.collapsed,\n (nextCollapsed, previousCollapsed) => {\n if (nextCollapsed !== undefined) {\n internalCollapsed.value = nextCollapsed\n } else if (previousCollapsed !== undefined) {\n internalCollapsed.value = previousCollapsed\n }\n }\n )\n\n // 切换非受控 Group 的折叠状态,并通知受控回调。\n const toggle = () => {\n if (!props.schema.collapsible || props.schema.disabled) {\n return\n }\n\n const nextCollapsed = !collapsed.value\n\n if (props.schema.collapsed === undefined) {\n internalCollapsed.value = nextCollapsed\n }\n\n props.schema.onCollapsedChange?.(nextCollapsed)\n }\n\n return (): VNodeChild => {\n const schema = props.schema\n\n if (schema.visible === false) {\n return null\n }\n\n const collapsible = Boolean(schema.collapsible)\n\n const isCollapsed = collapsed.value\n\n const destroyOnCollapse = schema.destroyOnCollapse ?? true\n\n const uniqueId = schema.debug?.runtimeNodeId ?? `local-${componentId}`\n\n const idBase = `schemx-group-${uniqueId}-${normalizeId(schema.key)}`\n\n const headerId = `${idBase}-header`\n\n const bodyId = `${idBase}-body`\n\n const rowConfig =\n props.rowConfig || schema.row ? { ...props.rowConfig, ...schema.row } : undefined\n\n /**\n * 按需渲染 Group 的默认子级内容;Content 插槽存在时由插槽接管布局。\n */\n const renderChild = (child: SchemxViewSchema): VNodeChild => {\n if (isViewDynamicSchema(child)) {\n if (child.visible === false) {\n return null\n }\n\n return child.items.map((item) => item.children.map(renderChild))\n }\n\n if (isViewGroupSchema(child)) {\n return (\n <Group\n key={child.key}\n schema={child as SchemxViewGroupSchema}\n class={props.class}\n style={props.style}\n v-slots={slots}\n />\n )\n }\n\n return (\n <Field\n key={`${child.key}:${normalizeNameKey(child.name)}`}\n schema={child}\n v-slots={slots}\n />\n )\n }\n\n const renderGroupChildren = (): VNodeChild => {\n if (!props.renderChildren) {\n return schema.children.map(renderChild)\n }\n\n return rowConfig === undefined\n ? props.renderChildren(schema.children)\n : props.renderChildren(schema.children, rowConfig)\n }\n\n const { hasHeader, renderBodyContent, renderHeaderContent } =\n createGroupSlotRenderers({\n schema,\n collapsed: isCollapsed,\n collapsible,\n disabled: Boolean(schema.disabled),\n readonly: Boolean(schema.readonly),\n toggle,\n slots,\n renderChildren: renderGroupChildren,\n })\n\n const body = (\n <div\n id={bodyId}\n role=\"group\"\n aria-labelledby={schema.label ? headerId : undefined}\n aria-hidden={isCollapsed || undefined}\n class=\"schemx-group__body\"\n style={!destroyOnCollapse && isCollapsed ? { display: \"none\" } : undefined}\n >\n {renderBodyContent()}\n </div>\n )\n\n const groupWrapper = (\n <div\n {...attrs}\n class={classnames(\n \"schemx-group-wrapper\",\n props.class,\n attrs.class,\n schema.class\n )}\n data-key={schema.key}\n aria-disabled={schema.disabled || undefined}\n style={[attrs.style, props.style, schema.style]}\n >\n <div\n class={classnames(\"schemx-group\", {\n \"schemx-group--collapsed\": isCollapsed,\n \"is-readonly\": schema.readonly,\n \"is-disabled\": schema.disabled,\n })}\n >\n {hasHeader && (\n <div\n id={headerId}\n role={collapsible ? \"button\" : undefined}\n tabindex={collapsible ? (schema.disabled ? -1 : 0) : undefined}\n aria-expanded={collapsible ? !isCollapsed : undefined}\n aria-controls={collapsible ? bodyId : undefined}\n aria-disabled={collapsible ? schema.disabled || undefined : undefined}\n class={classnames(\"schemx-group__header\", {\n \"schemx-group__header--clickable\": collapsible && !schema.disabled,\n })}\n onClick={toggle}\n onKeydown={(e: KeyboardEvent) => {\n if (!schema.disabled && (e.key === \"Enter\" || e.key === \" \")) {\n e.preventDefault()\n toggle()\n }\n }}\n >\n {renderHeaderContent()}\n </div>\n )}\n {destroyOnCollapse ? !isCollapsed && body : body}\n </div>\n </div>\n )\n\n if (!schema.layout) {\n return groupWrapper\n }\n\n return <Col col={schema.layout}>{groupWrapper}</Col>\n }\n },\n})\n\nexport default Group\n","/**\n * Row - Schema 列表行包装组件。\n *\n * 将 Form、Group 或 Dynamic 的同级节点交给配置的 UI Row 组件渲染;未传入组件时\n * 回退到 Vue 层内置的基础 flex 行容器。调用方可通过 `enabled` 明确关闭 Row。\n *\n * @module components/Row\n */\n\nimport { computed, defineComponent, h, markRaw, type PropType, toRaw } from \"vue\"\nimport type { ClassValue, StyleValue, VNodeChild } from \"vue\"\n\nimport { useOptionalFormContextValue } from \"../../context/formContext\"\nimport { normalizeSchemxGutter } from \"../../utils/layout\"\n\nimport type { SchemxRowConfig } from \"../../types/layout\"\n\nconst Row = defineComponent({\n name: \"SchemxRow\",\n inheritAttrs: false,\n\n props: {\n row: {\n type: Object as PropType<SchemxRowConfig>,\n required: false,\n default: undefined,\n },\n enabled: {\n type: Boolean,\n required: false,\n default: true,\n },\n },\n\n /**\n * 根据 Row 配置和当前 Form Context 创建行容器。\n *\n * @param props - Row 配置与启用状态。\n * @param setupContext - 父级透传属性与默认插槽。\n */\n setup(props, setupContext) {\n const { attrs, slots } = setupContext\n\n const formContext = useOptionalFormContextValue()\n\n const resolvedComponent = computed(() => {\n const component = formContext?.rowComponent\n\n return component ? markRaw(toRaw(component)) : undefined\n })\n\n return (): VNodeChild => {\n const component = resolvedComponent.value\n\n const row = props.row ?? {}\n\n const { gutter, justify, align, ...extensionProps } = row\n\n const { class: attrsClass, style: attrsStyle, ...restAttrs } = attrs\n\n const componentAttrs = {\n ...extensionProps,\n ...restAttrs,\n }\n\n const rowClassValue = [\"schemx-row\", attrsClass] as ClassValue[]\n\n const justifyContent =\n justify === \"start\" ? \"flex-start\" : justify === \"end\" ? \"flex-end\" : justify\n\n const alignItems =\n align === \"top\"\n ? \"flex-start\"\n : align === \"middle\"\n ? \"center\"\n : align === \"bottom\"\n ? \"flex-end\"\n : undefined\n\n const [gutterTop, gutterRight, gutterBottom, gutterLeft] =\n normalizeSchemxGutter(gutter)\n\n const paddingTop = gutterTop / 2\n\n const paddingRight = gutterRight / 2\n\n const paddingBottom = gutterBottom / 2\n\n const paddingLeft = gutterLeft / 2\n\n const internalRowStyle = [\n attrsStyle as StyleValue,\n {\n \"--schemx-gutter-top\": `${paddingTop}px`,\n \"--schemx-gutter-right\": `${paddingRight}px`,\n \"--schemx-gutter-bottom\": `${paddingBottom}px`,\n \"--schemx-gutter-left\": `${paddingLeft}px`,\n margin: `-${paddingTop}px -${paddingRight}px -${paddingBottom}px -${paddingLeft}px`,\n justifyContent,\n alignItems,\n },\n ] as StyleValue\n\n if (!props.enabled) {\n return slots.default?.() ?? null\n }\n\n if (!component) {\n return (\n <div {...restAttrs} class={rowClassValue} style={internalRowStyle}>\n {slots.default?.()}\n </div>\n )\n }\n\n return h(\n component,\n {\n ...componentAttrs,\n gutter,\n justify,\n align,\n class: rowClassValue,\n style: internalRowStyle as StyleValue,\n },\n slots\n )\n }\n },\n})\n\nexport default Row\n","/**\n * SchemaList - 统一递归渲染 ViewSchema 列表。\n *\n * 负责遍历同级 ViewSchema,将节点分发给 Field、Group 和 Dynamic,并为当前列表\n * 建立 Row 包裹;Col 由 Field、Group 和 Dynamic 的布局路径负责。\n *\n * @module components/SchemaList\n */\n\nimport { defineComponent, h, type PropType } from \"vue\"\nimport type { ClassValue, VNodeChild } from \"vue\"\n\nimport { isViewDynamicSchema, isViewGroupSchema } from \"@schemx/core\"\n\nimport { normalizeNameKey } from \"../../utils\"\nimport Dynamic from \"../Dynamic\"\nimport Field from \"../Field\"\nimport Group from \"../Group\"\nimport Row from \"../Row\"\n\nimport type { SchemxRowConfig } from \"../../types/layout\"\nimport type { SchemxViewFieldSchema, SchemxViewSchema, Values } from \"@schemx/core\"\n\nimport \"./index.css\"\n\n/**\n * SchemaList 的公开属性。\n */\nexport interface SchemxSchemaListProps<TValues extends Values = Values> {\n /**\n * 当前同级 ViewSchema 列表。\n */\n schemas: readonly SchemxViewSchema<TValues>[]\n /**\n * 根级 ViewSchema 列表,供 Field 首尾样式计算。\n */\n viewSchemas: readonly SchemxViewSchema<TValues>[]\n /**\n * 当前 Form 或父级容器继承的 Row 配置。\n */\n rowConfig?: SchemxRowConfig\n /**\n * 根级 Field wrapper 的 class 解析器。\n */\n fieldClassResolver?: (schema: SchemxViewSchema<TValues>) => ClassValue\n}\n\nconst SchemaList = defineComponent({\n name: \"SchemxSchemaList\",\n inheritAttrs: false,\n\n props: {\n schemas: {\n type: Array as PropType<readonly SchemxViewSchema[]>,\n required: true,\n },\n viewSchemas: {\n type: Array as PropType<readonly SchemxViewSchema[]>,\n required: true,\n },\n rowConfig: {\n type: Object as PropType<SchemxRowConfig>,\n required: false,\n default: undefined,\n },\n fieldClassResolver: {\n type: Function as PropType<(schema: SchemxViewSchema) => ClassValue>,\n required: false,\n default: undefined,\n },\n },\n\n setup(props, { slots }) {\n /**\n * 根据字段路径生成稳定的 Field 渲染 key。\n *\n * @param schema - 当前字段 ViewSchema。\n * @returns 包含 Schema key 和字段路径的渲染 key。\n */\n const getFieldRenderKey = (schema: SchemxViewFieldSchema): string =>\n `${schema.key}:${normalizeNameKey(schema.name)}`\n\n /**\n * 递归创建子级 SchemaList,并复用当前 Form 的布局与字段渲染配置。\n *\n * @param schemas - 当前子级 ViewSchema 列表。\n * @returns 子级 SchemaList 的 VNode。\n */\n const renderChildren = (\n schemas: readonly SchemxViewSchema[],\n rowConfig: SchemxRowConfig | undefined = props.rowConfig\n ): VNodeChild => {\n return h(\n SchemaList,\n {\n schemas,\n viewSchemas: props.viewSchemas,\n rowConfig,\n fieldClassResolver: props.fieldClassResolver,\n },\n slots\n )\n }\n\n /**\n * 将单个 ViewSchema 分发为 Field、Group 或 Dynamic。\n *\n * @param schema - 当前待渲染的 ViewSchema。\n * @returns 当前 Schema 对应的 VNode。\n */\n const renderSchema = (schema: SchemxViewSchema): VNodeChild => {\n if (schema.visible === false) {\n return null\n }\n\n let content: VNodeChild\n\n if (isViewGroupSchema(schema)) {\n content = (\n <Group\n key={schema.key}\n schema={schema}\n rowConfig={props.rowConfig}\n renderChildren={renderChildren}\n v-slots={slots}\n />\n )\n } else if (isViewDynamicSchema(schema)) {\n content = (\n <Dynamic\n key={schema.key}\n schema={schema}\n rowConfig={props.rowConfig}\n renderChildren={renderChildren}\n v-slots={slots}\n />\n )\n } else {\n content = (\n <Field\n key={getFieldRenderKey(schema)}\n schema={schema}\n class={props.fieldClassResolver?.(schema)}\n v-slots={slots}\n />\n )\n }\n\n return content\n }\n\n return (): VNodeChild => {\n return (\n <Row row={props.rowConfig} class=\"schemx-schema-list\">\n {props.schemas.map(renderSchema)}\n </Row>\n )\n }\n },\n})\n\nexport default SchemaList\n","<!--\n schemx - 主组件\n\n 基于 Schema 配置的表单组件,使用 useForm Hook 管理状态。\n\n @module schemx\n-->\n\n<script lang=\"ts\" setup generic=\"TValues extends Values = Values\">\n import { computed, nextTick, toRaw, useSlots, watch } from \"vue\"\n\n import {\n defaultSchemxConfigKeys,\n getGlobalSchemxConfig,\n isSchemxSchemas,\n mergeConfig,\n resolveSchemxConfig,\n } from \"@schemx/core\"\n import { pick } from \"es-toolkit\"\n\n import Button from \"./components/Button\"\n import SchemaList from \"./components/SchemaList\"\n import {\n defaultVueSchemaConfig,\n defaultVueSchemaConfigKeys,\n } from \"./config/defaultVueSchemaConfig\"\n import { provideFormContext, useConfigProviderContextRef } from \"./context\"\n import { useForm, useFormSelector, useViewSchemas } from \"./hooks\"\n import { getSectionPosition } from \"./utils/helpers\"\n\n import type { SchemxIconComponent } from \"./types/icon\"\n import type { SchemxFormActionConfig, SchemxFormProps } from \"./types/index\"\n import type {\n SchemxConfig,\n SchemxInstance,\n SchemxSchemaConfig,\n SchemxViewSchema,\n Values,\n } from \"@schemx/core\"\n\n import \"./styles/index.css\"\n\n defineOptions({ name: \"SchemxForm\" })\n\n /**\n * 规范化表单组件的公开输入,并为未提供的可选项补充默认值。\n *\n * 具体字段语义由 `SchemxFormProps<TValues>` 定义;其中 `modelValue`、\n * `schemas` 和 `form` 共同决定表单数据与实例来源。\n */\n const props = withDefaults(defineProps<SchemxFormProps<TValues>>(), {\n modelValue: () => ({}) as TValues,\n initialValues: () => ({}) as TValues,\n form: undefined,\n schemas: () => [],\n class: \"\",\n style: () => ({}),\n onFinish: undefined,\n onFinishFailed: undefined,\n onReset: undefined,\n onLoadingChange: undefined,\n onValuesChange: undefined,\n onFieldsChange: undefined,\n loading: undefined,\n submitter: true,\n resetter: true,\n rendererProps: undefined,\n rendererRegistry: undefined,\n presetRuleRegistry: undefined,\n fieldRules: undefined,\n schedulerOptions: undefined,\n validationConcurrency: undefined,\n visible: undefined,\n validationTrigger: undefined,\n readonly: undefined,\n disabled: undefined,\n colon: undefined,\n showRequiredMark: undefined,\n bordered: undefined,\n col: undefined,\n colComponent: undefined,\n iconComponent: undefined,\n row: undefined,\n rowComponent: undefined,\n })\n\n /**\n * 定义表单 v-model 的同步事件。\n *\n * 仅在内部表单值变化且不是外部 `modelValue` 同步窗口时发出更新。\n */\n const emit = defineEmits<{\n \"update:modelValue\": [value: TValues]\n }>()\n\n /**\n * 读取组件保留操作区插槽,并据此决定是否渲染默认操作区。\n */\n const slots = useSlots()\n\n /**\n * Core 兼容键与 Vue 展示键的合并集合。\n */\n const schemaConfigKeys = [\n ...defaultSchemxConfigKeys,\n ...defaultVueSchemaConfigKeys,\n ] as (keyof SchemxSchemaConfig)[]\n\n /**\n * 提取需要同步到 Core 的表单级 schema 配置。\n */\n const pickSchemaConfig = (): Partial<SchemxSchemaConfig> => {\n // Vue 保留 `required` 对当前 TValues 的泛型约束;Core 的表单级配置使用\n // unknown 表示任意字段值。运行时该回调只会接收当前 Form 的字段值,因此在\n // Vue 到 Core 的适配边界收窄为 Core 配置类型。\n const schemaConfig = pick(props, schemaConfigKeys) as Partial<SchemxSchemaConfig>\n\n return Object.fromEntries(\n Object.entries(schemaConfig).filter(([, value]) => value !== undefined)\n ) as Partial<SchemxSchemaConfig>\n }\n\n // 是否由调用方传入并负责生命周期的外部 Form。\n const isExternalForm = props.form !== undefined\n\n // 当前组件显式传入的、待同步到 Core 的 schema 配置。\n const schemaConfigProps = computed(pickSchemaConfig)\n\n // 当前 App 或组件树中最近 Provider 的响应式配置。\n const providerConfig = useConfigProviderContextRef()\n\n /**\n * 读取 setup 时的 Core 模块级配置快照;后续全局配置变更不影响当前 Form。\n */\n const coreConfig = getGlobalSchemxConfig()\n\n /**\n * 保持 SchemxForm 既有默认行为、且允许 Provider/App 覆盖的最低优先级配置。\n */\n const formFallbackConfig: SchemxConfig<TValues> = {\n schemaConfig: {\n visible: true,\n validationTrigger: [\"blur\", \"change\"],\n },\n }\n\n /**\n * 合并配置来源;外部 Form 只接收组件显式配置与组件默认行为。\n */\n const mergedConfig = computed(() =>\n isExternalForm\n ? mergeConfig<TValues>(\n { schemaConfig: schemaConfigProps.value },\n formFallbackConfig\n )\n : mergeConfig<TValues>(\n { schemaConfig: schemaConfigProps.value },\n (providerConfig?.value as SchemxConfig<TValues> | undefined) ?? {},\n formFallbackConfig,\n coreConfig as SchemxConfig<TValues>\n )\n )\n\n /**\n * 为后代 Field 补充 Vue 展示默认值。\n */\n const contextSchemaConfig = computed<Partial<SchemxSchemaConfig>>(() => ({\n ...defaultVueSchemaConfig,\n ...mergedConfig.value.schemaConfig,\n }))\n\n /**\n * 计算内部 Form 当前完整生效的配置,用于撤销局部覆盖和响应 Provider 变化。\n */\n const resolvedSchemaConfig = computed<SchemxSchemaConfig>(\n () => resolveSchemxConfig({ schemaConfig: contextSchemaConfig.value }).schemaConfig\n )\n\n /**\n * 判断配置对象是否显式包含指定 key。\n *\n * @param config - 待检查的配置对象。\n * @param key - 要检查的配置 key。\n * @returns 配置对象自身包含该 key 时返回 `true`。\n */\n const hasSchemaConfigKey = (\n config: Partial<SchemxSchemaConfig>,\n key: keyof SchemxSchemaConfig\n ): boolean => Object.prototype.hasOwnProperty.call(config, key)\n\n /**\n * 当前 Form 使用的 Col,按 Form、Provider/App、全局注册顺序解析。\n */\n const resolvedColComponent = computed(\n () =>\n props.colComponent ?? providerConfig?.value.colComponent ?? coreConfig.colComponent\n )\n\n /**\n * 当前 Form 使用的 Row,按 Form、Provider/App、全局注册顺序解析。\n */\n const resolvedRowComponent = computed(\n () =>\n props.rowComponent ?? providerConfig?.value.rowComponent ?? coreConfig.rowComponent\n )\n\n /**\n * 当前 Form 使用的 Icon Adapter,按 Form、Provider/App、Core 全局配置顺序解析。\n */\n const resolvedIconComponent = computed<SchemxIconComponent | undefined>(\n () =>\n props.iconComponent ??\n providerConfig?.value.iconComponent ??\n coreConfig.iconComponent\n )\n\n /**\n * 当前 Form 的 Row 配置,局部 Form 配置覆盖 Provider 或 App 默认值。\n */\n const resolvedRowConfig = computed(() => {\n const schemaConfigRow = resolvedSchemaConfig.value.row\n\n const inheritedRowConfig =\n providerConfig?.value.row ?? coreConfig.row ?? schemaConfigRow\n\n if (inheritedRowConfig === undefined && props.row === undefined) {\n return undefined\n }\n\n return {\n ...inheritedRowConfig,\n ...props.row,\n }\n })\n\n /**\n * 获取或创建表单实例\n *\n * 优先使用外部传入的 form,否则内部通过 useForm 创建。\n * 必须在 setup 同步阶段调用,确保 provide 正确注入。\n */\n const providedForm = props.form\n ? props.form\n : useForm<TValues>({\n schemas: props.schemas,\n schemaConfig: resolvedSchemaConfig.value,\n initialValues:\n Object.keys(props.modelValue).length > 0\n ? props.modelValue\n : props.initialValues,\n\n rendererProps: props.rendererProps,\n rendererRegistry: props.rendererRegistry,\n defaultRendererType: props.defaultRendererType,\n presetRuleRegistry: props.presetRuleRegistry,\n fieldRules: props.fieldRules,\n validatorAdapters: props.validatorAdapters,\n schedulerOptions: props.schedulerOptions,\n validationConcurrency: props.validationConcurrency,\n\n /**\n * 转发提交成功回调。\n *\n * @param values - 提交成功时的完整表单快照。\n */\n onFinish: (values) => props.onFinish?.(values),\n /**\n * 转发提交失败回调。\n *\n * @param failure - 提交失败结果,包含本次表单值和校验错误。\n */\n onFinishFailed: (failure) => props.onFinishFailed?.(failure),\n /**\n * 转发完整表单重置回调。\n */\n onReset: () => {\n props.onReset?.()\n },\n /**\n * 转发 Core 发出的提交 loading 状态。\n *\n * 外部传入 Form 时不会注入该回调,保持实例的创建期边界。\n *\n * @param loading - 当前是否处于提交流程中。\n */\n onLoadingChange: (loading) => {\n props.onLoadingChange?.(loading)\n },\n /**\n * 转发值变化回调。\n *\n * @param changedValues - 本次变更涉及的字段值。\n * @param latestSnapshot - 变更后的完整表单快照。\n */\n onValuesChange: (changedValues, latestSnapshot) => {\n props.onValuesChange?.(changedValues, latestSnapshot)\n },\n /**\n * 转发字段变化回调。\n *\n * @param changedPaths - 本次发生变化的字段路径。\n * @param allPaths - 当前已变更字段路径集合。\n */\n onFieldsChange: (changedPaths, allPaths) => {\n props.onFieldsChange?.(changedPaths, allPaths)\n },\n })\n\n /**\n * 注册表单上下文。\n *\n * 无论实例来自 props.form 还是 useForm,都必须同步注册,\n * 从而保证 Field、useField 等后代逻辑能够获取同一个实例。\n */\n const formInstance = provideFormContext({\n form: providedForm,\n get schemaConfig() {\n return contextSchemaConfig.value\n },\n get iconComponent() {\n return resolvedIconComponent.value\n },\n get colComponent() {\n return resolvedColComponent.value\n },\n get rowComponent() {\n return resolvedRowComponent.value\n },\n })\n\n /**\n * 组件未受控时直接跟随 Core 提交状态;受控值仅覆盖操作区展示。\n */\n const effectiveLoading = computed(() => props.loading ?? formInstance.isLoading())\n\n /**\n * Form 根节点的 class 来源:组件内部标识与调用方自定义 class。\n */\n const formRootClass = computed(() => [\"schemx\", props.class])\n\n /**\n * Form 根节点的 style 来源;保留 Vue StyleValue 的对象/数组合并能力。\n */\n const formRootStyle = computed(() => props.style)\n\n /**\n * 归一化启用状态下的操作配置。\n *\n * @param action - 布尔开关或操作按钮配置。\n * @returns 可直接用于渲染按钮的配置对象。\n */\n const normalizeActionConfig = (\n action: SchemxFormProps<TValues>[\"submitter\"]\n ): SchemxFormActionConfig => (action === true ? {} : action || {})\n\n /**\n * 提交操作的归一化配置。\n */\n const submitterConfig = computed(() => normalizeActionConfig(props.submitter))\n\n /**\n * 重置操作的归一化配置。\n */\n const resetterConfig = computed(() => normalizeActionConfig(props.resetter))\n\n /**\n * 操作区必须保护内部事件和 button type,不接受运行时透传的同名属性。\n *\n * @param config - 当前操作按钮的配置。\n * @returns 过滤内部事件和 type 后的按钮属性。\n */\n const getButtonProps = (config: SchemxFormActionConfig) => {\n const buttonProps = Object.fromEntries(\n Object.entries(config.buttonProps ?? {}).filter(\n ([name]) => name !== \"type\" && name !== \"onClick\"\n )\n )\n\n return buttonProps\n }\n\n /**\n * 提交按钮可安全透传的原生属性。\n */\n const submitterButtonProps = computed(() => getButtonProps(submitterConfig.value))\n\n /**\n * 重置按钮可安全透传的原生属性。\n */\n const resetterButtonProps = computed(() => getButtonProps(resetterConfig.value))\n\n /**\n * 仅配置或提供对应插槽时展示提交操作。\n */\n const isSubmitterVisible = computed(\n () => props.submitter !== false && (props.submitter !== undefined || slots.submitter)\n )\n\n /**\n * 仅配置或提供对应插槽时展示重置操作。\n */\n const isResetterVisible = computed(\n () => props.resetter !== false && (props.resetter !== undefined || slots.resetter)\n )\n\n /**\n * 操作区的整体显示状态。\n */\n const isActionsVisible = computed(\n () => isSubmitterVisible.value || isResetterVisible.value\n )\n\n /**\n * 操作区保留插槽不能下传给字段,避免与同名字段插槽冲突。\n */\n const fieldSlots = computed(() =>\n Object.fromEntries(\n Object.entries(slots).filter(\n ([slotName]) => slotName !== \"submitter\" && slotName !== \"resetter\"\n )\n )\n )\n\n /**\n * 提交按钮在 loading 或显式 disabled 时不可点击。\n */\n const isSubmitterDisabled = computed(\n () => effectiveLoading.value || Boolean(submitterButtonProps.value.disabled)\n )\n\n /**\n * 重置按钮在 loading 或显式 disabled 时不可点击。\n */\n const isResetterDisabled = computed(\n () => effectiveLoading.value || Boolean(resetterButtonProps.value.disabled)\n )\n\n let syncingFromModel = false\n\n /**\n * 记录 Core 发出的、等待标准 v-model 回传的一次性快照身份。\n */\n const internalModelEchoes = new Set<TValues>()\n\n /**\n * 发出内部模型更新,并记录等待父级原样回传的快照。\n *\n * @param values - 要发出的最新表单值快照。\n */\n const emitModelValue = (values: TValues): void => {\n const rawValues = toRaw(values)\n\n internalModelEchoes.add(rawValues)\n emit(\"update:modelValue\", values)\n\n void nextTick(() => {\n internalModelEchoes.delete(rawValues)\n })\n }\n\n /**\n * 将外部 modelValue 同步到 Core,并标记窗口以阻止 v-model 回写。\n *\n * @param values - 外部传入的最新表单值。\n */\n watch(\n () => props.modelValue,\n (values) => {\n if (internalModelEchoes.delete(toRaw(values))) {\n return\n }\n\n syncingFromModel = true\n\n try {\n formInstance.setFieldsValue(values)\n } finally {\n syncingFromModel = false\n }\n },\n { deep: true, immediate: isExternalForm }\n )\n\n /**\n * 响应提交按钮点击,并返回 Core Promise 以让 Vue 处理异常。\n */\n const handleSubmit: SchemxInstance<TValues>[\"submit\"] = () => formInstance.submit()\n\n /**\n * 响应重置按钮点击。\n */\n const handleReset = (): void => {\n formInstance.reset()\n }\n\n /**\n * 通过共享 selector bridge 订阅完整快照,避免组件树重复注册 Core 监听。\n *\n * @param values - 当前表单的完整快照。\n */\n const formValues = useFormSelector(formInstance, (values) => values)\n\n /**\n * 将 Core 值同步回 v-model;外部 modelValue 写入期间跳过回写,避免循环。\n *\n * @param latestSnapshot - Core 发布的最新完整表单快照。\n */\n watch(\n formValues,\n (latestSnapshot) => {\n if (syncingFromModel) {\n return\n }\n\n emitModelValue(latestSnapshot)\n },\n { flush: \"sync\" }\n )\n\n /**\n * 将外部传入的原始 Schema 同步更新到 Core。\n *\n * @param schemas - 最新的 props.schemas 配置。\n */\n watch(\n () => props.schemas,\n (schemas) => {\n if (!isSchemxSchemas(schemas)) {\n formInstance.setSchemas(schemas)\n }\n },\n { immediate: isExternalForm }\n )\n\n // 当前 Form 的响应式 ViewSchema 列表。\n const viewSchemas = useViewSchemas(formInstance)\n\n /**\n * 根据 ViewSchema 在当前列表中的位置生成首尾样式类。\n *\n * @param schema - 当前需要计算样式的 ViewSchema。\n * @returns 用于包裹元素的首尾位置 class 映射。\n */\n const getFieldClass = (schema: SchemxViewSchema) => {\n const { isFirst, isLast } = getSectionPosition(\n viewSchemas.value as SchemxViewSchema[],\n schema.key\n )\n\n return {\n \"schemx-field-wrapper--first\": isFirst,\n \"schemx-field-wrapper--last\": isLast,\n }\n }\n\n /**\n * 将内部 Form 的完整配置同步到 Context 和 Core。\n *\n * @param nextSchemaConfig - 合并后的完整 schema 配置。\n */\n const syncInternalSchemaConfig = (nextSchemaConfig: SchemxSchemaConfig): void => {\n formInstance.updateSchemaConfig(nextSchemaConfig)\n }\n\n /**\n * 将外部 Form 的组件级配置增量同步到 Core;Context 从响应式 props 配置派生。\n *\n * @param nextSchemaConfig - 当前组件显式配置。\n * @param previousSchemaConfig - 上一次组件显式配置,用于清理已移除的 key。\n */\n const syncExternalSchemaConfig = (\n nextSchemaConfig: Partial<SchemxSchemaConfig>,\n previousSchemaConfig: Partial<SchemxSchemaConfig> | undefined\n ): void => {\n const patch: Partial<SchemxSchemaConfig> = { ...nextSchemaConfig }\n\n if (previousSchemaConfig !== undefined) {\n for (const key of schemaConfigKeys) {\n if (\n hasSchemaConfigKey(previousSchemaConfig, key) &&\n !hasSchemaConfigKey(nextSchemaConfig, key)\n ) {\n patch[key] = undefined\n }\n }\n }\n\n if (Object.keys(patch).length > 0) {\n formInstance.updateSchemaConfig(patch)\n }\n }\n\n if (isExternalForm) {\n watch(schemaConfigProps, syncExternalSchemaConfig, {\n deep: true,\n immediate: true,\n })\n } else {\n watch(resolvedSchemaConfig, syncInternalSchemaConfig, { deep: true })\n }\n\n /**\n * 暴露当前表单 Instance 的完整控制 API,供模板 ref 调用。\n */\n const exposed: SchemxInstance<TValues> = {\n ...formInstance,\n submit: handleSubmit,\n reset: handleReset,\n }\n\n defineExpose(exposed)\n</script>\n\n<template>\n <div :class=\"formRootClass\" :style=\"formRootStyle\">\n <SchemaList\n :schemas=\"viewSchemas as SchemxViewSchema[]\"\n :view-schemas=\"viewSchemas as SchemxViewSchema[]\"\n :row-component=\"resolvedRowComponent\"\n :row-config=\"resolvedRowConfig\"\n :field-class-resolver=\"getFieldClass\"\n >\n <template v-for=\"(_, slotName) in fieldSlots\" #[slotName]=\"slotProps\">\n <slot :name=\"slotName\" v-bind=\"slotProps ?? {}\" />\n </template>\n </SchemaList>\n\n <div v-if=\"isActionsVisible\" class=\"schemx-actions\">\n <slot\n v-if=\"isResetterVisible && slots.resetter\"\n name=\"resetter\"\n :form=\"formInstance\"\n :loading=\"effectiveLoading\"\n :disabled=\"isResetterDisabled\"\n :reset=\"handleReset\"\n />\n <Button\n v-else-if=\"isResetterVisible\"\n v-bind=\"resetterButtonProps\"\n class=\"schemx-actions-button schemx-actions-button--reset\"\n type=\"button\"\n :disabled=\"isResetterDisabled\"\n @click=\"handleReset\"\n >\n {{ resetterConfig.text ?? \"重置\" }}\n </Button>\n <slot\n v-if=\"isSubmitterVisible && slots.submitter\"\n name=\"submitter\"\n :form=\"formInstance\"\n :loading=\"effectiveLoading\"\n :disabled=\"isSubmitterDisabled\"\n :submit=\"handleSubmit\"\n />\n <Button\n v-else-if=\"isSubmitterVisible\"\n v-bind=\"submitterButtonProps\"\n class=\"schemx-actions-button schemx-actions-button--submit\"\n type=\"button\"\n :loading=\"effectiveLoading\"\n :disabled=\"isSubmitterDisabled\"\n @click=\"handleSubmit\"\n >\n {{ submitterConfig.text ?? \"提交\" }}\n </Button>\n </div>\n </div>\n</template>\n","/**\n * schemx 组件导出\n *\n * 为 SchemxForm 组件挂载静态方法(install、Field、registerRequest 等),\n * 并作为默认导出。\n *\n * @module formExport\n */\n\nimport type { App } from \"vue\"\n\nimport Field from \"./components/Field\"\nimport { provideSchemxAppConfig } from \"./context/configProviderContext\"\nimport SchemxForm from \"./formRuntime.js\"\n\nimport type { SchemxConfig } from \"@schemx/core\"\n\n/**\n * SchemxForm 插件安装选项\n *\n * 在 `app.use(SchemxForm, options)` 时传入,用于配置当前 Vue App 的默认行为。\n * 安装配置不会写入 Core 的模块级全局配置,因此多个 Vue App 可以彼此隔离。\n *\n * @example\n * ```ts\n * import SchemxForm from '@schemx/vue'\n *\n * app.use(SchemxForm, {\n * schemaConfig: { readonly: true },\n * })\n * ```\n */\nexport interface SchemxInstallOptions extends SchemxConfig {}\n\n/**\n * 为组件挂载静态属性并保留原始类型\n *\n * @param comp - 原始组件\n * @param extra - 要挂载的静态属性\n * @typeParam TComponent - 原始组件类型。\n * @typeParam TExtras - 待挂载的静态属性类型。\n *\n * @example\n * ```ts\n * const Plugin = withInstall(Component, { install(app) { app.component(\"Demo\", Component) } })\n * ```\n */\nexport function withInstall<\n TComponent extends object,\n TExtras extends Record<string, unknown>,\n>(comp: TComponent, extra: TExtras) {\n return Object.assign(comp, extra) as TComponent & TExtras\n}\n\n/**\n * 挂载了 Vue 插件安装方法和 `Field` 子组件的 Form 组件类型。\n */\nexport type SchemxFormPlugin = typeof SchemxForm & {\n install: (app: App, options?: SchemxInstallOptions) => void\n Field: typeof Field\n}\n\nconst SchemxFormExport = withInstall(SchemxForm, {\n /**\n * Vue 插件安装方法\n */\n install(app: App, options: SchemxInstallOptions = {}) {\n provideSchemxAppConfig(app, options)\n app.component(\"SchemxForm\", SchemxForm)\n },\n /**\n * Field 子组件引用\n */\n Field,\n}) as unknown as SchemxFormPlugin\n\nexport default SchemxFormExport\n","/**\n * WithRemoteOptions - 选项高阶组件\n *\n * 包装任意渲染器组件,自动注入 useDictionary 的选项加载能力。\n * 被包装组件会额外收到 options、loading 两个 props,\n * 无需自行调用 useDictionary。\n *\n * @module hocs/withRemoteOptions\n */\n\nimport { Component, computed, defineComponent, h, PropType, SetupContext } from \"vue\"\n\nimport type { SchemxDictionary } from \"@/types/dictionary\"\n\nimport { useFieldContext } from \"../context/fieldContext\"\nimport { useDictionary } from \"../hooks/useDictionary\"\n\n/**\n * WithRemoteOptions 注入给被包装组件的额外 Props\n */\nexport interface RemoteOptionsInjectedProps {\n /**\n * 加载的选项列表\n */\n options: unknown[]\n /**\n * 加载状态\n */\n loading: boolean\n}\n\ntype SchemxDictionaryInput = SchemxDictionary | SchemxDictionary[\"api\"]\n\n/**\n * 将 api 简写规范化为完整的字典配置。\n *\n * @param dictionary - 完整字典配置或 api 函数简写。\n * @returns 规范化后的字典配置;未提供时返回 `undefined`。\n */\nfunction normalizeDictionary(\n dictionary: SchemxDictionaryInput | undefined\n): SchemxDictionary | undefined {\n if (typeof dictionary === \"function\") {\n return { api: dictionary }\n }\n\n return dictionary\n}\n\n/**\n * 选项高阶组件\n *\n * 包装一个渲染器组件,当 dict prop 存在时,\n * 调用 useDictionary 加载选项,并将结果作为 options prop 注入。\n *\n * 当组件自身已传入非空 options 且无 dict 时,优先使用静态 options。\n *\n * @param WrappedComponent - 被包装的渲染器组件\n * @returns 增强后的组件,自动具备选项加载能力\n *\n * @example\n * ```ts\n * import { WithRemoteOptions } from '@schemx/vue'\n * import MySelect from './MySelect.vue'\n *\n * const RemoteSelect = WithRemoteOptions(MySelect)\n *\n * // 在 schema 中使用\n * const schema = {\n * name: 'city',\n * label: '城市',\n * componentType: 'select',\n * componentProps: {\n * dict: {\n * api: async (values) => fetchCities(values.province),\n * dependsOn: ['province'],\n * shouldFetch: (values) => !!values.province,\n * resetOnDepsChange: true,\n * immediate: false,\n * },\n * },\n * }\n * ```\n */\nexport function WithRemoteOptions(WrappedComponent: Component): Component {\n return defineComponent({\n name: `WithRemoteOptions(${WrappedComponent.name || \"Anonymous\"})`,\n inheritAttrs: false,\n props: {\n dict: {\n type: [Object, Function] as PropType<SchemxDictionaryInput>,\n default: undefined,\n },\n },\n setup(props, { attrs, slots }: SetupContext) {\n const dictionary = normalizeDictionary(props.dict)\n\n // 内嵌于 Field 时自动从字段 Context 获取目标字段;显式 fieldName\n // 保留给脱离 Field 的独立使用场景。\n const fieldName = dictionary\n ? ((attrs.fieldName as string | undefined) ?? useFieldContext().name)\n : undefined\n\n const dictResult = dictionary ? useDictionary(dictionary, fieldName) : null\n\n const childrenProps = computed(() => {\n return {\n ...attrs,\n dict: dictionary,\n options: dictionary ? dictResult?.list.value : attrs.options,\n loading: dictionary ? dictResult?.loading.value : attrs.loading,\n }\n })\n\n return () => h(WrappedComponent, childrenProps.value, slots)\n },\n })\n}\n\nexport default WithRemoteOptions\n","<script setup lang=\"ts\">\n /**\n * Renderer 外层包装器。\n *\n * Wrapper 只负责 renderer 的外层属性、状态样式和 readonly 内容切换。\n * 具体控件布局与交互由 default 插槽中的子 renderer 负责。\n */\n import { computed, onMounted, ref, useAttrs, useSlots, watch } from \"vue\"\n\n interface Props {\n /**\n * 是否以只读插槽替换默认 Renderer 内容。\n */\n readonly?: boolean\n /**\n * 是否应用禁用状态样式。\n */\n disabled?: boolean\n }\n\n defineOptions({\n name: \"SchemxWrapper\",\n inheritAttrs: false,\n })\n\n const props = withDefaults(defineProps<Props>(), {\n readonly: false,\n disabled: false,\n })\n\n // 当前 Wrapper 的非组件属性。\n const attrs = useAttrs()\n\n // 用于判断是否提供只读插槽。\n const slots = useSlots()\n\n // 防止同一 Wrapper 在开发环境重复输出提示。\n const warnedReadonlySlot = ref(false)\n\n // 根据状态合并 Wrapper 根节点 class。\n const rootClass = computed(() => [\n \"schemx-wrapper\",\n attrs.class,\n props.readonly && \"schemx-wrapper--readonly\",\n props.disabled && \"schemx-wrapper--disabled\",\n ])\n\n // 转发给根节点但排除已单独处理的 class。\n const forwardedAttrs = computed(() => {\n const { class: _class, ...rest } = attrs\n\n return rest\n })\n\n /**\n * 在开发环境提示只读状态缺少 `#readonly` 插槽。\n *\n * @param readonly - 当前 Wrapper 是否处于只读状态。\n */\n const warnIfReadonlySlotIsMissing = (readonly: boolean): void => {\n if (!readonly || slots.readonly || warnedReadonlySlot.value || !import.meta.env.DEV) {\n return\n }\n\n warnedReadonlySlot.value = true\n console.warn(\"[schemx] SchemxWrapper is readonly but no #readonly slot was provided.\")\n }\n\n onMounted(() => warnIfReadonlySlotIsMissing(props.readonly))\n watch(() => props.readonly, warnIfReadonlySlotIsMissing)\n</script>\n\n<template>\n <div v-bind=\"forwardedAttrs\" :class=\"rootClass\">\n <template v-if=\"props.readonly\">\n <slot name=\"readonly\" :readonly=\"props.readonly\" :disabled=\"props.disabled\" />\n </template>\n <slot v-else :readonly=\"props.readonly\" :disabled=\"props.disabled\" />\n </div>\n</template>\n\n<style>\n .schemx-wrapper {\n box-sizing: border-box;\n width: 100%;\n }\n\n .schemx-wrapper--readonly {\n color: var(--schemx-wrapper-readonly-color, var(--schemx-readonly-color, #969799));\n cursor: default;\n }\n\n .schemx-wrapper--disabled {\n opacity: var(--schemx-disabled-opacity, 0.6);\n cursor: not-allowed;\n }\n\n .is-disabled .schemx-wrapper--disabled {\n opacity: 1;\n }\n</style>\n","/**\n * ConfigProvider - Vue 组件树级默认配置。\n *\n * 不渲染额外 DOM,只为后代 Form 提供 Vue 层配置。\n *\n * @module components/ConfigProvider\n */\n\nimport { computed, defineComponent, type PropType } from \"vue\"\n\nimport { createConfigProviderContext } from \"../../context\"\n\nimport type {\n SchemxColComponent,\n SchemxIconComponent,\n SchemxRowComponent,\n SchemxRowConfig,\n} from \"../../types\"\nimport type {\n PresetRuleRegistry,\n RendererRegistry,\n SchemxConfig,\n SchemxRendererKey,\n SchemxRendererPropsMap,\n SchemxSchemaConfig,\n ValidationAdapterOption,\n Values,\n} from \"@schemx/core\"\n\n/**\n * ConfigProvider 的公开 Props。\n *\n * 配置会按组件树继承;子级 Provider 的非空配置覆盖父级同名配置。\n *\n * @typeParam TValues - 表单值类型。\n */\nexport type ConfigProviderProps<TValues extends Values = Values> = SchemxConfig<TValues>\n\nconst ConfigProvider = defineComponent({\n name: \"SchemxConfigProvider\",\n inheritAttrs: false,\n\n props: {\n schemaConfig: {\n type: Object as PropType<Partial<SchemxSchemaConfig>>,\n default: undefined,\n },\n rendererProps: {\n type: Object as PropType<SchemxRendererPropsMap>,\n default: undefined,\n },\n validatorAdapters: {\n type: Array as PropType<readonly ValidationAdapterOption[]>,\n default: undefined,\n },\n defaultRendererType: {\n type: String as PropType<SchemxRendererKey>,\n default: undefined,\n },\n rendererRegistry: {\n type: Object as PropType<RendererRegistry>,\n default: undefined,\n },\n presetRuleRegistry: {\n type: Object as PropType<PresetRuleRegistry>,\n default: undefined,\n },\n colComponent: {\n type: [Object, Function] as PropType<SchemxColComponent>,\n default: undefined,\n },\n rowComponent: {\n type: [Object, Function] as PropType<SchemxRowComponent>,\n default: undefined,\n },\n iconComponent: {\n type: [Object, Function] as PropType<SchemxIconComponent>,\n default: undefined,\n },\n row: {\n type: Object as PropType<SchemxRowConfig>,\n default: undefined,\n },\n },\n\n /**\n * 合并 Props 与 fallthrough attrs,并向后代提供配置上下文。\n *\n * @param props - 当前 ConfigProvider 的 Schemx 配置。\n * @param setupContext - 父级传入的默认插槽与额外配置属性。\n */\n setup(props, setupContext) {\n const { slots, attrs } = setupContext\n\n const config = computed<SchemxConfig>(() => ({\n schemaConfig: props.schemaConfig,\n rendererProps: props.rendererProps,\n validatorAdapters: props.validatorAdapters,\n defaultRendererType: props.defaultRendererType,\n rendererRegistry: props.rendererRegistry,\n presetRuleRegistry: props.presetRuleRegistry,\n colComponent: props.colComponent,\n rowComponent: props.rowComponent,\n iconComponent: props.iconComponent,\n row: props.row,\n ...attrs,\n }))\n\n createConfigProviderContext(config)\n\n return () => slots.default?.()\n },\n})\n\nexport default ConfigProvider\n"],"names":["rendererRegistry","presetRuleRegistry","values","Col","defineComponent","name","inheritAttrs","props","col","type","Object","required","default","undefined","component","Function","layout","setup","setupContext","attrs","slots","formContext","useOptionalFormContextValue","resolvedComponent","computed","colComponent","markRaw","toRaw","value","block","span","configuredSpan","offset","configuredOffset","extensionProps","class","attrsClass","style","attrsStyle","restAttrs","width","marginLeft","h","flex","maxWidth","paddingTop","paddingRight","paddingBottom","paddingLeft","Icon","icon","String","useAttrs","adapter","createFieldSlotRenderers","options","schemaRef","field","form","componentProps","labelWidth","labelPosition","test","labelAlign","createSlotProps","additionalProps","schema","renderFieldSlot","suffix","slot","resolveSlot","normalizeNameKey","renderLabel","labelSlot","colon","schemaConfig","showRequiredMark","Boolean","disabled","readonly","_createVNode","textAlign","_Fragment","labelIcon","iconComponent","classnames","label","renderBefore","renderContent","rendererEntry","getRendererEntry","componentType","Error","childSlots","extractChildSlots","transformedProps","transformProps","columnElement","contentSlot","contentAlign","renderAfter","renderError","errorSlot","errors","length","_isSlot","s","prototype","toString","call","_isVNode","Field","Array","useFormContextValue","inputSchema","latestSchema","useViewSchema","key","isSchemxViewFieldSchema","useField","createFieldContext","trigger","mergeTrigger","validationTrigger","canVerified","isOperate","visible","handleChange","v","setValue","onChange","shouldValidateOn","validate","handleBlur","onBlur","updateValue","useStableRef","currentComponentProps","fieldSlot","fieldContent","fieldWrapper","_mergeProps","bordered","errorAlign","_createElementBlock","_unref","$slots","_openBlock","_renderSlot","_createTextVNode","_toDisplayString","Dynamic","rowConfig","renderChildren","row","items","map","item","children","createGroupSlotRenderers","collapsed","collapsible","toggle","slotKey","headerSlot","slotProps","renderHeaderContent","renderBodyContent","hasHeader","Group","internalCollapsed","ref","defaultCollapsed","componentId","getCurrentInstance","uid","watch","nextCollapsed","previousCollapsed","onCollapsedChange","isCollapsed","destroyOnCollapse","uniqueId","debug","runtimeNodeId","idBase","normalizeId","headerId","bodyId","renderChild","child","isViewDynamicSchema","isViewGroupSchema","renderGroupChildren","body","display","groupWrapper","e","preventDefault","Row","enabled","rowComponent","gutter","justify","align","componentAttrs","rowClassValue","justifyContent","alignItems","gutterTop","gutterRight","gutterBottom","gutterLeft","normalizeSchemxGutter","internalRowStyle","margin","SchemaList","schemas","viewSchemas","fieldClassResolver","getFieldRenderKey","renderSchema","content","_slot","_withCtx","_normalizeProps","_guardReactiveProps","_createBlock","Button","SchemxForm","ConfigProvider","rendererProps","validatorAdapters","defaultRendererType","config","createConfigProviderContext"],"mappings":"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"}