@schemx/vue 1.0.0 → 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 (121) hide show
  1. package/README.md +509 -324
  2. package/dist/analyze.html +1 -1
  3. package/dist/bridge/fieldBridge.d.ts +12 -0
  4. package/dist/bridge/fieldBridge.d.ts.map +1 -1
  5. package/dist/bridge/formBridge.d.ts +35 -2
  6. package/dist/bridge/formBridge.d.ts.map +1 -1
  7. package/dist/bridge/formInstance.d.ts +24 -4
  8. package/dist/bridge/formInstance.d.ts.map +1 -1
  9. package/dist/bridge/helpers.d.ts +8 -0
  10. package/dist/bridge/helpers.d.ts.map +1 -1
  11. package/dist/bridge/index.d.ts +2 -3
  12. package/dist/bridge/index.d.ts.map +1 -1
  13. package/dist/bridge/types.d.ts +97 -9
  14. package/dist/bridge/types.d.ts.map +1 -1
  15. package/dist/bridge/viewSchemaBridge.d.ts +14 -1
  16. package/dist/bridge/viewSchemaBridge.d.ts.map +1 -1
  17. package/dist/components/Button/index.d.ts.map +1 -1
  18. package/dist/components/Button/index.vue.d.ts +12 -0
  19. package/dist/components/Button/index.vue.d.ts.map +1 -1
  20. package/dist/components/Button/types.d.ts +15 -5
  21. package/dist/components/Button/types.d.ts.map +1 -1
  22. package/dist/components/Col/index.d.ts +27 -5
  23. package/dist/components/Col/index.d.ts.map +1 -1
  24. package/dist/components/ConfigProvider/index.d.ts +40 -7
  25. package/dist/components/ConfigProvider/index.d.ts.map +1 -1
  26. package/dist/components/Dynamic/index.d.ts +27 -17
  27. package/dist/components/Dynamic/index.d.ts.map +1 -1
  28. package/dist/components/Field/index.d.ts +13 -2
  29. package/dist/components/Field/index.d.ts.map +1 -1
  30. package/dist/components/Field/slot.d.ts +34 -10
  31. package/dist/components/Field/slot.d.ts.map +1 -1
  32. package/dist/components/Group/index.d.ts +37 -8
  33. package/dist/components/Group/index.d.ts.map +1 -1
  34. package/dist/components/Group/slot.d.ts +36 -9
  35. package/dist/components/Group/slot.d.ts.map +1 -1
  36. package/dist/components/Icon/index.d.ts +29 -0
  37. package/dist/components/Icon/index.d.ts.map +1 -0
  38. package/dist/components/Row/index.d.ts +30 -0
  39. package/dist/components/Row/index.d.ts.map +1 -0
  40. package/dist/components/SchemaList/index.d.ts +22 -12
  41. package/dist/components/SchemaList/index.d.ts.map +1 -1
  42. package/dist/components/Wrapper/index.vue.d.ts +6 -0
  43. package/dist/components/Wrapper/index.vue.d.ts.map +1 -1
  44. package/dist/config/defaultVueSchemaConfig.d.ts +62 -0
  45. package/dist/config/defaultVueSchemaConfig.d.ts.map +1 -0
  46. package/dist/config/index.d.ts +12 -2
  47. package/dist/config/index.d.ts.map +1 -1
  48. package/dist/config/vueConfig.d.ts +14 -3
  49. package/dist/config/vueConfig.d.ts.map +1 -1
  50. package/dist/context/configProviderContext.d.ts +66 -0
  51. package/dist/context/configProviderContext.d.ts.map +1 -0
  52. package/dist/context/fieldContext.d.ts +11 -0
  53. package/dist/context/fieldContext.d.ts.map +1 -0
  54. package/dist/context/formContext.d.ts +167 -0
  55. package/dist/context/formContext.d.ts.map +1 -0
  56. package/dist/context/index.d.ts +18 -0
  57. package/dist/context/index.d.ts.map +1 -0
  58. package/dist/form.d.ts +10 -2
  59. package/dist/form.d.ts.map +1 -1
  60. package/dist/hocs/withRemoteOptions.d.ts +6 -2
  61. package/dist/hocs/withRemoteOptions.d.ts.map +1 -1
  62. package/dist/hooks/index.d.ts +23 -15
  63. package/dist/hooks/index.d.ts.map +1 -1
  64. package/dist/hooks/useDictionary.d.ts +32 -9
  65. package/dist/hooks/useDictionary.d.ts.map +1 -1
  66. package/dist/hooks/useField.d.ts +7 -0
  67. package/dist/hooks/useField.d.ts.map +1 -1
  68. package/dist/hooks/useForm.d.ts +4 -16
  69. package/dist/hooks/useForm.d.ts.map +1 -1
  70. package/dist/hooks/useFormSelector.d.ts.map +1 -1
  71. package/dist/hooks/useViewSchemas.d.ts +26 -2
  72. package/dist/hooks/useViewSchemas.d.ts.map +1 -1
  73. package/dist/index.cjs +1 -1
  74. package/dist/index.cjs.map +1 -1
  75. package/dist/index.d.ts +35 -13
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.mjs +684 -357
  78. package/dist/index.mjs.map +1 -1
  79. package/dist/style.css +1 -1
  80. package/dist/types/definition.d.ts +248 -0
  81. package/dist/types/definition.d.ts.map +1 -0
  82. package/dist/types/dictionary.d.ts +9 -3
  83. package/dist/types/dictionary.d.ts.map +1 -1
  84. package/dist/types/field.d.ts +93 -21
  85. package/dist/types/field.d.ts.map +1 -1
  86. package/dist/types/form.d.ts +82 -6
  87. package/dist/types/form.d.ts.map +1 -1
  88. package/dist/types/icon.d.ts +15 -0
  89. package/dist/types/icon.d.ts.map +1 -0
  90. package/dist/types/index.d.ts +2 -15
  91. package/dist/types/index.d.ts.map +1 -1
  92. package/dist/types/layout.d.ts +89 -13
  93. package/dist/types/layout.d.ts.map +1 -1
  94. package/dist/utils/diff.d.ts +3 -6
  95. package/dist/utils/diff.d.ts.map +1 -1
  96. package/dist/utils/dynamic.d.ts +6 -2
  97. package/dist/utils/dynamic.d.ts.map +1 -1
  98. package/dist/utils/equal.d.ts +2 -2
  99. package/dist/utils/helpers.d.ts +26 -2
  100. package/dist/utils/helpers.d.ts.map +1 -1
  101. package/dist/utils/index.d.ts +19 -4
  102. package/dist/utils/index.d.ts.map +1 -1
  103. package/dist/utils/layout.d.ts +17 -0
  104. package/dist/utils/layout.d.ts.map +1 -0
  105. package/dist/utils/rendererProvider.d.ts +10 -3
  106. package/dist/utils/rendererProvider.d.ts.map +1 -1
  107. package/dist/utils/validation.d.ts +6 -2
  108. package/dist/utils/validation.d.ts.map +1 -1
  109. package/package.json +2 -2
  110. package/dist/config/appConfig.d.ts +0 -19
  111. package/dist/config/appConfig.d.ts.map +0 -1
  112. package/dist/config/providerConfig.d.ts +0 -22
  113. package/dist/config/providerConfig.d.ts.map +0 -1
  114. package/dist/hooks/provideFieldContext.d.ts +0 -40
  115. package/dist/hooks/provideFieldContext.d.ts.map +0 -1
  116. package/dist/hooks/provideFormConfigContext.d.ts +0 -71
  117. package/dist/hooks/provideFormConfigContext.d.ts.map +0 -1
  118. package/dist/hooks/provideFormContext.d.ts +0 -26
  119. package/dist/hooks/provideFormContext.d.ts.map +0 -1
  120. package/dist/utils/colProvider.d.ts +0 -20
  121. package/dist/utils/colProvider.d.ts.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import "./style.css";
2
- import { shallowRef, computed, getCurrentInstance, inject, provide, onScopeDispose, onUnmounted, ref, onMounted, watchEffect, watch, readonly, createVNode, h, createTextVNode, defineComponent, mergeProps, useAttrs, openBlock, createElementBlock, unref, renderSlot, createCommentVNode, createStaticVNode, Fragment, toDisplayString, markRaw, toRaw, isVNode, useSlots, reactive, normalizeClass, normalizeStyle, createSlots, renderList, withCtx, normalizeProps, guardReactiveProps, createBlock, nextTick } from "vue";
3
- import { isViewGroupSchema, isViewDynamicSchema, mergeSchemxConfig, createPresetRuleRegistry, createForm, createField, createWatch, isSchemxViewFieldSchema, getGlobalSchemxConfig, mergeAndResolveSchemxConfig, isSchemxSchemas, defaultSchemxConfigKeys } from "@schemx/core";
2
+ import { shallowRef, computed, getCurrentScope, onScopeDispose, provide, inject, getCurrentInstance, onUnmounted, ref, onMounted, watchEffect, watch, readonly, defineComponent, markRaw, toRaw, h, useAttrs, createVNode, Fragment, mergeProps, isVNode, openBlock, createElementBlock, unref, renderSlot, createCommentVNode, createStaticVNode, createTextVNode, toDisplayString, useSlots, normalizeClass, normalizeStyle, createSlots, renderList, withCtx, normalizeProps, guardReactiveProps, createBlock, nextTick } from "vue";
3
+ import { isViewGroupSchema, isViewDynamicSchema, mergeConfig, createPresetRuleRegistry, getGlobalSchemxConfig, createForm, createField, createWatch, isSchemxViewFieldSchema, defaultSchemxConfigKeys, resolveSchemxConfig, isSchemxSchemas } from "@schemx/core";
4
4
  export * from "@schemx/core";
5
5
  import classnames from "classnames";
6
6
  import { createFormStateAdapter, createRendererRegistry } from "@schemx/core/adapter";
@@ -169,7 +169,14 @@ function createViewSchemaIndex(viewSchemas) {
169
169
  return schemasByKey;
170
170
  }
171
171
  const runtimeCache = /* @__PURE__ */ new WeakMap();
172
- const instanceRuntimeCache = /* @__PURE__ */ new WeakMap();
172
+ function useVueFormRuntime(form) {
173
+ if (!getCurrentScope()) {
174
+ throw new Error("[schemx] useVueFormRuntime() requires an active Vue scope.");
175
+ }
176
+ const { runtime, release } = acquireVueFormRuntime(form);
177
+ onScopeDispose(release);
178
+ return runtime;
179
+ }
173
180
  function acquireVueFormRuntime(form) {
174
181
  const runtime = getOrCreateVueFormRuntime(form);
175
182
  const release = runtime.retain();
@@ -179,17 +186,13 @@ function acquireVueFormRuntime(form) {
179
186
  };
180
187
  }
181
188
  function getOrCreateVueFormRuntime(form) {
182
- const cachedByInstance = instanceRuntimeCache.get(form);
183
- if (cachedByInstance) {
184
- return cachedByInstance;
185
- }
186
189
  const cachedByCore = runtimeCache.get(form);
187
190
  if (cachedByCore) {
188
191
  return cachedByCore;
189
192
  }
190
193
  const runtime = createVueFormRuntime(form);
191
194
  runtimeCache.set(form, runtime);
192
- instanceRuntimeCache.set(runtime.instance, runtime);
195
+ runtimeCache.set(runtime.instance, runtime);
193
196
  return runtime;
194
197
  }
195
198
  function createVueFormRuntime(core) {
@@ -203,26 +206,27 @@ function createVueFormRuntime(core) {
203
206
  const pendingFields = bindSnapshotSource(stateAdapter.pendingFields);
204
207
  const loading = bindSnapshotSource(stateAdapter.loading);
205
208
  const fieldStates = /* @__PURE__ */ new Map();
206
- let viewSchemaState;
207
209
  let disposed = false;
208
210
  const dispose = () => {
211
+ var _a;
209
212
  if (disposed) {
210
213
  return;
211
214
  }
212
215
  disposed = true;
216
+ (_a = currentResources.viewSchemaState) == null ? void 0 : _a.dispose();
213
217
  fieldStates.clear();
214
218
  stateAdapter.dispose();
215
219
  };
216
- return {
220
+ const currentResources = {
217
221
  stateAdapter,
218
222
  values,
219
223
  touchedFields,
220
224
  pendingFields,
221
225
  loading,
222
226
  fieldStates,
223
- viewSchemaState,
224
227
  dispose
225
228
  };
229
+ return currentResources;
226
230
  };
227
231
  const ensureResources = () => {
228
232
  if (destroyed) {
@@ -335,22 +339,98 @@ function createVueFormRuntime(core) {
335
339
  };
336
340
  return runtime;
337
341
  }
338
- const SCHEMX_APP_CONFIG_KEY = Symbol("schemx:app-config");
339
- const EMPTY_SCHEMX_CONFIG = Object.freeze({
340
- schemaConfig: Object.freeze({}),
341
- validatorAdapters: Object.freeze([])
342
- });
342
+ const SCHEMX_FORM_INSTANCE_KEY = Symbol("schemx:instance");
343
+ const SCHEMX_FORM_CONFIG_KEY = Symbol("schemx:form-config");
344
+ function provideFormContext(context) {
345
+ const form = useVueFormRuntime(context.form).instance;
346
+ provide(SCHEMX_FORM_INSTANCE_KEY, form);
347
+ provide(SCHEMX_FORM_CONFIG_KEY, context);
348
+ return form;
349
+ }
350
+ function useFormContextValue() {
351
+ const context = useOptionalFormContextValue();
352
+ if (context) {
353
+ return context;
354
+ }
355
+ throw new Error(
356
+ "[schemx] useFormContextValue() must be called inside a <SchemxForm> descendant. Ensure provideFormContext({ form, schemaConfig }) is called synchronously during setup()."
357
+ );
358
+ }
359
+ function useOptionalFormContextValue() {
360
+ const form = inject(SCHEMX_FORM_INSTANCE_KEY, null);
361
+ const config = inject(SCHEMX_FORM_CONFIG_KEY, null);
362
+ if (form && config) {
363
+ return {
364
+ form,
365
+ get schemaConfig() {
366
+ return config.schemaConfig;
367
+ },
368
+ get iconComponent() {
369
+ return config.iconComponent;
370
+ },
371
+ get rowComponent() {
372
+ return config.rowComponent;
373
+ },
374
+ get colComponent() {
375
+ return config.colComponent;
376
+ }
377
+ };
378
+ }
379
+ return void 0;
380
+ }
381
+ function createFormContext(instance) {
382
+ const form = useVueFormRuntime(instance).instance;
383
+ provide(SCHEMX_FORM_INSTANCE_KEY, form);
384
+ return form;
385
+ }
386
+ function useFormContext() {
387
+ const instance = inject(SCHEMX_FORM_INSTANCE_KEY, null);
388
+ if (!instance) {
389
+ throw new Error(
390
+ "[schemx] useFormContext() must be called inside a <SchemxForm> descendant. Ensure provideFormContext({ form, schemaConfig }) is called synchronously during setup()."
391
+ );
392
+ }
393
+ return instance;
394
+ }
395
+ function createFormConfigContext(props) {
396
+ provide(SCHEMX_FORM_CONFIG_KEY, props);
397
+ }
398
+ function useFormConfigContext() {
399
+ const config = inject(SCHEMX_FORM_CONFIG_KEY, null);
400
+ if (!config) {
401
+ throw new Error(
402
+ "[schemx] useFormConfigContext() must be called inside a <SchemxForm> descendant. Ensure provideFormContext({ form, schemaConfig }) is called synchronously during setup()."
403
+ );
404
+ }
405
+ return config;
406
+ }
407
+ function useFormRuntimeContext() {
408
+ return useVueFormRuntime(useFormContext());
409
+ }
410
+ const SCHEMX_FIELD_CONTEXT_KEY = Symbol("schemx:field");
411
+ function createFieldContext(field) {
412
+ provide(SCHEMX_FIELD_CONTEXT_KEY, field);
413
+ }
414
+ function useFieldContext() {
415
+ const field = inject(SCHEMX_FIELD_CONTEXT_KEY, null);
416
+ if (!field) {
417
+ throw new Error(
418
+ "[schemx] useFieldContext() must be called inside a component tree where createFieldContext(field) has been called."
419
+ );
420
+ }
421
+ return field;
422
+ }
423
+ const SCHEMX_CONFIG_PROVIDER_KEY = Symbol(
424
+ "schemx:config-provider"
425
+ );
343
426
  function normalizeSchemxAppConfig(config) {
344
427
  const schemaConfig = Object.freeze({ ...config.schemaConfig ?? {} });
345
428
  const validatorAdapters = Object.freeze([...config.validatorAdapters ?? []]);
346
429
  return Object.freeze({
430
+ ...config,
347
431
  schemaConfig,
348
432
  rendererProps: normalizeRendererProps(config.rendererProps),
349
- validatorAdapters,
350
- defaultRendererType: config.defaultRendererType,
351
- rendererRegistry: config.rendererRegistry,
352
- presetRuleRegistry: config.presetRuleRegistry,
353
- colComponent: config.colComponent
433
+ validatorAdapters
354
434
  });
355
435
  }
356
436
  function normalizeRendererProps(source) {
@@ -364,33 +444,35 @@ function normalizeRendererProps(source) {
364
444
  }
365
445
  function provideSchemxAppConfig(app, config = {}) {
366
446
  const normalizedConfig = normalizeSchemxAppConfig(config);
367
- app.provide(SCHEMX_APP_CONFIG_KEY, normalizedConfig);
368
- }
369
- function getSchemxAppConfig() {
370
- if (getCurrentInstance() === null) {
371
- return EMPTY_SCHEMX_CONFIG;
372
- }
373
- return inject(SCHEMX_APP_CONFIG_KEY, EMPTY_SCHEMX_CONFIG);
447
+ app.provide(
448
+ SCHEMX_CONFIG_PROVIDER_KEY,
449
+ computed(() => normalizedConfig)
450
+ );
374
451
  }
375
- const SCHEMX_CONFIG_PROVIDER_KEY = Symbol(
376
- "schemx:config-provider"
377
- );
378
- function provideSchemxConfigProvider(config) {
452
+ function createConfigProviderContext(config) {
379
453
  const parentConfig = inject(SCHEMX_CONFIG_PROVIDER_KEY, void 0);
380
454
  const mergedConfig = computed(() => {
381
- const mergedCoreConfig = mergeSchemxConfig(config.value, (parentConfig == null ? void 0 : parentConfig.value) ?? {});
455
+ const mergedCoreConfig = mergeConfig(config.value, (parentConfig == null ? void 0 : parentConfig.value) ?? {});
456
+ const parentRow = parentConfig == null ? void 0 : parentConfig.value.row;
457
+ const localRow = config.value.row;
382
458
  return {
383
459
  ...mergedCoreConfig,
384
- colComponent: config.value.colComponent ?? (parentConfig == null ? void 0 : parentConfig.value.colComponent)
460
+ colComponent: config.value.colComponent ?? (parentConfig == null ? void 0 : parentConfig.value.colComponent),
461
+ rowComponent: config.value.rowComponent ?? (parentConfig == null ? void 0 : parentConfig.value.rowComponent),
462
+ iconComponent: config.value.iconComponent ?? (parentConfig == null ? void 0 : parentConfig.value.iconComponent),
463
+ row: localRow === void 0 ? parentRow : {
464
+ ...parentRow,
465
+ ...localRow
466
+ }
385
467
  };
386
468
  });
387
469
  provide(SCHEMX_CONFIG_PROVIDER_KEY, mergedConfig);
388
470
  }
389
- function getSchemxConfigProvider() {
471
+ function useConfigProviderContext() {
390
472
  var _a;
391
- return (_a = getSchemxConfigProviderRef()) == null ? void 0 : _a.value;
473
+ return (_a = useConfigProviderContextRef()) == null ? void 0 : _a.value;
392
474
  }
393
- function getSchemxConfigProviderRef() {
475
+ function useConfigProviderContextRef() {
394
476
  if (getCurrentInstance() === null) {
395
477
  return void 0;
396
478
  }
@@ -399,29 +481,82 @@ function getSchemxConfigProviderRef() {
399
481
  const presetRuleRegistry = createPresetRuleRegistry();
400
482
  const rendererRegistry = createRendererRegistry("input");
401
483
  function mergeVueSchemxConfig(localConfig, fallbackConfig = {}) {
402
- const providerConfig = getSchemxConfigProvider();
403
- return mergeSchemxConfig(
484
+ const providerConfig = useConfigProviderContext();
485
+ const coreConfig = getGlobalSchemxConfig();
486
+ return mergeConfig(
404
487
  localConfig,
405
488
  providerConfig ?? {},
406
- getSchemxAppConfig(),
407
489
  fallbackConfig,
490
+ coreConfig,
408
491
  {
409
492
  rendererRegistry,
410
493
  presetRuleRegistry
411
494
  }
412
495
  );
413
496
  }
497
+ const defaultVueSchemaConfig = Object.freeze({
498
+ /**
499
+ * 表单级标签图标默认值。
500
+ */
501
+ labelIcon: "",
502
+ /**
503
+ * 表单级标签对齐默认值。
504
+ */
505
+ labelAlign: "right",
506
+ /**
507
+ * 表单级标签位置默认值。
508
+ */
509
+ labelPosition: "left",
510
+ /**
511
+ * 表单级标签宽度默认值。
512
+ */
513
+ labelWidth: "auto",
514
+ /**
515
+ * 表单级内容对齐默认值。
516
+ */
517
+ contentAlign: "left",
518
+ /**
519
+ * 表单级校验错误对齐默认值。
520
+ */
521
+ errorAlign: "left",
522
+ /**
523
+ * 表单级标签冒号默认值。
524
+ */
525
+ colon: true,
526
+ /**
527
+ * 表单级必填标记默认值。
528
+ */
529
+ showRequiredMark: void 0,
530
+ /**
531
+ * 字段默认 Col 配置。
532
+ */
533
+ col: { span: 24 },
534
+ /**
535
+ * 旧版字段默认布局配置。
536
+ *
537
+ * @deprecated 请改用 {@link import("../types/layout").SchemxColConfig} 与 `col` 字段。
538
+ */
539
+ layout: { span: 24 },
540
+ /**
541
+ * 是否在 field schema 后显示底部边框。
542
+ */
543
+ bordered: true
544
+ });
545
+ const defaultVueSchemaConfigKeys = Object.keys(
546
+ defaultVueSchemaConfig
547
+ );
414
548
  function useForm(options = {}) {
415
- const configuredOptions = mergeVueSchemxConfig(getUseFormSchemxConfig(options));
549
+ const configuredOptions = mergeVueSchemxConfig(
550
+ getUseFormSchemxConfig(options),
551
+ {}
552
+ );
416
553
  const mergedOptions = {
417
554
  ...options,
418
555
  ...configuredOptions
419
556
  };
420
557
  const instance = createForm(mergedOptions);
421
- const acquired = acquireVueFormRuntime(instance);
422
- const form = acquired.runtime.instance;
558
+ const form = useVueFormRuntime(instance).instance;
423
559
  onScopeDispose(() => {
424
- acquired.release();
425
560
  form.destroy();
426
561
  });
427
562
  return form;
@@ -444,41 +579,6 @@ function getUseFormSchemxConfig(options) {
444
579
  validatorAdapters
445
580
  };
446
581
  }
447
- const SCHEMX_FORM_INSTANCE_KEY = Symbol(
448
- "schemx:instance"
449
- );
450
- const SCHEMX_FORM_RUNTIME_KEY = Symbol(
451
- "schemx:runtime"
452
- );
453
- function createFormContext(instance) {
454
- const { runtime, release } = acquireVueFormRuntime(instance);
455
- provide(
456
- SCHEMX_FORM_INSTANCE_KEY,
457
- runtime.instance
458
- );
459
- provide(SCHEMX_FORM_RUNTIME_KEY, runtime);
460
- onScopeDispose(release);
461
- return runtime.instance;
462
- }
463
- function useFormContext() {
464
- const instance = inject(SCHEMX_FORM_INSTANCE_KEY, null);
465
- if (!instance) {
466
- throw new Error(
467
- "[schemx] useFormContext() must be called inside a <SchemxForm> descendant. Ensure createFormContext(form) is called synchronously during setup()."
468
- );
469
- }
470
- return instance;
471
- }
472
- function useFormRuntimeContext() {
473
- const providedRuntime = inject(SCHEMX_FORM_RUNTIME_KEY, null);
474
- if (providedRuntime) {
475
- return providedRuntime;
476
- }
477
- const instance = useFormContext();
478
- const acquired = acquireVueFormRuntime(instance);
479
- onScopeDispose(acquired.release);
480
- return acquired.runtime;
481
- }
482
582
  function createFieldHook(form, coreForm, name, fieldState) {
483
583
  const coreField = createField(coreForm, name);
484
584
  const errors = computed(() => fieldState.errors.value);
@@ -507,27 +607,12 @@ const useField = (name) => {
507
607
  const form = useFormContext();
508
608
  const runtime = useFormRuntimeContext();
509
609
  const fieldState = runtime.getFieldState(name);
510
- return createFieldHook(form, runtime.core, name, fieldState);
610
+ return createFieldHook(form, runtime.instance, name, fieldState);
511
611
  };
512
- const SCHEMX_FORM_FIELD_KEY = Symbol(
513
- "schemx:field"
514
- );
515
- function createFieldContext(field) {
516
- provide(SCHEMX_FORM_FIELD_KEY, field);
517
- }
518
- function useFieldContext() {
519
- const field = inject(SCHEMX_FORM_FIELD_KEY);
520
- if (!field) {
521
- throw new Error(
522
- "[schemx] useFieldContext() must be called inside a component tree where createFieldContext(field) has been called."
523
- );
524
- }
525
- return field;
526
- }
527
612
  function useWatch(nameOrNamesOrCallback, callbackOrOptions, maybeOptions) {
528
613
  const runtime = useFormRuntimeContext();
529
614
  const dispose = createWatch(
530
- runtime.core,
615
+ runtime.instance,
531
616
  nameOrNamesOrCallback,
532
617
  callbackOrOptions,
533
618
  maybeOptions
@@ -692,21 +777,6 @@ function callDictionaryApi(values, form, api, signal) {
692
777
  }
693
778
  return api(values, form);
694
779
  }
695
- const SCHEMX_FORM_CONFIG_KEY = Symbol(
696
- "schemx:form-config"
697
- );
698
- const createFormConfigContext = (props) => {
699
- provide(SCHEMX_FORM_CONFIG_KEY, props);
700
- };
701
- function useFormConfigContext() {
702
- const context = inject(SCHEMX_FORM_CONFIG_KEY);
703
- if (!context) {
704
- throw new Error(
705
- "[schemx] useFormConfigContext() must be called inside a <SchemxForm> descendant. Ensure createFormConfigContext(props) is called synchronously during setup()."
706
- );
707
- }
708
- return context;
709
- }
710
780
  const isShallowEqual = (a, b) => {
711
781
  const keysA = Object.keys(a);
712
782
  const keysB = Object.keys(b);
@@ -725,24 +795,19 @@ function useStableRef(factory) {
725
795
  return stableRef;
726
796
  }
727
797
  function useViewSchemas(form) {
728
- const acquired = acquireVueFormRuntime(form);
729
- const state = acquired.runtime.getViewSchemaState();
730
- onScopeDispose(acquired.release);
798
+ const state = useVueFormRuntime(form).getViewSchemaState();
731
799
  return state.viewSchemas;
732
800
  }
733
801
  function useViewSchema(form, getKey) {
734
- const acquired = acquireVueFormRuntime(form);
735
- const state = acquired.runtime.getViewSchemaState();
802
+ const state = useVueFormRuntime(form).getViewSchemaState();
736
803
  const schema = computed(() => state.schemasByKey.value.get(getKey()));
737
- onScopeDispose(acquired.release);
738
804
  return schema;
739
805
  }
740
806
  function useFormSelector(form, selector, options = {}) {
741
- const acquired = acquireVueFormRuntime(form);
742
- const values = acquired.runtime.getValuesRef();
807
+ const values = useVueFormRuntime(form).getValuesRef();
743
808
  const selected = shallowRef(selector(values.value));
744
809
  const equals = options.equals ?? Object.is;
745
- const stop = watch(
810
+ watch(
746
811
  values,
747
812
  (values2) => {
748
813
  const next = selector(values2);
@@ -752,10 +817,6 @@ function useFormSelector(form, selector, options = {}) {
752
817
  },
753
818
  { flush: options.flush ?? "sync" }
754
819
  );
755
- onScopeDispose(() => {
756
- stop();
757
- acquired.release();
758
- });
759
820
  return readonly(selected);
760
821
  }
761
822
  function isValidTrigger(v) {
@@ -878,6 +939,146 @@ function hasPositionItemInSection(list, startIndex, step) {
878
939
  }
879
940
  return false;
880
941
  }
942
+ function normalizeSchemxGutter(gutter) {
943
+ if (gutter === void 0) {
944
+ return [0, 0, 0, 0];
945
+ }
946
+ if (typeof gutter === "number") {
947
+ return [gutter, gutter, gutter, gutter];
948
+ }
949
+ if (gutter.length === 2) {
950
+ const [vertical, horizontal] = gutter;
951
+ return [vertical, horizontal, vertical, horizontal];
952
+ }
953
+ return gutter;
954
+ }
955
+ const Col = /* @__PURE__ */ defineComponent({
956
+ name: "SchemxCol",
957
+ inheritAttrs: false,
958
+ props: {
959
+ col: {
960
+ type: Object,
961
+ required: false,
962
+ default: void 0
963
+ },
964
+ /**
965
+ * @deprecated 请在 Form 或 ConfigProvider 的 `colComponent` 中配置实现,见 {@link import("@schemx/core").SchemxConfig}。
966
+ */
967
+ component: {
968
+ type: [Object, Function],
969
+ required: false,
970
+ default: void 0
971
+ },
972
+ /**
973
+ * @deprecated 请改用 {@link import("../../types/layout").SchemxColProps.col}。
974
+ */
975
+ layout: {
976
+ type: Object,
977
+ required: false,
978
+ default: void 0
979
+ }
980
+ },
981
+ /**
982
+ * 根据 Col 配置和当前 Form Context 创建列组件。
983
+ *
984
+ * @param props - 列配置及兼容期的组件覆写属性。
985
+ * @param setupContext - 父级透传属性与默认插槽。
986
+ */
987
+ setup(props, setupContext) {
988
+ const {
989
+ attrs,
990
+ slots
991
+ } = setupContext;
992
+ const formContext = useOptionalFormContextValue();
993
+ const resolvedComponent = computed(() => {
994
+ const component = props.component ?? (formContext == null ? void 0 : formContext.colComponent);
995
+ return component ? markRaw(toRaw(component)) : void 0;
996
+ });
997
+ return () => {
998
+ const component = resolvedComponent.value;
999
+ const col = props.col ?? props.layout ?? {};
1000
+ const {
1001
+ block,
1002
+ span: configuredSpan,
1003
+ offset: configuredOffset,
1004
+ ...extensionProps
1005
+ } = col;
1006
+ const span = block ? 24 : configuredSpan ?? 24;
1007
+ const offset = block ? 0 : configuredOffset ?? 0;
1008
+ const {
1009
+ class: attrsClass,
1010
+ style: attrsStyle,
1011
+ ...restAttrs
1012
+ } = attrs;
1013
+ if (!component) {
1014
+ const width = `${span / 24 * 100}%`;
1015
+ const marginLeft = `${offset / 24 * 100}%`;
1016
+ return h("div", {
1017
+ ...restAttrs,
1018
+ class: ["schemx-col", attrsClass],
1019
+ style: [attrsStyle, {
1020
+ flex: `0 0 ${width}`,
1021
+ maxWidth: width,
1022
+ marginLeft,
1023
+ paddingTop: "var(--schemx-gutter-top, 0px)",
1024
+ paddingRight: "var(--schemx-gutter-right, 0px)",
1025
+ paddingBottom: "var(--schemx-gutter-bottom, 0px)",
1026
+ paddingLeft: "var(--schemx-gutter-left, 0px)"
1027
+ }]
1028
+ }, slots);
1029
+ }
1030
+ return h(component, {
1031
+ ...extensionProps,
1032
+ ...restAttrs,
1033
+ class: ["schemx-col", attrsClass],
1034
+ style: attrsStyle,
1035
+ span,
1036
+ offset
1037
+ }, slots);
1038
+ };
1039
+ }
1040
+ });
1041
+ const Col$1 = Col;
1042
+ const Icon = /* @__PURE__ */ defineComponent({
1043
+ name: "SchemxIcon",
1044
+ inheritAttrs: false,
1045
+ props: {
1046
+ icon: {
1047
+ type: [String, Object, Function],
1048
+ required: true
1049
+ },
1050
+ component: {
1051
+ type: [Object, Function],
1052
+ required: false,
1053
+ default: void 0
1054
+ }
1055
+ },
1056
+ /**
1057
+ * 渲染直接传入的组件,或将字符串名称交给 Icon Adapter。
1058
+ *
1059
+ * @param props - 当前图标值及可选的 Adapter 组件。
1060
+ */
1061
+ setup(props) {
1062
+ const attrs = useAttrs();
1063
+ return () => {
1064
+ if (typeof props.icon !== "string") {
1065
+ return h(markRaw(toRaw(props.icon)), attrs);
1066
+ }
1067
+ const adapter = props.component;
1068
+ if (adapter === void 0) {
1069
+ return h("span", {
1070
+ ...attrs,
1071
+ class: ["schemx-icon-text", attrs.class]
1072
+ }, props.icon);
1073
+ }
1074
+ return h(markRaw(toRaw(adapter)), {
1075
+ ...attrs,
1076
+ icon: props.icon
1077
+ });
1078
+ };
1079
+ }
1080
+ });
1081
+ const Icon$1 = Icon;
881
1082
  function createFieldSlotRenderers(options) {
882
1083
  const {
883
1084
  schemaRef,
@@ -887,15 +1088,19 @@ function createFieldSlotRenderers(options) {
887
1088
  componentProps,
888
1089
  slots
889
1090
  } = options;
890
- const renderRequired = () => {
891
- const showRequiredMark = schemaRef.value.showRequiredMark ?? Boolean(schemaRef.value.required);
892
- if (!showRequiredMark || schemaRef.value.disabled || schemaRef.value.readonly) {
893
- return null;
1091
+ const labelWidth = computed(() => {
1092
+ if (schemaRef.value.labelPosition === "top") {
1093
+ return "100%";
894
1094
  }
895
- return createVNode("span", {
896
- "class": "schemx-field__required"
897
- }, [createTextVNode("*")]);
898
- };
1095
+ const width = schemaRef.value.labelWidth ?? "auto";
1096
+ return /^\d+(?:\.\d+)?$/.test(String(width)) ? `${width}px` : width;
1097
+ });
1098
+ const labelAlign = computed(() => {
1099
+ if (schemaRef.value.labelPosition === "top") {
1100
+ return "left";
1101
+ }
1102
+ return schemaRef.value.labelAlign;
1103
+ });
899
1104
  const createSlotProps = (additionalProps = {}) => {
900
1105
  return {
901
1106
  schema: schemaRef.value,
@@ -912,54 +1117,63 @@ function createFieldSlotRenderers(options) {
912
1117
  };
913
1118
  const renderLabel = () => {
914
1119
  const labelSlot = resolveSlot(slots, `${normalizeNameKey(schemaRef.value.name)}Label`);
915
- if (labelSlot) {
916
- return labelSlot(createSlotProps());
917
- }
918
- const labelAlign = schemaRef.value.labelAlign || formContext.schemaConfig.labelAlign;
919
- const labelWidth = schemaRef.value.labelWidth || formContext.schemaConfig.labelWidth;
920
1120
  const colon = schemaRef.value.colon ?? formContext.schemaConfig.colon;
1121
+ const showRequiredMark = (schemaRef.value.showRequiredMark ?? Boolean(schemaRef.value.required)) && !schemaRef.value.disabled && !schemaRef.value.readonly;
921
1122
  return createVNode("label", {
922
1123
  "class": "schemx-field__label",
923
1124
  "style": {
924
- width: labelWidth,
925
- textAlign: labelAlign
1125
+ width: labelWidth.value,
1126
+ textAlign: labelAlign.value,
1127
+ marginLeft: labelAlign.value === "right" ? "auto" : ""
926
1128
  }
927
- }, [renderRequired(), createVNode("span", {
928
- "class": "schemx-field__label-text"
929
- }, [schemaRef.value.label, colon ? ":" : ""])]);
1129
+ }, [labelSlot ? labelSlot(createSlotProps()) : createVNode(Fragment, null, [schemaRef.value.labelIcon && createVNode("span", {
1130
+ "class": "schemx-field__label-icon"
1131
+ }, [createVNode(Icon$1, {
1132
+ "icon": schemaRef.value.labelIcon,
1133
+ "component": formContext.iconComponent
1134
+ }, null)]), createVNode("span", {
1135
+ "class": classnames("schemx-field__label-text", {
1136
+ "is-required": showRequiredMark
1137
+ })
1138
+ }, [schemaRef.value.label, colon ? ":" : ""])])]);
930
1139
  };
931
1140
  const renderBefore = () => renderFieldSlot("Before");
932
1141
  const renderContent = () => {
933
- const component = form.getRenderer(schemaRef.value.componentType);
934
- if (!component) {
1142
+ const rendererEntry = form.getRendererEntry(schemaRef.value.componentType);
1143
+ if (!rendererEntry) {
935
1144
  throw new Error(`[schemx] Can not find component renderer of "${schemaRef.value.componentType}".`);
936
1145
  }
937
1146
  const childSlots = extractChildSlots(normalizeNameKey(schemaRef.value.name), slots);
938
- const columnElement = h(component, componentProps.value, childSlots);
1147
+ const transformedProps = rendererEntry.transformProps ? rendererEntry.transformProps(componentProps.value, {
1148
+ schema: schemaRef.value,
1149
+ form
1150
+ }) : componentProps.value;
1151
+ const columnElement = h(rendererEntry.component, transformedProps, childSlots);
939
1152
  const contentSlot = resolveSlot(slots, `${normalizeNameKey(schemaRef.value.name)}Content`);
940
- if (contentSlot) {
941
- return contentSlot(createSlotProps({
942
- columnElement
943
- }));
944
- }
945
1153
  return createVNode("div", {
946
- "class": "schemx-field__control"
947
- }, [columnElement]);
1154
+ "class": "schemx-field__content",
1155
+ "style": {
1156
+ textAlign: schemaRef.value.contentAlign
1157
+ }
1158
+ }, [contentSlot ? contentSlot(createSlotProps({
1159
+ columnElement
1160
+ })) : columnElement]);
948
1161
  };
949
1162
  const renderAfter = () => renderFieldSlot("After");
950
1163
  const renderError = () => {
1164
+ var _a;
951
1165
  const errorSlot = resolveSlot(slots, `${normalizeNameKey(schemaRef.value.name)}Error`);
952
- if (errorSlot) {
953
- return errorSlot(createSlotProps({
954
- errors: field.errors.value
955
- }));
956
- }
957
- if (field.errors.value.length === 0) {
1166
+ if (!errorSlot && field.errors.value.length === 0) {
958
1167
  return null;
959
1168
  }
960
1169
  return createVNode("div", {
961
- "class": "schemx-field__error"
962
- }, [field.errors.value[0]]);
1170
+ "class": "schemx-field__error",
1171
+ "style": {
1172
+ marginLeft: ((_a = schemaRef.value) == null ? void 0 : _a.labelPosition) === "top" ? "8px" : `calc(${labelWidth.value} + var(--schemx-field-gap))`
1173
+ }
1174
+ }, [errorSlot ? errorSlot(createSlotProps({
1175
+ errors: field.errors.value
1176
+ })) : field.errors.value[0]]);
963
1177
  };
964
1178
  return {
965
1179
  createSlotProps,
@@ -970,6 +1184,9 @@ function createFieldSlotRenderers(options) {
970
1184
  renderLabel
971
1185
  };
972
1186
  }
1187
+ function _isSlot$3(s) {
1188
+ return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
1189
+ }
973
1190
  const Field = /* @__PURE__ */ defineComponent({
974
1191
  name: "SchemxField",
975
1192
  inheritAttrs: false,
@@ -989,49 +1206,50 @@ const Field = /* @__PURE__ */ defineComponent({
989
1206
  default: void 0
990
1207
  }
991
1208
  },
1209
+ slots: Object,
992
1210
  /**
993
1211
  * 初始化字段上下文,并组合响应式 schema、校验处理器与插槽渲染器。
994
1212
  *
995
- * @param props - 当前字段项的 schema 属性。
996
- * @param attrs - Vue setup 上下文提供的透传属性。
997
- * @param slots - Vue setup 上下文提供的插槽集合。
1213
+ * @param props - 当前字段项的 Schema、class 和 style。
1214
+ * @param setupContext - Vue setup 上下文,包含透传属性和字段插槽。
998
1215
  */
999
- setup(props, {
1000
- attrs,
1001
- slots
1002
- }) {
1003
- const form = useFormContext();
1216
+ setup(props, setupContext) {
1217
+ const {
1218
+ attrs,
1219
+ slots
1220
+ } = setupContext;
1221
+ const formContext = useFormContextValue();
1222
+ const form = formContext.form;
1004
1223
  const inputSchema = computed(() => props.schema);
1005
1224
  const latestSchema = useViewSchema(form, () => inputSchema.value.key);
1006
1225
  const schemaRef = computed(() => {
1007
1226
  return latestSchema.value && isSchemxViewFieldSchema(latestSchema.value) ? latestSchema.value : inputSchema.value;
1008
1227
  });
1009
- const formContext = useFormConfigContext();
1010
1228
  const field = useField(schemaRef.value.name);
1011
1229
  createFieldContext(field);
1012
1230
  const trigger = computed(() => mergeTrigger(schemaRef.value.validationTrigger, formContext.schemaConfig.validationTrigger, "onChange"));
1013
1231
  const canVerified = computed(() => {
1014
1232
  const isOperate = schemaRef.value.visible !== false && !schemaRef.value.readonly && !schemaRef.value.disabled;
1015
- const rules = schemaRef.value.rules;
1016
- const hasRules = Array.isArray(rules) ? (rules == null ? void 0 : rules.length) > 0 : !!schemaRef.value.rules;
1017
- return isOperate && (Boolean(schemaRef.value.required) || hasRules);
1233
+ return isOperate;
1018
1234
  });
1019
1235
  const handleChange = (v) => {
1020
- var _a, _b;
1236
+ var _a, _b, _c, _d;
1021
1237
  field.setValue(v);
1022
1238
  (_b = (_a = schemaRef.value.componentProps) == null ? void 0 : _a.onChange) == null ? void 0 : _b.call(_a, v);
1239
+ (_d = (_c = schemaRef.value).onChange) == null ? void 0 : _d.call(_c, v, form);
1023
1240
  if (canVerified.value && shouldValidateOn("change", trigger.value)) {
1024
1241
  field.validate();
1025
1242
  }
1026
1243
  };
1027
1244
  const handleBlur = (v) => {
1028
- var _a, _b;
1245
+ var _a, _b, _c, _d;
1029
1246
  (_b = (_a = schemaRef.value.componentProps) == null ? void 0 : _a.onBlur) == null ? void 0 : _b.call(_a, v);
1247
+ (_d = (_c = schemaRef.value).onBlur) == null ? void 0 : _d.call(_c, form);
1030
1248
  if (canVerified.value && shouldValidateOn("blur", trigger.value)) {
1031
1249
  field.validate();
1032
1250
  }
1033
1251
  };
1034
- const handleValueUpdate = (v) => {
1252
+ const updateValue = (v) => {
1035
1253
  field.setValue(v);
1036
1254
  };
1037
1255
  const componentProps = useStableRef(() => {
@@ -1041,7 +1259,7 @@ const Field = /* @__PURE__ */ defineComponent({
1041
1259
  value: field.value.value,
1042
1260
  onChange: handleChange,
1043
1261
  onBlur: handleBlur,
1044
- "onUpdate:value": handleValueUpdate
1262
+ "onUpdate:value": updateValue
1045
1263
  };
1046
1264
  });
1047
1265
  const {
@@ -1064,19 +1282,25 @@ const Field = /* @__PURE__ */ defineComponent({
1064
1282
  return null;
1065
1283
  }
1066
1284
  const fieldSlot = resolveSlot(slots, normalizeNameKey(schemaRef.value.name));
1067
- const labelPosition = schemaRef.value.labelPosition || formContext.schemaConfig.labelPosition;
1285
+ const labelPosition = schemaRef.value.labelPosition;
1068
1286
  const fieldContent = fieldSlot ? fieldSlot(createSlotProps()) : createVNode("div", {
1069
1287
  "class": classnames("schemx-field", `schemx-field--label-${labelPosition}`, {
1070
1288
  "is-readonly": schemaRef.value.readonly,
1071
1289
  "is-disabled": schemaRef.value.disabled
1072
1290
  })
1073
- }, [renderLabel(), createVNode("div", {
1074
- "class": "schemx-field__content"
1075
- }, [renderBefore(), renderContent(), renderAfter(), renderError()])]);
1076
- return createVNode("div", mergeProps(attrs, {
1077
- "class": classnames("schemx-field-wrapper", props.class, attrs.class, schemaRef.value.class),
1078
- "style": [attrs.style, props.style, schemaRef.value.style]
1079
- }), [fieldContent]);
1291
+ }, [renderLabel(), renderContent()]);
1292
+ const fieldWrapper = createVNode("div", mergeProps(attrs, {
1293
+ "class": classnames("schemx-field-wrapper", props.class, attrs.class, schemaRef.value.class, schemaRef.value.bordered ? "is-bordered" : ""),
1294
+ "style": [attrs.style, props.style, schemaRef.value.style, {
1295
+ "--schemx-content-align": schemaRef.value.contentAlign,
1296
+ "--schemx-error-align": schemaRef.value.errorAlign ?? formContext.schemaConfig.errorAlign ?? "left"
1297
+ }]
1298
+ }), [renderBefore(), fieldContent, renderError(), renderAfter()]);
1299
+ return createVNode(Col$1, {
1300
+ "col": schemaRef.value.col ?? schemaRef.value.layout
1301
+ }, _isSlot$3(fieldWrapper) ? fieldWrapper : {
1302
+ default: () => [fieldWrapper]
1303
+ });
1080
1304
  };
1081
1305
  }
1082
1306
  });
@@ -1140,58 +1364,59 @@ const _sfc_main$2 = /* @__PURE__ */ defineComponent({
1140
1364
  };
1141
1365
  }
1142
1366
  });
1143
- const registeredColComponent = shallowRef();
1144
- function registerCol(component) {
1145
- registeredColComponent.value = component;
1367
+ function _isSlot$2(s) {
1368
+ return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
1146
1369
  }
1147
- const Col = /* @__PURE__ */ defineComponent({
1148
- name: "SchemxCol",
1370
+ const Dynamic = /* @__PURE__ */ defineComponent({
1371
+ name: "SchemxDynamic",
1149
1372
  inheritAttrs: false,
1150
1373
  props: {
1151
- layout: {
1374
+ schema: {
1152
1375
  type: Object,
1153
- required: false,
1154
- default: void 0
1376
+ required: true
1155
1377
  },
1156
- component: {
1157
- type: [Object, Function],
1378
+ rowConfig: {
1379
+ type: Object,
1158
1380
  required: false,
1159
1381
  default: void 0
1382
+ },
1383
+ renderChildren: {
1384
+ type: Function,
1385
+ required: true
1160
1386
  }
1161
1387
  },
1162
- setup(props, {
1163
- attrs,
1164
- slots
1165
- }) {
1166
- const resolvedComponent = computed(() => {
1167
- const component = props.component ?? registeredColComponent.value;
1168
- return component ? markRaw(toRaw(component)) : void 0;
1169
- });
1388
+ /**
1389
+ * 初始化 Dynamic 的行模板渲染器。
1390
+ *
1391
+ * @param props - 当前 Dynamic ViewSchema、继承的 Row 配置和子级渲染回调。
1392
+ */
1393
+ setup(props) {
1170
1394
  return () => {
1171
- var _a;
1172
- const component = resolvedComponent.value;
1173
- if (!component) {
1174
- return ((_a = slots.default) == null ? void 0 : _a.call(slots)) ?? null;
1395
+ if (props.schema.visible === false) {
1396
+ return null;
1175
1397
  }
1176
- const layout = props.layout ?? {};
1177
- const span = layout.block ? 24 : layout.span ?? 24;
1178
- const offset = layout.block ? 0 : layout.offset ?? 0;
1179
- const {
1180
- class: attrsClass,
1181
- style: attrsStyle,
1182
- ...restAttrs
1183
- } = attrs;
1184
- return h(component, {
1185
- ...restAttrs,
1186
- class: ["schemx-col", attrsClass],
1187
- style: attrsStyle,
1188
- span,
1189
- offset
1190
- }, slots);
1398
+ const rowConfig = props.rowConfig || props.schema.row ? {
1399
+ ...props.rowConfig,
1400
+ ...props.schema.row
1401
+ } : void 0;
1402
+ const items = props.schema.items.map((item) => {
1403
+ const children = rowConfig === void 0 ? props.renderChildren(item.children) : props.renderChildren(item.children, rowConfig);
1404
+ return createVNode(Fragment, {
1405
+ "key": item.key
1406
+ }, [children]);
1407
+ });
1408
+ if (!props.schema.layout) {
1409
+ return items;
1410
+ }
1411
+ return createVNode(Col$1, {
1412
+ "col": props.schema.layout
1413
+ }, _isSlot$2(items) ? items : {
1414
+ default: () => [items]
1415
+ });
1191
1416
  };
1192
1417
  }
1193
1418
  });
1194
- const Col$1 = Col;
1419
+ const Dynamic$1 = Dynamic;
1195
1420
  function createGroupSlotRenderers(options) {
1196
1421
  const {
1197
1422
  schema,
@@ -1243,6 +1468,9 @@ function createGroupSlotRenderers(options) {
1243
1468
  renderHeaderContent
1244
1469
  };
1245
1470
  }
1471
+ function _isSlot$1(s) {
1472
+ return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
1473
+ }
1246
1474
  const Group = /* @__PURE__ */ defineComponent({
1247
1475
  name: "SchemxGroup",
1248
1476
  inheritAttrs: false,
@@ -1251,6 +1479,11 @@ const Group = /* @__PURE__ */ defineComponent({
1251
1479
  type: Object,
1252
1480
  required: true
1253
1481
  },
1482
+ rowConfig: {
1483
+ type: Object,
1484
+ required: false,
1485
+ default: void 0
1486
+ },
1254
1487
  class: {
1255
1488
  type: [String, Object, Array, Boolean],
1256
1489
  required: false,
@@ -1267,11 +1500,19 @@ const Group = /* @__PURE__ */ defineComponent({
1267
1500
  default: void 0
1268
1501
  }
1269
1502
  },
1270
- setup(props, {
1271
- attrs,
1272
- slots
1273
- }) {
1503
+ slots: Object,
1504
+ /**
1505
+ * 组合 Group 的折叠状态、子级渲染和插槽内容。
1506
+ *
1507
+ * @param props - 当前 Group Schema、布局和兼容渲染回调。
1508
+ * @param setupContext - 父级透传属性与 Group 插槽。
1509
+ */
1510
+ setup(props, setupContext) {
1274
1511
  var _a;
1512
+ const {
1513
+ attrs,
1514
+ slots
1515
+ } = setupContext;
1275
1516
  const internalCollapsed = ref(Boolean(props.schema.defaultCollapsed));
1276
1517
  const collapsed = computed(() => props.schema.collapsed ?? internalCollapsed.value);
1277
1518
  const componentId = ((_a = getCurrentInstance()) == null ? void 0 : _a.uid) ?? 0;
@@ -1306,12 +1547,16 @@ const Group = /* @__PURE__ */ defineComponent({
1306
1547
  const idBase = `schemx-group-${uniqueId}-${normalizeId(schema.key)}`;
1307
1548
  const headerId = `${idBase}-header`;
1308
1549
  const bodyId = `${idBase}-body`;
1550
+ const rowConfig = props.rowConfig || schema.row ? {
1551
+ ...props.rowConfig,
1552
+ ...schema.row
1553
+ } : void 0;
1309
1554
  const renderChild = (child) => {
1310
1555
  if (isViewDynamicSchema(child)) {
1311
1556
  if (child.visible === false) {
1312
1557
  return null;
1313
1558
  }
1314
- return child.items.map((item) => item.children.map((itemChild) => renderChild(itemChild)));
1559
+ return child.items.map((item) => item.children.map(renderChild));
1315
1560
  }
1316
1561
  if (isViewGroupSchema(child)) {
1317
1562
  return createVNode(Group, {
@@ -1326,6 +1571,12 @@ const Group = /* @__PURE__ */ defineComponent({
1326
1571
  "schema": child
1327
1572
  }, slots);
1328
1573
  };
1574
+ const renderGroupChildren = () => {
1575
+ if (!props.renderChildren) {
1576
+ return schema.children.map(renderChild);
1577
+ }
1578
+ return rowConfig === void 0 ? props.renderChildren(schema.children) : props.renderChildren(schema.children, rowConfig);
1579
+ };
1329
1580
  const {
1330
1581
  hasHeader,
1331
1582
  renderBodyContent,
@@ -1338,7 +1589,7 @@ const Group = /* @__PURE__ */ defineComponent({
1338
1589
  readonly: Boolean(schema.readonly),
1339
1590
  toggle,
1340
1591
  slots,
1341
- renderChildren: () => props.renderChildren ? props.renderChildren(schema.children) : schema.children.map(renderChild)
1592
+ renderChildren: renderGroupChildren
1342
1593
  });
1343
1594
  const body = createVNode("div", {
1344
1595
  "id": bodyId,
@@ -1350,7 +1601,7 @@ const Group = /* @__PURE__ */ defineComponent({
1350
1601
  display: "none"
1351
1602
  } : void 0
1352
1603
  }, [renderBodyContent()]);
1353
- return createVNode("div", mergeProps(attrs, {
1604
+ const groupWrapper = createVNode("div", mergeProps(attrs, {
1354
1605
  "class": classnames("schemx-group-wrapper", props.class, attrs.class, schema.class),
1355
1606
  "data-key": schema.key,
1356
1607
  "aria-disabled": schema.disabled || void 0,
@@ -1379,76 +1630,106 @@ const Group = /* @__PURE__ */ defineComponent({
1379
1630
  }
1380
1631
  }
1381
1632
  }, [renderHeaderContent()]), destroyOnCollapse ? !isCollapsed && body : body])]);
1633
+ if (!schema.layout) {
1634
+ return groupWrapper;
1635
+ }
1636
+ return createVNode(Col$1, {
1637
+ "col": schema.layout
1638
+ }, _isSlot$1(groupWrapper) ? groupWrapper : {
1639
+ default: () => [groupWrapper]
1640
+ });
1382
1641
  };
1383
1642
  }
1384
1643
  });
1385
1644
  const Group$1 = Group;
1386
- const Dynamic = /* @__PURE__ */ defineComponent({
1387
- name: "SchemxDynamic",
1645
+ const Row = /* @__PURE__ */ defineComponent({
1646
+ name: "SchemxRow",
1388
1647
  inheritAttrs: false,
1389
1648
  props: {
1390
- schema: {
1649
+ row: {
1391
1650
  type: Object,
1392
- required: true
1393
- },
1394
- viewSchemas: {
1395
- type: Array,
1396
- required: true
1397
- },
1398
- renderChildren: {
1399
- type: Function,
1400
1651
  required: false,
1401
1652
  default: void 0
1653
+ },
1654
+ enabled: {
1655
+ type: Boolean,
1656
+ required: false,
1657
+ default: true
1402
1658
  }
1403
1659
  },
1404
1660
  /**
1405
- * 初始化 Dynamic 的行模板渲染器。
1661
+ * 根据 Row 配置和当前 Form Context 创建行容器。
1406
1662
  *
1407
- * @param props - 当前 Dynamic ViewSchema 与 Form 根级 ViewSchema。
1408
- * @param slots - 父级透传的字段插槽。
1663
+ * @param props - Row 配置与启用状态。
1664
+ * @param setupContext - 父级透传属性与默认插槽。
1409
1665
  */
1410
- setup(props, {
1411
- slots
1412
- }) {
1413
- const getFieldRenderKey = (schema) => `${schema.key}:${normalizeNameKey(schema.name)}`;
1414
- const getFieldClass = (schema) => {
1666
+ setup(props, setupContext) {
1667
+ const {
1668
+ attrs,
1669
+ slots
1670
+ } = setupContext;
1671
+ const formContext = useOptionalFormContextValue();
1672
+ const resolvedComponent = computed(() => {
1673
+ const component = formContext == null ? void 0 : formContext.rowComponent;
1674
+ return component ? markRaw(toRaw(component)) : void 0;
1675
+ });
1676
+ return () => {
1677
+ var _a, _b;
1678
+ const component = resolvedComponent.value;
1679
+ const row = props.row ?? {};
1415
1680
  const {
1416
- isFirst,
1417
- isLast
1418
- } = getSectionPosition(props.viewSchemas, schema.key);
1419
- return {
1420
- "schemx-field-wrapper--first": isFirst,
1421
- "schemx-field-wrapper--last": isLast
1681
+ gutter,
1682
+ justify,
1683
+ align,
1684
+ ...extensionProps
1685
+ } = row;
1686
+ const {
1687
+ class: attrsClass,
1688
+ style: attrsStyle,
1689
+ ...restAttrs
1690
+ } = attrs;
1691
+ const componentAttrs = {
1692
+ ...extensionProps,
1693
+ ...restAttrs
1422
1694
  };
1423
- };
1424
- const renderItemSchema = (schema) => {
1425
- if (isViewGroupSchema(schema)) {
1426
- return createVNode(Group$1, {
1427
- "key": schema.key,
1428
- "schema": schema
1429
- }, slots);
1695
+ const rowClassValue = ["schemx-row", attrsClass];
1696
+ const justifyContent = justify === "start" ? "flex-start" : justify === "end" ? "flex-end" : justify;
1697
+ const alignItems = align === "top" ? "flex-start" : align === "middle" ? "center" : align === "bottom" ? "flex-end" : void 0;
1698
+ const [gutterTop, gutterRight, gutterBottom, gutterLeft] = normalizeSchemxGutter(gutter);
1699
+ const paddingTop = gutterTop / 2;
1700
+ const paddingRight = gutterRight / 2;
1701
+ const paddingBottom = gutterBottom / 2;
1702
+ const paddingLeft = gutterLeft / 2;
1703
+ const internalRowStyle = [attrsStyle, {
1704
+ "--schemx-gutter-top": `${paddingTop}px`,
1705
+ "--schemx-gutter-right": `${paddingRight}px`,
1706
+ "--schemx-gutter-bottom": `${paddingBottom}px`,
1707
+ "--schemx-gutter-left": `${paddingLeft}px`,
1708
+ margin: `-${paddingTop}px -${paddingRight}px -${paddingBottom}px -${paddingLeft}px`,
1709
+ justifyContent,
1710
+ alignItems
1711
+ }];
1712
+ if (!props.enabled) {
1713
+ return ((_a = slots.default) == null ? void 0 : _a.call(slots)) ?? null;
1430
1714
  }
1431
- const field = schema;
1432
- return createVNode(Field$1, {
1433
- "key": getFieldRenderKey(field),
1434
- "schema": field,
1435
- "class": getFieldClass(field)
1436
- }, slots);
1437
- };
1438
- return () => {
1439
- if (props.schema.visible === false) {
1440
- return null;
1715
+ if (!component) {
1716
+ return createVNode("div", mergeProps(restAttrs, {
1717
+ "class": rowClassValue,
1718
+ "style": internalRowStyle
1719
+ }), [(_b = slots.default) == null ? void 0 : _b.call(slots)]);
1441
1720
  }
1442
- return props.schema.items.map((item) => {
1443
- const children = props.renderChildren ? props.renderChildren(item.children) : item.children.map(renderItemSchema);
1444
- return createVNode(Fragment, {
1445
- "key": item.key
1446
- }, [children]);
1447
- });
1721
+ return h(component, {
1722
+ ...componentAttrs,
1723
+ gutter,
1724
+ justify,
1725
+ align,
1726
+ class: rowClassValue,
1727
+ style: internalRowStyle
1728
+ }, slots);
1448
1729
  };
1449
1730
  }
1450
1731
  });
1451
- const Dynamic$1 = Dynamic;
1732
+ const Row$1 = Row;
1452
1733
  function _isSlot(s) {
1453
1734
  return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
1454
1735
  }
@@ -1464,8 +1745,8 @@ const SchemaList = /* @__PURE__ */ defineComponent({
1464
1745
  type: Array,
1465
1746
  required: true
1466
1747
  },
1467
- colComponent: {
1468
- type: [Object, Function],
1748
+ rowConfig: {
1749
+ type: Object,
1469
1750
  required: false,
1470
1751
  default: void 0
1471
1752
  },
@@ -1479,17 +1760,12 @@ const SchemaList = /* @__PURE__ */ defineComponent({
1479
1760
  slots
1480
1761
  }) {
1481
1762
  const getFieldRenderKey = (schema) => `${schema.key}:${normalizeNameKey(schema.name)}`;
1482
- const getSchemaRenderKey = (schema) => {
1483
- if (isSchemxViewFieldSchema(schema)) {
1484
- return getFieldRenderKey(schema);
1485
- }
1486
- return schema.key;
1487
- };
1488
- const renderChildren = (schemas) => {
1763
+ const renderChildren = (schemas, rowConfig = props.rowConfig) => {
1489
1764
  return h(SchemaList, {
1490
1765
  schemas,
1491
1766
  viewSchemas: props.viewSchemas,
1492
- colComponent: props.colComponent
1767
+ rowConfig,
1768
+ fieldClassResolver: props.fieldClassResolver
1493
1769
  }, slots);
1494
1770
  };
1495
1771
  const renderSchema = (schema) => {
@@ -1502,13 +1778,14 @@ const SchemaList = /* @__PURE__ */ defineComponent({
1502
1778
  content = createVNode(Group$1, {
1503
1779
  "key": schema.key,
1504
1780
  "schema": schema,
1781
+ "rowConfig": props.rowConfig,
1505
1782
  "renderChildren": renderChildren
1506
1783
  }, slots);
1507
1784
  } else if (isViewDynamicSchema(schema)) {
1508
1785
  content = createVNode(Dynamic$1, {
1509
1786
  "key": schema.key,
1510
1787
  "schema": schema,
1511
- "viewSchemas": props.viewSchemas,
1788
+ "rowConfig": props.rowConfig,
1512
1789
  "renderChildren": renderChildren
1513
1790
  }, slots);
1514
1791
  } else {
@@ -1518,25 +1795,16 @@ const SchemaList = /* @__PURE__ */ defineComponent({
1518
1795
  "class": (_a = props.fieldClassResolver) == null ? void 0 : _a.call(props, schema)
1519
1796
  }, slots);
1520
1797
  }
1521
- if (!props.colComponent) {
1522
- return content;
1523
- }
1524
- return createVNode(Col$1, {
1525
- "key": getSchemaRenderKey(schema),
1526
- "component": props.colComponent,
1527
- "layout": schema.layout
1528
- }, _isSlot(content) ? content : {
1529
- default: () => [content]
1530
- });
1798
+ return content;
1531
1799
  };
1532
1800
  return () => {
1533
- const children = props.schemas.map(renderSchema);
1534
- if (!props.colComponent) {
1535
- return children;
1536
- }
1537
- return createVNode("div", {
1538
- "class": "schemx-row"
1539
- }, [children]);
1801
+ let _slot;
1802
+ return createVNode(Row$1, {
1803
+ "row": props.rowConfig,
1804
+ "class": "schemx-schema-list"
1805
+ }, _isSlot(_slot = props.schemas.map(renderSchema)) ? _slot : {
1806
+ default: () => [_slot]
1807
+ });
1540
1808
  };
1541
1809
  }
1542
1810
  });
@@ -1554,12 +1822,12 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
1554
1822
  initialValues: { default: () => ({}) },
1555
1823
  modelValue: { default: () => ({}) },
1556
1824
  form: { default: void 0 },
1825
+ row: { default: void 0 },
1557
1826
  loading: { type: Boolean, default: void 0 },
1558
1827
  submitter: { type: [Boolean, Object], default: true },
1559
1828
  resetter: { type: [Boolean, Object], default: true },
1560
1829
  class: { type: [Boolean, null, String, Object, Array], default: "" },
1561
1830
  style: { type: [Boolean, null, String, Object, Array], default: () => ({}) },
1562
- colComponent: { default: void 0 },
1563
1831
  rendererProps: { default: void 0 },
1564
1832
  validatorAdapters: {},
1565
1833
  defaultRendererType: {},
@@ -1579,33 +1847,40 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
1579
1847
  readonly: { type: Boolean, default: void 0 },
1580
1848
  disabled: { type: Boolean, default: void 0 },
1581
1849
  visible: { type: Boolean, default: void 0 },
1850
+ colComponent: { default: void 0 },
1851
+ rowComponent: { default: void 0 },
1852
+ iconComponent: { default: void 0 },
1853
+ col: { default: void 0 },
1854
+ layout: {},
1582
1855
  labelIcon: {},
1583
1856
  labelAlign: {},
1584
1857
  labelPosition: {},
1585
1858
  labelWidth: {},
1586
1859
  contentAlign: {},
1860
+ errorAlign: {},
1587
1861
  validationTrigger: { default: void 0 },
1588
1862
  colon: { type: Boolean, default: void 0 },
1589
- showRequiredMark: { type: Boolean, default: void 0 }
1863
+ showRequiredMark: { type: Boolean, default: void 0 },
1864
+ bordered: { type: Boolean, default: void 0 }
1590
1865
  },
1591
1866
  emits: ["update:modelValue"],
1592
1867
  setup(__props, { expose: __expose, emit: __emit }) {
1593
1868
  const props = __props;
1594
1869
  const emit = __emit;
1595
1870
  const slots = useSlots();
1871
+ const schemaConfigKeys = [
1872
+ ...defaultSchemxConfigKeys,
1873
+ ...defaultVueSchemaConfigKeys
1874
+ ];
1596
1875
  const pickSchemaConfig = () => {
1597
- const schemaConfig = pick(
1598
- props,
1599
- defaultSchemxConfigKeys
1600
- );
1876
+ const schemaConfig = pick(props, schemaConfigKeys);
1601
1877
  return Object.fromEntries(
1602
1878
  Object.entries(schemaConfig).filter(([, value]) => value !== void 0)
1603
1879
  );
1604
1880
  };
1605
1881
  const isExternalForm = props.form !== void 0;
1606
1882
  const schemaConfigProps = computed(pickSchemaConfig);
1607
- const appConfig = getSchemxAppConfig();
1608
- const providerConfig = getSchemxConfigProviderRef();
1883
+ const providerConfig = useConfigProviderContextRef();
1609
1884
  const coreConfig = getGlobalSchemxConfig();
1610
1885
  const formFallbackConfig = {
1611
1886
  schemaConfig: {
@@ -1613,45 +1888,48 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
1613
1888
  validationTrigger: ["blur", "change"]
1614
1889
  }
1615
1890
  };
1616
- const contextSchemaConfig = computed(() => {
1617
- const mergedConfig = isExternalForm ? mergeSchemxConfig({ schemaConfig: schemaConfigProps.value }, formFallbackConfig) : mergeSchemxConfig(
1891
+ const mergedConfig = computed(
1892
+ () => isExternalForm ? mergeConfig(
1618
1893
  { schemaConfig: schemaConfigProps.value },
1619
- (providerConfig == null ? void 0 : providerConfig.value) ?? {},
1620
- appConfig,
1621
1894
  formFallbackConfig
1622
- );
1623
- return mergedConfig.schemaConfig ?? {};
1624
- });
1625
- const resolvedSchemaConfig = computed(
1626
- () => mergeAndResolveSchemxConfig(
1895
+ ) : mergeConfig(
1627
1896
  { schemaConfig: schemaConfigProps.value },
1628
1897
  (providerConfig == null ? void 0 : providerConfig.value) ?? {},
1629
- appConfig,
1630
1898
  formFallbackConfig,
1631
1899
  coreConfig
1632
- ).schemaConfig
1900
+ )
1633
1901
  );
1634
- const initialContextSchemaConfig = contextSchemaConfig.value;
1635
- const initialCoreSchemaConfig = isExternalForm ? initialContextSchemaConfig : resolvedSchemaConfig.value;
1636
- const formSchemaConfig = reactive(
1637
- initialContextSchemaConfig
1902
+ const contextSchemaConfig = computed(() => ({
1903
+ ...defaultVueSchemaConfig,
1904
+ ...mergedConfig.value.schemaConfig
1905
+ }));
1906
+ const resolvedSchemaConfig = computed(
1907
+ () => resolveSchemxConfig({ schemaConfig: contextSchemaConfig.value }).schemaConfig
1638
1908
  );
1639
1909
  const hasSchemaConfigKey = (config, key) => Object.prototype.hasOwnProperty.call(config, key);
1640
- const replaceFormSchemaConfig = (nextSchemaConfig) => {
1641
- for (const key of defaultSchemxConfigKeys) {
1642
- if (!hasSchemaConfigKey(nextSchemaConfig, key)) {
1643
- delete formSchemaConfig[key];
1644
- }
1645
- }
1646
- Object.assign(formSchemaConfig, nextSchemaConfig);
1647
- };
1648
1910
  const resolvedColComponent = computed(
1649
- () => props.colComponent ?? (providerConfig == null ? void 0 : providerConfig.value.colComponent) ?? appConfig.colComponent ?? registeredColComponent.value
1911
+ () => props.colComponent ?? (providerConfig == null ? void 0 : providerConfig.value.colComponent) ?? coreConfig.colComponent
1650
1912
  );
1651
- createFormConfigContext({ schemaConfig: formSchemaConfig });
1913
+ const resolvedRowComponent = computed(
1914
+ () => props.rowComponent ?? (providerConfig == null ? void 0 : providerConfig.value.rowComponent) ?? coreConfig.rowComponent
1915
+ );
1916
+ const resolvedIconComponent = computed(
1917
+ () => props.iconComponent ?? (providerConfig == null ? void 0 : providerConfig.value.iconComponent) ?? coreConfig.iconComponent
1918
+ );
1919
+ const resolvedRowConfig = computed(() => {
1920
+ const schemaConfigRow = resolvedSchemaConfig.value.row;
1921
+ const inheritedRowConfig = (providerConfig == null ? void 0 : providerConfig.value.row) ?? coreConfig.row ?? schemaConfigRow;
1922
+ if (inheritedRowConfig === void 0 && props.row === void 0) {
1923
+ return void 0;
1924
+ }
1925
+ return {
1926
+ ...inheritedRowConfig,
1927
+ ...props.row
1928
+ };
1929
+ });
1652
1930
  const providedForm = props.form ? props.form : useForm({
1653
1931
  schemas: props.schemas,
1654
- schemaConfig: initialCoreSchemaConfig,
1932
+ schemaConfig: resolvedSchemaConfig.value,
1655
1933
  initialValues: Object.keys(props.modelValue).length > 0 ? props.modelValue : props.initialValues,
1656
1934
  rendererProps: props.rendererProps,
1657
1935
  rendererRegistry: props.rendererRegistry,
@@ -1673,11 +1951,11 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
1673
1951
  /**
1674
1952
  * 转发提交失败回调。
1675
1953
  *
1676
- * @param errors - 提交失败时的字段错误集合。
1954
+ * @param failure - 提交失败结果,包含本次表单值和校验错误。
1677
1955
  */
1678
- onFinishFailed: (errors) => {
1956
+ onFinishFailed: (failure) => {
1679
1957
  var _a;
1680
- return (_a = props.onFinishFailed) == null ? void 0 : _a.call(props, errors);
1958
+ return (_a = props.onFinishFailed) == null ? void 0 : _a.call(props, failure);
1681
1959
  },
1682
1960
  /**
1683
1961
  * 转发完整表单重置回调。
@@ -1718,7 +1996,21 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
1718
1996
  (_a = props.onFieldsChange) == null ? void 0 : _a.call(props, changedPaths, allPaths);
1719
1997
  }
1720
1998
  });
1721
- const formInstance = createFormContext(providedForm);
1999
+ const formInstance = provideFormContext({
2000
+ form: providedForm,
2001
+ get schemaConfig() {
2002
+ return contextSchemaConfig.value;
2003
+ },
2004
+ get iconComponent() {
2005
+ return resolvedIconComponent.value;
2006
+ },
2007
+ get colComponent() {
2008
+ return resolvedColComponent.value;
2009
+ },
2010
+ get rowComponent() {
2011
+ return resolvedRowComponent.value;
2012
+ }
2013
+ });
1722
2014
  const effectiveLoading = computed(() => props.loading ?? formInstance.isLoading());
1723
2015
  const formRootClass = computed(() => ["schemx", props.class]);
1724
2016
  const formRootStyle = computed(() => props.style);
@@ -1818,19 +2110,17 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
1818
2110
  };
1819
2111
  };
1820
2112
  const syncInternalSchemaConfig = (nextSchemaConfig) => {
1821
- replaceFormSchemaConfig(contextSchemaConfig.value);
1822
2113
  formInstance.updateSchemaConfig(nextSchemaConfig);
1823
2114
  };
1824
2115
  const syncExternalSchemaConfig = (nextSchemaConfig, previousSchemaConfig) => {
1825
2116
  const patch = { ...nextSchemaConfig };
1826
2117
  if (previousSchemaConfig !== void 0) {
1827
- for (const key of defaultSchemxConfigKeys) {
2118
+ for (const key of schemaConfigKeys) {
1828
2119
  if (hasSchemaConfigKey(previousSchemaConfig, key) && !hasSchemaConfigKey(nextSchemaConfig, key)) {
1829
2120
  patch[key] = void 0;
1830
2121
  }
1831
2122
  }
1832
2123
  }
1833
- replaceFormSchemaConfig(contextSchemaConfig.value);
1834
2124
  if (Object.keys(patch).length > 0) {
1835
2125
  formInstance.updateSchemaConfig(patch);
1836
2126
  }
@@ -1857,7 +2147,8 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
1857
2147
  createVNode(unref(SchemaList$1), {
1858
2148
  schemas: unref(viewSchemas),
1859
2149
  "view-schemas": unref(viewSchemas),
1860
- "col-component": resolvedColComponent.value,
2150
+ "row-component": resolvedRowComponent.value,
2151
+ "row-config": resolvedRowConfig.value,
1861
2152
  "field-class-resolver": getFieldClass
1862
2153
  }, createSlots({ _: 2 }, [
1863
2154
  renderList(fieldSlots.value, (_, slotName) => {
@@ -1868,7 +2159,7 @@ const _sfc_main$1 = /* @__PURE__ */ defineComponent({
1868
2159
  ])
1869
2160
  };
1870
2161
  })
1871
- ]), 1032, ["schemas", "view-schemas", "col-component"]),
2162
+ ]), 1032, ["schemas", "view-schemas", "row-component", "row-config"]),
1872
2163
  isActionsVisible.value ? (openBlock(), createElementBlock("div", _hoisted_1, [
1873
2164
  isResetterVisible.value && unref(slots).resetter ? renderSlot(_ctx.$slots, "resetter", {
1874
2165
  form: unref(formInstance),
@@ -1912,12 +2203,16 @@ function withInstall(comp, extra) {
1912
2203
  return Object.assign(comp, extra);
1913
2204
  }
1914
2205
  const SchemxFormExport = withInstall(_sfc_main$1, {
1915
- /** Vue 插件安装方法 */
2206
+ /**
2207
+ * Vue 插件安装方法
2208
+ */
1916
2209
  install(app, options = {}) {
1917
2210
  provideSchemxAppConfig(app, options);
1918
2211
  app.component("SchemxForm", _sfc_main$1);
1919
2212
  },
1920
- /** Field 子组件引用 */
2213
+ /**
2214
+ * Field 子组件引用
2215
+ */
1921
2216
  Field: Field$1
1922
2217
  });
1923
2218
  const SchemxFormExport$1 = SchemxFormExport;
@@ -2031,11 +2326,31 @@ const ConfigProvider = /* @__PURE__ */ defineComponent({
2031
2326
  colComponent: {
2032
2327
  type: [Object, Function],
2033
2328
  default: void 0
2329
+ },
2330
+ rowComponent: {
2331
+ type: [Object, Function],
2332
+ default: void 0
2333
+ },
2334
+ iconComponent: {
2335
+ type: [Object, Function],
2336
+ default: void 0
2337
+ },
2338
+ row: {
2339
+ type: Object,
2340
+ default: void 0
2034
2341
  }
2035
2342
  },
2036
- setup(props, {
2037
- slots
2038
- }) {
2343
+ /**
2344
+ * 合并 Props 与 fallthrough attrs,并向后代提供配置上下文。
2345
+ *
2346
+ * @param props - 当前 ConfigProvider 的 Schemx 配置。
2347
+ * @param setupContext - 父级传入的默认插槽与额外配置属性。
2348
+ */
2349
+ setup(props, setupContext) {
2350
+ const {
2351
+ slots,
2352
+ attrs
2353
+ } = setupContext;
2039
2354
  const config = computed(() => ({
2040
2355
  schemaConfig: props.schemaConfig,
2041
2356
  rendererProps: props.rendererProps,
@@ -2043,9 +2358,13 @@ const ConfigProvider = /* @__PURE__ */ defineComponent({
2043
2358
  defaultRendererType: props.defaultRendererType,
2044
2359
  rendererRegistry: props.rendererRegistry,
2045
2360
  presetRuleRegistry: props.presetRuleRegistry,
2046
- colComponent: props.colComponent
2361
+ colComponent: props.colComponent,
2362
+ rowComponent: props.rowComponent,
2363
+ iconComponent: props.iconComponent,
2364
+ row: props.row,
2365
+ ...attrs
2047
2366
  }));
2048
- provideSchemxConfigProvider(config);
2367
+ createConfigProviderContext(config);
2049
2368
  return () => {
2050
2369
  var _a;
2051
2370
  return (_a = slots.default) == null ? void 0 : _a.call(slots);
@@ -2058,22 +2377,30 @@ export {
2058
2377
  ConfigProvider$1 as ConfigProvider,
2059
2378
  Field$1 as Field,
2060
2379
  Group$1 as Group,
2380
+ Icon$1 as Icon,
2381
+ Row$1 as Row,
2061
2382
  WithRemoteOptions,
2062
2383
  _sfc_main as Wrapper,
2384
+ createConfigProviderContext,
2063
2385
  createFieldContext,
2064
2386
  createFormConfigContext,
2065
2387
  createFormContext,
2066
2388
  SchemxFormExport$1 as default,
2389
+ normalizeSchemxGutter,
2067
2390
  presetRuleRegistry,
2068
- registerCol,
2391
+ provideFormContext,
2069
2392
  rendererRegistry,
2070
2393
  SchemxFormExport$1 as schemxForm,
2394
+ useConfigProviderContext,
2395
+ useConfigProviderContextRef,
2071
2396
  useDictionary,
2072
2397
  useField,
2073
2398
  useFieldContext,
2074
2399
  useForm,
2075
2400
  useFormConfigContext,
2076
2401
  useFormContext,
2402
+ useFormContextValue,
2403
+ useFormRuntimeContext,
2077
2404
  useFormSelector,
2078
2405
  useStableRef,
2079
2406
  useViewSchemas,