@schemx/vue 1.0.0-next.0 → 1.0.0-next.2
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.
- package/README.md +172 -129
- package/dist/analyze.html +1 -1
- package/dist/components/Button/index.d.ts +3 -0
- package/dist/components/Button/index.d.ts.map +1 -0
- package/dist/components/Button/types.d.ts +21 -0
- package/dist/components/Button/types.d.ts.map +1 -0
- package/dist/components/FormItem/index.d.ts +5 -6
- package/dist/components/FormItem/index.d.ts.map +1 -1
- package/dist/components/FormItem/slot.d.ts +48 -0
- package/dist/components/FormItem/slot.d.ts.map +1 -0
- package/dist/config/appConfig.d.ts.map +1 -1
- package/dist/form.d.ts.map +1 -1
- package/dist/formBridge.d.ts +188 -0
- package/dist/formBridge.d.ts.map +1 -0
- package/dist/hocs/withRemoteOptions.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +4 -2
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/provideFormConfigContext.d.ts +3 -4
- package/dist/hooks/provideFormConfigContext.d.ts.map +1 -1
- package/dist/hooks/provideFormContext.d.ts +7 -4
- package/dist/hooks/provideFormContext.d.ts.map +1 -1
- package/dist/hooks/useField.d.ts +4 -30
- package/dist/hooks/useField.d.ts.map +1 -1
- package/dist/hooks/useForm.d.ts +3 -2
- package/dist/hooks/useForm.d.ts.map +1 -1
- package/dist/hooks/useFormSelector.d.ts +38 -0
- package/dist/hooks/useFormSelector.d.ts.map +1 -0
- package/dist/hooks/useViewSchemas.d.ts +23 -3
- package/dist/hooks/useViewSchemas.d.ts.map +1 -1
- package/dist/hooks/useWatch.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +807 -224
- package/dist/index.mjs.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/dictionary.d.ts +6 -3
- package/dist/types/dictionary.d.ts.map +1 -1
- package/dist/types/field.d.ts +1 -1
- package/dist/types/form.d.ts +34 -2
- package/dist/types/form.d.ts.map +1 -1
- package/dist/utils/helpers.d.ts.map +1 -1
- package/dist/utils/rendererProvider.d.ts +2 -1
- package/dist/utils/rendererProvider.d.ts.map +1 -1
- package/package.json +8 -6
- package/dist/hooks/useEffect.d.ts +0 -33
- package/dist/hooks/useEffect.d.ts.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import "./style.css";
|
|
2
|
-
import { getCurrentInstance, inject, onScopeDispose, provide,
|
|
3
|
-
import
|
|
4
|
-
import { createRendererRegistry, createValidationRuleRegistry, mergeSchemxConfig, createForm, createField, createWatch, createEffect, isSchemxSchemas, defaultSchemxConfigKeys } from "@schemx/core";
|
|
2
|
+
import { getCurrentInstance, inject, shallowRef, onScopeDispose, provide, computed, onUnmounted, ref, onMounted, watchEffect, watch, readonly, defineComponent, createVNode, h, createTextVNode, mergeProps, useAttrs, openBlock, createElementBlock, unref, renderSlot, createCommentVNode, createStaticVNode, Fragment, toDisplayString, useSlots, reactive, normalizeClass, normalizeStyle, renderList, createBlock, createSlots, withCtx } from "vue";
|
|
3
|
+
import { createValidationRuleRegistry, mergeSchemxConfig, createForm, createField, createWatch, isViewGroupSchema, isSchemxViewFieldSchema, isSchemxSchemas, defaultSchemxConfigKeys } from "@schemx/core";
|
|
5
4
|
export * from "@schemx/core";
|
|
5
|
+
import classnames from "classnames";
|
|
6
|
+
import { createFormExternalStore, createRendererRegistry } from "@schemx/core/adapter";
|
|
6
7
|
import { pick } from "es-toolkit";
|
|
7
8
|
const SCHEMX_APP_CONFIG_KEY = Symbol("schemx:app-config");
|
|
8
9
|
const EMPTY_SCHEMX_CONFIG = Object.freeze({
|
|
@@ -14,12 +15,22 @@ function normalizeSchemxAppConfig(config) {
|
|
|
14
15
|
const validatorAdapters = Object.freeze([...config.validatorAdapters ?? []]);
|
|
15
16
|
return Object.freeze({
|
|
16
17
|
schemaConfig,
|
|
18
|
+
rendererProps: normalizeRendererProps(config.rendererProps),
|
|
17
19
|
validatorAdapters,
|
|
18
20
|
defaultRendererType: config.defaultRendererType,
|
|
19
21
|
rendererRegistry: config.rendererRegistry,
|
|
20
22
|
validationRuleRegistry: config.validationRuleRegistry
|
|
21
23
|
});
|
|
22
24
|
}
|
|
25
|
+
function normalizeRendererProps(source) {
|
|
26
|
+
if (source === void 0) {
|
|
27
|
+
return void 0;
|
|
28
|
+
}
|
|
29
|
+
const entries = Object.entries(source).map(([type, props]) => {
|
|
30
|
+
return [type, props === void 0 ? void 0 : Object.freeze({ ...props })];
|
|
31
|
+
});
|
|
32
|
+
return Object.freeze(Object.fromEntries(entries));
|
|
33
|
+
}
|
|
23
34
|
function provideSchemxAppConfig(app, config = {}) {
|
|
24
35
|
const normalizedConfig = normalizeSchemxAppConfig(config);
|
|
25
36
|
app.provide(SCHEMX_APP_CONFIG_KEY, normalizedConfig);
|
|
@@ -30,11 +41,258 @@ function getSchemxAppConfig() {
|
|
|
30
41
|
}
|
|
31
42
|
return inject(SCHEMX_APP_CONFIG_KEY, EMPTY_SCHEMX_CONFIG);
|
|
32
43
|
}
|
|
44
|
+
const formBridgeCache = /* @__PURE__ */ new WeakMap();
|
|
45
|
+
const formFacadeCache = /* @__PURE__ */ new WeakMap();
|
|
46
|
+
const facadeCoreFormCache = /* @__PURE__ */ new WeakMap();
|
|
47
|
+
function createVueShallowRef(value) {
|
|
48
|
+
return shallowRef(value);
|
|
49
|
+
}
|
|
50
|
+
function getCoreForm(form) {
|
|
51
|
+
const coreForm = facadeCoreFormCache.get(form);
|
|
52
|
+
return coreForm ?? form;
|
|
53
|
+
}
|
|
54
|
+
function getVueFormBridge(form) {
|
|
55
|
+
const coreForm = getCoreForm(form);
|
|
56
|
+
const cachedBridge = formBridgeCache.get(coreForm);
|
|
57
|
+
if (cachedBridge) {
|
|
58
|
+
return cachedBridge;
|
|
59
|
+
}
|
|
60
|
+
const bridge = createVueFormBridge(coreForm);
|
|
61
|
+
formBridgeCache.set(coreForm, bridge);
|
|
62
|
+
return bridge;
|
|
63
|
+
}
|
|
64
|
+
function getVueFormFacade(form) {
|
|
65
|
+
const coreForm = getCoreForm(form);
|
|
66
|
+
const cachedFacade = formFacadeCache.get(coreForm);
|
|
67
|
+
if (cachedFacade) {
|
|
68
|
+
return cachedFacade;
|
|
69
|
+
}
|
|
70
|
+
const facade = createVueFormFacade(coreForm);
|
|
71
|
+
formFacadeCache.set(coreForm, facade);
|
|
72
|
+
facadeCoreFormCache.set(facade, coreForm);
|
|
73
|
+
return facade;
|
|
74
|
+
}
|
|
75
|
+
function retainVueFormBridge(bridge) {
|
|
76
|
+
if (bridge.destroyed) {
|
|
77
|
+
return () => {
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
bridge.refCount++;
|
|
81
|
+
let released = false;
|
|
82
|
+
return () => {
|
|
83
|
+
if (released || bridge.destroyed) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
released = true;
|
|
87
|
+
bridge.refCount--;
|
|
88
|
+
if (bridge.refCount === 0) {
|
|
89
|
+
disposeVueFormBridge(bridge);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function getVueFieldBridge(bridge, name) {
|
|
94
|
+
const store = bridge.externalStore.field(name);
|
|
95
|
+
const cachedBridge = bridge.fieldBridges.get(store);
|
|
96
|
+
if (cachedBridge) {
|
|
97
|
+
return cachedBridge;
|
|
98
|
+
}
|
|
99
|
+
const snapshot = store.getSnapshot();
|
|
100
|
+
const value = createVueShallowRef(
|
|
101
|
+
snapshot.value
|
|
102
|
+
);
|
|
103
|
+
const errors = createVueShallowRef(snapshot.errors);
|
|
104
|
+
const touched = createVueShallowRef(snapshot.touched);
|
|
105
|
+
const pending = createVueShallowRef(snapshot.pending);
|
|
106
|
+
const updateFieldRefs = () => {
|
|
107
|
+
const nextSnapshot = store.getSnapshot();
|
|
108
|
+
if (!Object.is(value.value, nextSnapshot.value)) {
|
|
109
|
+
value.value = nextSnapshot.value;
|
|
110
|
+
}
|
|
111
|
+
if (!areStringListsEqual(errors.value, nextSnapshot.errors)) {
|
|
112
|
+
errors.value = nextSnapshot.errors;
|
|
113
|
+
}
|
|
114
|
+
if (touched.value !== nextSnapshot.touched) {
|
|
115
|
+
touched.value = nextSnapshot.touched;
|
|
116
|
+
}
|
|
117
|
+
if (pending.value !== nextSnapshot.pending) {
|
|
118
|
+
pending.value = nextSnapshot.pending;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
const unsubscribe = store.subscribe(updateFieldRefs);
|
|
122
|
+
const dispose = () => {
|
|
123
|
+
unsubscribe();
|
|
124
|
+
};
|
|
125
|
+
const fieldBridge = {
|
|
126
|
+
store,
|
|
127
|
+
value,
|
|
128
|
+
errors,
|
|
129
|
+
touched,
|
|
130
|
+
pending,
|
|
131
|
+
dispose
|
|
132
|
+
};
|
|
133
|
+
bridge.fieldBridges.set(store, fieldBridge);
|
|
134
|
+
return fieldBridge;
|
|
135
|
+
}
|
|
136
|
+
function disposeVueFormBridge(bridge) {
|
|
137
|
+
if (bridge.destroyed) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
bridge.destroyed = true;
|
|
141
|
+
bridge.refCount = 0;
|
|
142
|
+
bridge.unsubscribe();
|
|
143
|
+
for (const fieldBridge of bridge.fieldBridges.values()) {
|
|
144
|
+
fieldBridge.dispose();
|
|
145
|
+
}
|
|
146
|
+
bridge.fieldBridges.clear();
|
|
147
|
+
bridge.externalStore.dispose();
|
|
148
|
+
formBridgeCache.delete(bridge.form);
|
|
149
|
+
}
|
|
150
|
+
function createVueFormBridge(form) {
|
|
151
|
+
const externalStore = createFormExternalStore(form);
|
|
152
|
+
const values = createVueShallowRef(externalStore.values.getSnapshot());
|
|
153
|
+
const touchedFields = createVueShallowRef(
|
|
154
|
+
externalStore.touchedFields.getSnapshot()
|
|
155
|
+
);
|
|
156
|
+
const pendingFields = createVueShallowRef(
|
|
157
|
+
externalStore.pendingFields.getSnapshot()
|
|
158
|
+
);
|
|
159
|
+
const loading = createVueShallowRef(externalStore.loading.getSnapshot());
|
|
160
|
+
const fieldBridges = /* @__PURE__ */ new Map();
|
|
161
|
+
const syncValues = () => {
|
|
162
|
+
values.value = externalStore.values.getSnapshot();
|
|
163
|
+
};
|
|
164
|
+
const syncTouchedFields = () => {
|
|
165
|
+
touchedFields.value = externalStore.touchedFields.getSnapshot();
|
|
166
|
+
};
|
|
167
|
+
const syncPendingFields = () => {
|
|
168
|
+
pendingFields.value = externalStore.pendingFields.getSnapshot();
|
|
169
|
+
};
|
|
170
|
+
const syncLoading = () => {
|
|
171
|
+
loading.value = externalStore.loading.getSnapshot();
|
|
172
|
+
};
|
|
173
|
+
const unsubscribeValues = externalStore.values.subscribe(syncValues);
|
|
174
|
+
const unsubscribeTouchedFields = externalStore.touchedFields.subscribe(syncTouchedFields);
|
|
175
|
+
const unsubscribePendingFields = externalStore.pendingFields.subscribe(syncPendingFields);
|
|
176
|
+
const unsubscribeLoading = externalStore.loading.subscribe(syncLoading);
|
|
177
|
+
const unsubscribe = () => {
|
|
178
|
+
unsubscribeValues();
|
|
179
|
+
unsubscribeTouchedFields();
|
|
180
|
+
unsubscribePendingFields();
|
|
181
|
+
unsubscribeLoading();
|
|
182
|
+
};
|
|
183
|
+
const facade = getVueFormFacade(form);
|
|
184
|
+
const bridge = {
|
|
185
|
+
form,
|
|
186
|
+
externalStore,
|
|
187
|
+
values,
|
|
188
|
+
touchedFields,
|
|
189
|
+
pendingFields,
|
|
190
|
+
loading,
|
|
191
|
+
fieldBridges,
|
|
192
|
+
refCount: 0,
|
|
193
|
+
destroyed: false,
|
|
194
|
+
unsubscribe,
|
|
195
|
+
facade
|
|
196
|
+
};
|
|
197
|
+
return bridge;
|
|
198
|
+
}
|
|
199
|
+
function createVueFormFacade(form) {
|
|
200
|
+
let destroyed = false;
|
|
201
|
+
const getFieldValue = (name) => {
|
|
202
|
+
if (!destroyed) {
|
|
203
|
+
const bridge = getVueFormBridge(form);
|
|
204
|
+
void getVueFieldBridge(bridge, name).value.value;
|
|
205
|
+
}
|
|
206
|
+
return form.getFieldValue(name);
|
|
207
|
+
};
|
|
208
|
+
const getFieldErrors = (name) => {
|
|
209
|
+
if (!destroyed) {
|
|
210
|
+
const bridge = getVueFormBridge(form);
|
|
211
|
+
void getVueFieldBridge(bridge, name).errors.value;
|
|
212
|
+
}
|
|
213
|
+
return form.getFieldErrors(name);
|
|
214
|
+
};
|
|
215
|
+
const isFieldTouched = (name) => {
|
|
216
|
+
if (!destroyed) {
|
|
217
|
+
const bridge = getVueFormBridge(form);
|
|
218
|
+
void getVueFieldBridge(bridge, name).touched.value;
|
|
219
|
+
}
|
|
220
|
+
return form.isFieldTouched(name);
|
|
221
|
+
};
|
|
222
|
+
const isFieldPending = (name) => {
|
|
223
|
+
if (!destroyed) {
|
|
224
|
+
const bridge = getVueFormBridge(form);
|
|
225
|
+
void getVueFieldBridge(bridge, name).pending.value;
|
|
226
|
+
}
|
|
227
|
+
return form.isFieldPending(name);
|
|
228
|
+
};
|
|
229
|
+
const getFieldsValue = (names) => {
|
|
230
|
+
if (!destroyed) {
|
|
231
|
+
const bridge = getVueFormBridge(form);
|
|
232
|
+
if (names === void 0) {
|
|
233
|
+
void bridge.values.value;
|
|
234
|
+
} else {
|
|
235
|
+
for (const name of names) {
|
|
236
|
+
void getVueFieldBridge(bridge, name).value.value;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return form.getFieldsValue(names);
|
|
241
|
+
};
|
|
242
|
+
const getTouchedFields = () => {
|
|
243
|
+
if (!destroyed) {
|
|
244
|
+
const bridge = getVueFormBridge(form);
|
|
245
|
+
void bridge.touchedFields.value;
|
|
246
|
+
}
|
|
247
|
+
return form.getTouchedFields();
|
|
248
|
+
};
|
|
249
|
+
const getPendingFields = () => {
|
|
250
|
+
if (!destroyed) {
|
|
251
|
+
const bridge = getVueFormBridge(form);
|
|
252
|
+
void bridge.pendingFields.value;
|
|
253
|
+
}
|
|
254
|
+
return form.getPendingFields();
|
|
255
|
+
};
|
|
256
|
+
const isLoading = () => {
|
|
257
|
+
if (!destroyed) {
|
|
258
|
+
const bridge = getVueFormBridge(form);
|
|
259
|
+
void bridge.loading.value;
|
|
260
|
+
}
|
|
261
|
+
return form.isLoading();
|
|
262
|
+
};
|
|
263
|
+
const destroy = () => {
|
|
264
|
+
if (destroyed) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
destroyed = true;
|
|
268
|
+
const bridge = formBridgeCache.get(form);
|
|
269
|
+
if (bridge) {
|
|
270
|
+
disposeVueFormBridge(bridge);
|
|
271
|
+
}
|
|
272
|
+
form.destroy();
|
|
273
|
+
};
|
|
274
|
+
return {
|
|
275
|
+
...form,
|
|
276
|
+
getFieldValue,
|
|
277
|
+
getFieldErrors,
|
|
278
|
+
isFieldTouched,
|
|
279
|
+
isFieldPending,
|
|
280
|
+
getFieldsValue,
|
|
281
|
+
getTouchedFields,
|
|
282
|
+
getPendingFields,
|
|
283
|
+
isLoading,
|
|
284
|
+
destroy
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
function areStringListsEqual(previous, next) {
|
|
288
|
+
return previous.length === next.length && previous.every((value, index) => value === next[index]);
|
|
289
|
+
}
|
|
33
290
|
const rendererRegistry = createRendererRegistry("input");
|
|
34
291
|
const validationRuleRegistry = createValidationRuleRegistry();
|
|
35
292
|
function useForm(options = {}) {
|
|
36
293
|
const configuredOptions = mergeSchemxConfig(
|
|
37
294
|
getUseFormSchemxConfig(options),
|
|
295
|
+
// App 安装配置以 Values 存储;在 useForm 边界关联到当前 TValues。
|
|
38
296
|
getSchemxAppConfig(),
|
|
39
297
|
{
|
|
40
298
|
rendererRegistry,
|
|
@@ -46,22 +304,26 @@ function useForm(options = {}) {
|
|
|
46
304
|
...configuredOptions
|
|
47
305
|
};
|
|
48
306
|
const instance = createForm(mergedOptions);
|
|
307
|
+
const form = getVueFormFacade(instance);
|
|
308
|
+
const releaseBridge = retainVueFormBridge(getVueFormBridge(instance));
|
|
49
309
|
onScopeDispose(() => {
|
|
50
|
-
|
|
310
|
+
releaseBridge();
|
|
311
|
+
form.destroy();
|
|
51
312
|
});
|
|
52
|
-
return
|
|
313
|
+
return form;
|
|
53
314
|
}
|
|
54
315
|
function getUseFormSchemxConfig(options) {
|
|
55
316
|
const {
|
|
56
317
|
schemaConfig = {},
|
|
318
|
+
rendererProps = void 0,
|
|
57
319
|
validatorAdapters = [],
|
|
58
320
|
defaultRendererType = void 0,
|
|
59
321
|
rendererRegistry: rendererRegistry2 = void 0,
|
|
60
|
-
validationRuleRegistry: validationRuleRegistry2 = void 0
|
|
61
|
-
...rest
|
|
322
|
+
validationRuleRegistry: validationRuleRegistry2 = void 0
|
|
62
323
|
} = options;
|
|
63
324
|
return {
|
|
64
325
|
schemaConfig,
|
|
326
|
+
rendererProps,
|
|
65
327
|
defaultRendererType,
|
|
66
328
|
rendererRegistry: rendererRegistry2,
|
|
67
329
|
validationRuleRegistry: validationRuleRegistry2,
|
|
@@ -70,7 +332,11 @@ function getUseFormSchemxConfig(options) {
|
|
|
70
332
|
}
|
|
71
333
|
const SCHEMX_FORM_INSTANCE_KEY = Symbol("schemx:instance");
|
|
72
334
|
function createFormContext(instance) {
|
|
73
|
-
|
|
335
|
+
const form = getVueFormFacade(instance);
|
|
336
|
+
const releaseBridge = retainVueFormBridge(getVueFormBridge(form));
|
|
337
|
+
provide(SCHEMX_FORM_INSTANCE_KEY, form);
|
|
338
|
+
onScopeDispose(releaseBridge);
|
|
339
|
+
return form;
|
|
74
340
|
}
|
|
75
341
|
function useFormContext() {
|
|
76
342
|
const instance = inject(SCHEMX_FORM_INSTANCE_KEY, null);
|
|
@@ -81,63 +347,37 @@ function useFormContext() {
|
|
|
81
347
|
}
|
|
82
348
|
return instance;
|
|
83
349
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const
|
|
87
|
-
const
|
|
88
|
-
const
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
void fieldValue.value;
|
|
98
|
-
return field.isTouched();
|
|
99
|
-
});
|
|
100
|
-
const pending = computed(() => fieldPending.value);
|
|
101
|
-
const result = {
|
|
350
|
+
function createFieldHook(form, name, fieldBridge) {
|
|
351
|
+
const coreForm = getCoreForm(form);
|
|
352
|
+
const coreField = createField(coreForm, name);
|
|
353
|
+
const errors = computed(() => fieldBridge.errors.value);
|
|
354
|
+
const dirty = computed(() => fieldBridge.touched.value);
|
|
355
|
+
const pending = computed(() => fieldBridge.pending.value);
|
|
356
|
+
const getValue = () => fieldBridge.value.value;
|
|
357
|
+
const getErrors = () => fieldBridge.errors.value;
|
|
358
|
+
const isTouched = () => fieldBridge.touched.value;
|
|
359
|
+
const isPending = () => fieldBridge.pending.value;
|
|
360
|
+
const getValues = () => form.getFieldsValue();
|
|
361
|
+
return {
|
|
362
|
+
...coreField,
|
|
102
363
|
name,
|
|
103
|
-
value:
|
|
364
|
+
value: fieldBridge.value,
|
|
104
365
|
errors,
|
|
105
366
|
dirty,
|
|
106
367
|
pending,
|
|
107
|
-
|
|
108
|
-
|
|
368
|
+
getValue,
|
|
369
|
+
getErrors,
|
|
370
|
+
isTouched,
|
|
371
|
+
isPending,
|
|
372
|
+
getValues
|
|
109
373
|
};
|
|
110
|
-
return { result, dispose };
|
|
111
374
|
}
|
|
112
375
|
const useField = (name) => {
|
|
113
376
|
const form = useFormContext();
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
fieldHookCache.set(form, formCache);
|
|
119
|
-
}
|
|
120
|
-
const cachedEntry = formCache.get(key);
|
|
121
|
-
let activeEntry;
|
|
122
|
-
if (cachedEntry) {
|
|
123
|
-
cachedEntry.refCount++;
|
|
124
|
-
activeEntry = cachedEntry;
|
|
125
|
-
} else {
|
|
126
|
-
const { result, dispose } = createFieldHook(form, name);
|
|
127
|
-
activeEntry = {
|
|
128
|
-
refCount: 1,
|
|
129
|
-
result,
|
|
130
|
-
dispose
|
|
131
|
-
};
|
|
132
|
-
formCache.set(key, activeEntry);
|
|
133
|
-
}
|
|
134
|
-
onUnmounted(() => {
|
|
135
|
-
if (--activeEntry.refCount <= 0) {
|
|
136
|
-
activeEntry.dispose();
|
|
137
|
-
formCache.delete(key);
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
return activeEntry.result;
|
|
377
|
+
const coreForm = getCoreForm(form);
|
|
378
|
+
const formBridge = getVueFormBridge(coreForm);
|
|
379
|
+
const fieldBridge = getVueFieldBridge(formBridge, name);
|
|
380
|
+
return createFieldHook(form, name, fieldBridge);
|
|
141
381
|
};
|
|
142
382
|
const SCHEMX_FORM_FIELD_KEY = Symbol(
|
|
143
383
|
"schemx:field"
|
|
@@ -157,7 +397,7 @@ function useFieldContext() {
|
|
|
157
397
|
function useWatch(nameOrNamesOrCallback, callbackOrOptions, maybeOptions) {
|
|
158
398
|
const form = useFormContext();
|
|
159
399
|
const dispose = createWatch(
|
|
160
|
-
form,
|
|
400
|
+
getCoreForm(form),
|
|
161
401
|
nameOrNamesOrCallback,
|
|
162
402
|
callbackOrOptions,
|
|
163
403
|
maybeOptions
|
|
@@ -174,13 +414,9 @@ function useWatchFields(names, callback, options) {
|
|
|
174
414
|
function useWatchAll(callback, options) {
|
|
175
415
|
return useWatch(callback, options);
|
|
176
416
|
}
|
|
177
|
-
function useEffect(callback) {
|
|
178
|
-
const dispose = createEffect(callback);
|
|
179
|
-
onUnmounted(dispose);
|
|
180
|
-
return dispose;
|
|
181
|
-
}
|
|
182
417
|
function normalizeError(err) {
|
|
183
|
-
if (err instanceof Error)
|
|
418
|
+
if (err instanceof Error)
|
|
419
|
+
return err;
|
|
184
420
|
return new Error(String(err));
|
|
185
421
|
}
|
|
186
422
|
const useDictionary = (options, fieldName) => {
|
|
@@ -229,9 +465,11 @@ const useDictionary = (options, fieldName) => {
|
|
|
229
465
|
error.value = void 0;
|
|
230
466
|
const currentCount = ++requestCount;
|
|
231
467
|
const res = await executeWithRetry(formValues);
|
|
232
|
-
if (currentCount !== requestCount)
|
|
468
|
+
if (currentCount !== requestCount)
|
|
469
|
+
return;
|
|
233
470
|
const formatted = await format(res);
|
|
234
|
-
if (currentCount !== requestCount)
|
|
471
|
+
if (currentCount !== requestCount)
|
|
472
|
+
return;
|
|
235
473
|
list.value = formatted;
|
|
236
474
|
error.value = void 0;
|
|
237
475
|
if (typeof options.onSuccess === "function") {
|
|
@@ -289,7 +527,8 @@ function useFormConfigContext() {
|
|
|
289
527
|
const isShallowEqual = (a, b) => {
|
|
290
528
|
const keysA = Object.keys(a);
|
|
291
529
|
const keysB = Object.keys(b);
|
|
292
|
-
if (keysA.length !== keysB.length)
|
|
530
|
+
if (keysA.length !== keysB.length)
|
|
531
|
+
return false;
|
|
293
532
|
return keysA.every((key) => a[key] === b[key]);
|
|
294
533
|
};
|
|
295
534
|
function useStableRef(factory) {
|
|
@@ -302,24 +541,102 @@ function useStableRef(factory) {
|
|
|
302
541
|
});
|
|
303
542
|
return stableRef;
|
|
304
543
|
}
|
|
544
|
+
const viewSchemaBridgeCache = /* @__PURE__ */ new WeakMap();
|
|
305
545
|
function useViewSchemas(form) {
|
|
546
|
+
const bridge = acquireViewSchemaBridge(getCoreForm(form));
|
|
547
|
+
return bridge.viewSchemas;
|
|
548
|
+
}
|
|
549
|
+
function useViewSchema(form, getKey) {
|
|
550
|
+
const bridge = acquireViewSchemaBridge(getCoreForm(form));
|
|
551
|
+
return computed(() => bridge.schemasByKey.value.get(getKey()));
|
|
552
|
+
}
|
|
553
|
+
function createViewSchemaBridge(form) {
|
|
306
554
|
const viewSchemas = shallowRef(
|
|
307
555
|
form.getViewSchemas()
|
|
308
556
|
);
|
|
309
|
-
const
|
|
310
|
-
viewSchemas.value
|
|
557
|
+
const schemasByKey = computed(() => {
|
|
558
|
+
return createViewSchemaIndex(viewSchemas.value);
|
|
559
|
+
});
|
|
560
|
+
const unsubscribe = form.subscribeViewSchemas(
|
|
561
|
+
/**
|
|
562
|
+
* 接收 Core 发布的完整列表并替换共享引用,以保留更新边界。
|
|
563
|
+
*
|
|
564
|
+
* @param nextSchemas - Core 计算出的最新 ViewSchema 列表。
|
|
565
|
+
*/
|
|
566
|
+
(nextSchemas) => {
|
|
567
|
+
viewSchemas.value = nextSchemas;
|
|
568
|
+
}
|
|
569
|
+
);
|
|
570
|
+
return {
|
|
571
|
+
refCount: 0,
|
|
572
|
+
schemasByKey,
|
|
573
|
+
unsubscribe,
|
|
574
|
+
viewSchemas
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
function acquireViewSchemaBridge(form) {
|
|
578
|
+
const cachedBridge = viewSchemaBridgeCache.get(form);
|
|
579
|
+
const bridge = cachedBridge ?? createViewSchemaBridge(form);
|
|
580
|
+
if (!cachedBridge) {
|
|
581
|
+
viewSchemaBridgeCache.set(form, bridge);
|
|
582
|
+
}
|
|
583
|
+
bridge.refCount++;
|
|
584
|
+
onScopeDispose(() => {
|
|
585
|
+
bridge.refCount--;
|
|
586
|
+
if (bridge.refCount > 0) {
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
bridge.unsubscribe();
|
|
590
|
+
viewSchemaBridgeCache.delete(form);
|
|
591
|
+
});
|
|
592
|
+
return bridge;
|
|
593
|
+
}
|
|
594
|
+
function createViewSchemaIndex(viewSchemas) {
|
|
595
|
+
const schemasByKey = /* @__PURE__ */ new Map();
|
|
596
|
+
const appendSchemas = (schemas) => {
|
|
597
|
+
for (const schema of schemas) {
|
|
598
|
+
schemasByKey.set(schema.key, schema);
|
|
599
|
+
if (isViewGroupSchema(schema)) {
|
|
600
|
+
appendSchemas(schema.children);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
appendSchemas(viewSchemas);
|
|
605
|
+
return schemasByKey;
|
|
606
|
+
}
|
|
607
|
+
function useFormSelector(form, selector, options = {}) {
|
|
608
|
+
const bridge = getVueFormBridge(getCoreForm(form));
|
|
609
|
+
const releaseBridge = retainVueFormBridge(bridge);
|
|
610
|
+
const selected = shallowRef(selector(bridge.values.value));
|
|
611
|
+
const equals = options.equals ?? Object.is;
|
|
612
|
+
const stop = watch(
|
|
613
|
+
bridge.values,
|
|
614
|
+
(values) => {
|
|
615
|
+
const next = selector(values);
|
|
616
|
+
if (!equals(selected.value, next)) {
|
|
617
|
+
selected.value = next;
|
|
618
|
+
}
|
|
619
|
+
},
|
|
620
|
+
{ flush: "sync" }
|
|
621
|
+
);
|
|
622
|
+
onScopeDispose(() => {
|
|
623
|
+
stop();
|
|
624
|
+
releaseBridge();
|
|
311
625
|
});
|
|
312
|
-
|
|
313
|
-
return viewSchemas;
|
|
626
|
+
return readonly(selected);
|
|
314
627
|
}
|
|
315
628
|
function isValidTrigger(v) {
|
|
316
|
-
if (v === void 0)
|
|
317
|
-
|
|
629
|
+
if (v === void 0)
|
|
630
|
+
return false;
|
|
631
|
+
if (Array.isArray(v) && v.length === 0)
|
|
632
|
+
return false;
|
|
318
633
|
return true;
|
|
319
634
|
}
|
|
320
635
|
function mergeTrigger(columnTrigger, contextTrigger, defaultTrigger) {
|
|
321
|
-
if (isValidTrigger(columnTrigger))
|
|
322
|
-
|
|
636
|
+
if (isValidTrigger(columnTrigger))
|
|
637
|
+
return columnTrigger;
|
|
638
|
+
if (isValidTrigger(contextTrigger))
|
|
639
|
+
return contextTrigger;
|
|
323
640
|
return defaultTrigger;
|
|
324
641
|
}
|
|
325
642
|
function normalizeTrigger(t) {
|
|
@@ -334,7 +651,8 @@ function normalizeTrigger(t) {
|
|
|
334
651
|
return map[t] ?? "submit";
|
|
335
652
|
}
|
|
336
653
|
function shouldValidateOn(event, trigger) {
|
|
337
|
-
if (!trigger)
|
|
654
|
+
if (!trigger)
|
|
655
|
+
return false;
|
|
338
656
|
const triggers = Array.isArray(trigger) ? trigger : [trigger];
|
|
339
657
|
return triggers.some((t) => normalizeTrigger(t) === event);
|
|
340
658
|
}
|
|
@@ -347,17 +665,21 @@ const kebabToCamel = (str) => {
|
|
|
347
665
|
return str.replace(/-([a-z])/g, (_match, letter) => letter.toUpperCase());
|
|
348
666
|
};
|
|
349
667
|
const normalizeToKebab = (str) => {
|
|
350
|
-
if (isCamelCase(str))
|
|
668
|
+
if (isCamelCase(str))
|
|
669
|
+
return camelToKebab(str);
|
|
351
670
|
return str;
|
|
352
671
|
};
|
|
353
672
|
const normalizeToCamel = (str) => {
|
|
354
|
-
if (isKebabCase(str))
|
|
673
|
+
if (isKebabCase(str))
|
|
674
|
+
return kebabToCamel(str);
|
|
355
675
|
return str;
|
|
356
676
|
};
|
|
357
677
|
const resolveSlot = (slots, name) => {
|
|
358
|
-
if (slots[name])
|
|
678
|
+
if (slots[name])
|
|
679
|
+
return slots[name];
|
|
359
680
|
const alt = isCamelCase(name) ? camelToKebab(name) : isKebabCase(name) ? kebabToCamel(name) : void 0;
|
|
360
|
-
if (alt && slots[alt])
|
|
681
|
+
if (alt && slots[alt])
|
|
682
|
+
return slots[alt];
|
|
361
683
|
return void 0;
|
|
362
684
|
};
|
|
363
685
|
const extractChildSlots = (fieldName, allSlots) => {
|
|
@@ -420,7 +742,7 @@ const FormGroup = /* @__PURE__ */ defineComponent((props, {
|
|
|
420
742
|
"style": !destroyOnCollapse && isCollapsed ? {
|
|
421
743
|
display: "none"
|
|
422
744
|
} : void 0
|
|
423
|
-
}, [schema.children.map((child) => createVNode(FormItem, {
|
|
745
|
+
}, [schema.children.map((child) => createVNode(FormItem$1, {
|
|
424
746
|
"key": child.key,
|
|
425
747
|
"schema": child
|
|
426
748
|
}, slots))]);
|
|
@@ -467,9 +789,105 @@ const FormGroup = /* @__PURE__ */ defineComponent((props, {
|
|
|
467
789
|
}
|
|
468
790
|
}
|
|
469
791
|
});
|
|
792
|
+
const FormGroup$1 = FormGroup;
|
|
470
793
|
const normalizeId = (key) => {
|
|
471
794
|
return String(key).replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
472
795
|
};
|
|
796
|
+
function createFormItemSlotRenderers(options) {
|
|
797
|
+
const {
|
|
798
|
+
schemaRef,
|
|
799
|
+
field,
|
|
800
|
+
form,
|
|
801
|
+
formContext,
|
|
802
|
+
componentProps,
|
|
803
|
+
slots
|
|
804
|
+
} = options;
|
|
805
|
+
const renderRequired = () => {
|
|
806
|
+
const showRequiredMark = schemaRef.value.showRequiredMark ?? Boolean(schemaRef.value.required);
|
|
807
|
+
if (!showRequiredMark || schemaRef.value.disabled || schemaRef.value.readonly) {
|
|
808
|
+
return null;
|
|
809
|
+
}
|
|
810
|
+
return createVNode("span", {
|
|
811
|
+
"class": "schemx-item__required"
|
|
812
|
+
}, [createTextVNode("*")]);
|
|
813
|
+
};
|
|
814
|
+
const createSlotProps = (additionalProps = {}) => {
|
|
815
|
+
return {
|
|
816
|
+
...componentProps.value,
|
|
817
|
+
value: field.value.value,
|
|
818
|
+
...additionalProps
|
|
819
|
+
};
|
|
820
|
+
};
|
|
821
|
+
const renderFieldSlot = (suffix) => {
|
|
822
|
+
const slot = resolveSlot(slots, `${schemaRef.value.name}${suffix}`);
|
|
823
|
+
return (slot == null ? void 0 : slot(createSlotProps())) ?? null;
|
|
824
|
+
};
|
|
825
|
+
const renderLabel = () => {
|
|
826
|
+
const labelSlot = resolveSlot(slots, `${schemaRef.value.name}Label`);
|
|
827
|
+
if (labelSlot) {
|
|
828
|
+
return labelSlot(schemaRef.value);
|
|
829
|
+
}
|
|
830
|
+
const labelAlign = schemaRef.value.labelAlign || formContext.schemaConfig.labelAlign;
|
|
831
|
+
const labelWidth = schemaRef.value.labelWidth || formContext.schemaConfig.labelWidth;
|
|
832
|
+
const colon = schemaRef.value.colon ?? formContext.schemaConfig.colon;
|
|
833
|
+
return createVNode("label", {
|
|
834
|
+
"class": "schemx-item__label",
|
|
835
|
+
"style": {
|
|
836
|
+
width: labelWidth,
|
|
837
|
+
textAlign: labelAlign
|
|
838
|
+
}
|
|
839
|
+
}, [renderRequired(), createVNode("span", {
|
|
840
|
+
"class": "schemx-item__label-text"
|
|
841
|
+
}, [schemaRef.value.label, colon ? ":" : ""])]);
|
|
842
|
+
};
|
|
843
|
+
const renderBefore = () => renderFieldSlot("Before");
|
|
844
|
+
const renderContent = () => {
|
|
845
|
+
const component = form.getRenderer(schemaRef.value.componentType);
|
|
846
|
+
if (!component) {
|
|
847
|
+
throw new Error(`[schemx] Can not find component renderer of "${schemaRef.value.componentType}".`);
|
|
848
|
+
}
|
|
849
|
+
const childSlots = extractChildSlots(normalizeNameKey(schemaRef.value.name), slots);
|
|
850
|
+
const columnElement = h(component, componentProps.value, childSlots);
|
|
851
|
+
const contentSlot = resolveSlot(slots, `${schemaRef.value.name}Content`);
|
|
852
|
+
if (contentSlot) {
|
|
853
|
+
return contentSlot(createSlotProps({
|
|
854
|
+
columnElement
|
|
855
|
+
}));
|
|
856
|
+
}
|
|
857
|
+
return createVNode("div", {
|
|
858
|
+
"class": "schemx-item__control"
|
|
859
|
+
}, [columnElement]);
|
|
860
|
+
};
|
|
861
|
+
const renderAfter = () => renderFieldSlot("After");
|
|
862
|
+
const renderError = () => {
|
|
863
|
+
const errorSlot = resolveSlot(slots, `${schemaRef.value.name}Error`);
|
|
864
|
+
if (errorSlot) {
|
|
865
|
+
return errorSlot(createSlotProps({
|
|
866
|
+
errors: field.errors.value
|
|
867
|
+
}));
|
|
868
|
+
}
|
|
869
|
+
if (field.errors.value.length === 0) {
|
|
870
|
+
return null;
|
|
871
|
+
}
|
|
872
|
+
return createVNode("div", {
|
|
873
|
+
"class": "schemx-item__error"
|
|
874
|
+
}, [field.errors.value[0]]);
|
|
875
|
+
};
|
|
876
|
+
return {
|
|
877
|
+
createSlotProps,
|
|
878
|
+
renderAfter,
|
|
879
|
+
renderBefore,
|
|
880
|
+
renderContent,
|
|
881
|
+
renderError,
|
|
882
|
+
renderLabel
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
function normalizeNameKey(name) {
|
|
886
|
+
if (Array.isArray(name)) {
|
|
887
|
+
return name.map((part) => String(part)).join(".");
|
|
888
|
+
}
|
|
889
|
+
return String(name);
|
|
890
|
+
}
|
|
473
891
|
const FormItem = /* @__PURE__ */ defineComponent({
|
|
474
892
|
name: "SchemxItem",
|
|
475
893
|
props: {
|
|
@@ -478,13 +896,19 @@ const FormItem = /* @__PURE__ */ defineComponent({
|
|
|
478
896
|
required: true
|
|
479
897
|
}
|
|
480
898
|
},
|
|
899
|
+
/**
|
|
900
|
+
* 根据 schema 类型分发字段组或字段项渲染。
|
|
901
|
+
*
|
|
902
|
+
* @param props - 当前组件的 schema 属性。
|
|
903
|
+
* @param slots - Vue setup 上下文提供的插槽集合。
|
|
904
|
+
*/
|
|
481
905
|
setup(props, {
|
|
482
906
|
slots
|
|
483
907
|
}) {
|
|
484
908
|
return () => {
|
|
485
909
|
const schema = props.schema;
|
|
486
|
-
if (isViewGroupSchema
|
|
487
|
-
return h(FormGroup, {
|
|
910
|
+
if (isViewGroupSchema(schema)) {
|
|
911
|
+
return h(FormGroup$1, {
|
|
488
912
|
schema
|
|
489
913
|
}, slots);
|
|
490
914
|
}
|
|
@@ -496,152 +920,169 @@ const FormItem = /* @__PURE__ */ defineComponent({
|
|
|
496
920
|
});
|
|
497
921
|
const FieldFormItem = /* @__PURE__ */ defineComponent({
|
|
498
922
|
name: "SchemxFieldItem",
|
|
923
|
+
inheritAttrs: false,
|
|
499
924
|
props: {
|
|
500
925
|
schema: {
|
|
501
926
|
type: Object,
|
|
502
927
|
required: true
|
|
503
928
|
}
|
|
504
929
|
},
|
|
930
|
+
/**
|
|
931
|
+
* 初始化字段上下文,并组合响应式 schema、校验处理器与插槽渲染器。
|
|
932
|
+
*
|
|
933
|
+
* @param props - 当前字段项的 schema 属性。
|
|
934
|
+
* @param attrs - Vue setup 上下文提供的透传属性。
|
|
935
|
+
* @param slots - Vue setup 上下文提供的插槽集合。
|
|
936
|
+
*/
|
|
505
937
|
setup(props, {
|
|
938
|
+
attrs,
|
|
506
939
|
slots
|
|
507
940
|
}) {
|
|
508
|
-
const schemaRef = toRef(props, "schema");
|
|
509
941
|
const form = useFormContext();
|
|
942
|
+
const inputSchema = computed(() => props.schema);
|
|
943
|
+
const latestSchema = useViewSchema(form, () => inputSchema.value.key);
|
|
944
|
+
const schemaRef = computed(() => {
|
|
945
|
+
return latestSchema.value && isSchemxViewFieldSchema(latestSchema.value) ? latestSchema.value : inputSchema.value;
|
|
946
|
+
});
|
|
510
947
|
const formContext = useFormConfigContext();
|
|
511
|
-
const
|
|
512
|
-
const field = useField(schema().name);
|
|
948
|
+
const field = useField(schemaRef.value.name);
|
|
513
949
|
createFieldContext(field);
|
|
514
|
-
const trigger = computed(() => mergeTrigger(
|
|
950
|
+
const trigger = computed(() => mergeTrigger(schemaRef.value.validationTrigger, formContext.schemaConfig.validationTrigger, "onChange"));
|
|
515
951
|
const canVerified = computed(() => {
|
|
516
|
-
const isOperate =
|
|
517
|
-
const rules =
|
|
518
|
-
const hasRules = Array.isArray(rules) ? (rules == null ? void 0 : rules.length) > 0 : !!
|
|
519
|
-
return isOperate && (Boolean(
|
|
952
|
+
const isOperate = schemaRef.value.visible && !schemaRef.value.readonly && !schemaRef.value.disabled;
|
|
953
|
+
const rules = schemaRef.value.rules;
|
|
954
|
+
const hasRules = Array.isArray(rules) ? (rules == null ? void 0 : rules.length) > 0 : !!schemaRef.value.rules;
|
|
955
|
+
return isOperate && (Boolean(schemaRef.value.required) || hasRules);
|
|
520
956
|
});
|
|
521
957
|
const handleChange = (v) => {
|
|
522
958
|
var _a, _b;
|
|
523
959
|
field.setValue(v);
|
|
524
|
-
(_b = (_a =
|
|
960
|
+
(_b = (_a = schemaRef.value.componentProps) == null ? void 0 : _a.onChange) == null ? void 0 : _b.call(_a, v);
|
|
525
961
|
if (canVerified.value && shouldValidateOn("change", trigger.value)) {
|
|
526
962
|
field.validate();
|
|
527
963
|
}
|
|
528
964
|
};
|
|
529
965
|
const handleBlur = (v) => {
|
|
530
966
|
var _a, _b;
|
|
531
|
-
(_b = (_a =
|
|
967
|
+
(_b = (_a = schemaRef.value.componentProps) == null ? void 0 : _a.onBlur) == null ? void 0 : _b.call(_a, v);
|
|
532
968
|
if (canVerified.value && shouldValidateOn("blur", trigger.value)) {
|
|
533
969
|
field.validate();
|
|
534
970
|
}
|
|
535
971
|
};
|
|
972
|
+
const handleValueUpdate = (v) => {
|
|
973
|
+
field.setValue(v);
|
|
974
|
+
};
|
|
536
975
|
const componentProps = useStableRef(() => {
|
|
537
|
-
const
|
|
976
|
+
const currentComponentProps = schemaRef.value.componentProps ?? {};
|
|
538
977
|
return {
|
|
539
|
-
...
|
|
540
|
-
|
|
541
|
-
disabled: currentSchema.disabled,
|
|
542
|
-
placeholder: currentSchema.placeholder,
|
|
543
|
-
formItemProps: currentSchema,
|
|
544
|
-
value: field.getValue(),
|
|
978
|
+
...currentComponentProps,
|
|
979
|
+
value: field.value.value,
|
|
545
980
|
onChange: handleChange,
|
|
546
981
|
onBlur: handleBlur,
|
|
547
|
-
"onUpdate:value":
|
|
982
|
+
"onUpdate:value": handleValueUpdate
|
|
548
983
|
};
|
|
549
984
|
});
|
|
550
|
-
const
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
const labelWidth = schema().labelWidth || formContext.schemaConfig.labelWidth;
|
|
566
|
-
const colon = schema().colon ?? formContext.schemaConfig.colon;
|
|
567
|
-
return createVNode("label", {
|
|
568
|
-
"class": "schemx-item__label",
|
|
569
|
-
"style": {
|
|
570
|
-
width: labelWidth,
|
|
571
|
-
textAlign: labelAlign
|
|
572
|
-
}
|
|
573
|
-
}, [renderRequired(), createVNode("span", {
|
|
574
|
-
"class": "schemx-item__label-text"
|
|
575
|
-
}, [schema().label, colon ? ":" : ""])]);
|
|
576
|
-
};
|
|
577
|
-
const renderContent = () => {
|
|
578
|
-
const component = form.getRenderer(schema().componentType);
|
|
579
|
-
if (!component) {
|
|
580
|
-
throw new Error(`[schemx] Can not find component renderer of "${schema().componentType}".`);
|
|
581
|
-
}
|
|
582
|
-
const childSlots = extractChildSlots(normalizeNameKey(schema().name), slots);
|
|
583
|
-
const columnElement = h(component, componentProps.value, childSlots);
|
|
584
|
-
const contentSlot = resolveSlot(slots, `${schema().name}Content`);
|
|
585
|
-
if (contentSlot) {
|
|
586
|
-
return contentSlot({
|
|
587
|
-
...schema(),
|
|
588
|
-
columnElement
|
|
589
|
-
});
|
|
590
|
-
}
|
|
591
|
-
return createVNode("div", {
|
|
592
|
-
"class": "schemx-item__control"
|
|
593
|
-
}, [columnElement]);
|
|
594
|
-
};
|
|
595
|
-
const renderError = () => {
|
|
596
|
-
const errorSlot = resolveSlot(slots, `${schema().name}Error`);
|
|
597
|
-
if (errorSlot) {
|
|
598
|
-
return errorSlot({
|
|
599
|
-
...schema(),
|
|
600
|
-
errors: field.errors.value
|
|
601
|
-
});
|
|
602
|
-
}
|
|
603
|
-
if (field.errors.value.length === 0) {
|
|
604
|
-
return null;
|
|
605
|
-
}
|
|
606
|
-
return createVNode("div", {
|
|
607
|
-
"class": "schemx-item__error"
|
|
608
|
-
}, [field.errors.value[0]]);
|
|
609
|
-
};
|
|
985
|
+
const {
|
|
986
|
+
createSlotProps,
|
|
987
|
+
renderAfter,
|
|
988
|
+
renderBefore,
|
|
989
|
+
renderContent,
|
|
990
|
+
renderError,
|
|
991
|
+
renderLabel
|
|
992
|
+
} = createFormItemSlotRenderers({
|
|
993
|
+
schemaRef,
|
|
994
|
+
field,
|
|
995
|
+
form,
|
|
996
|
+
formContext,
|
|
997
|
+
componentProps,
|
|
998
|
+
slots
|
|
999
|
+
});
|
|
610
1000
|
return () => {
|
|
611
|
-
if (!
|
|
1001
|
+
if (!schemaRef.value.visible) {
|
|
612
1002
|
return null;
|
|
613
1003
|
}
|
|
614
|
-
const itemSlot = resolveSlot(slots, normalizeNameKey(
|
|
1004
|
+
const itemSlot = resolveSlot(slots, normalizeNameKey(schemaRef.value.name));
|
|
615
1005
|
if (itemSlot) {
|
|
616
|
-
return itemSlot(
|
|
1006
|
+
return itemSlot(createSlotProps());
|
|
617
1007
|
}
|
|
618
|
-
const labelPosition =
|
|
619
|
-
return createVNode("div", {
|
|
620
|
-
"class": classnames("schemx-item-wrapper"),
|
|
621
|
-
"style":
|
|
622
|
-
}, [createVNode("div", {
|
|
623
|
-
"class": classnames("schemx-item", `schemx-item--label-${labelPosition}`,
|
|
624
|
-
"is-readonly":
|
|
625
|
-
"is-disabled":
|
|
1008
|
+
const labelPosition = schemaRef.value.labelPosition || formContext.schemaConfig.labelPosition;
|
|
1009
|
+
return createVNode("div", mergeProps(attrs, {
|
|
1010
|
+
"class": classnames("schemx-item-wrapper", attrs.class),
|
|
1011
|
+
"style": [attrs.style, schemaRef.value.style]
|
|
1012
|
+
}), [createVNode("div", {
|
|
1013
|
+
"class": classnames("schemx-item", `schemx-item--label-${labelPosition}`, schemaRef.value.class, {
|
|
1014
|
+
"is-readonly": schemaRef.value.readonly,
|
|
1015
|
+
"is-disabled": schemaRef.value.disabled
|
|
626
1016
|
}),
|
|
627
1017
|
"style": {
|
|
628
|
-
...
|
|
1018
|
+
...schemaRef.value.style ?? {}
|
|
629
1019
|
}
|
|
630
1020
|
}, [renderLabel(), createVNode("div", {
|
|
631
1021
|
"class": "schemx-item__content"
|
|
632
|
-
}, [renderContent(), renderError()])])]);
|
|
1022
|
+
}, [renderBefore(), renderContent(), renderAfter(), renderError()])])]);
|
|
633
1023
|
};
|
|
634
1024
|
}
|
|
635
1025
|
});
|
|
636
|
-
const
|
|
637
|
-
|
|
1026
|
+
const FormItem$1 = FormItem;
|
|
1027
|
+
const _hoisted_1$1 = ["aria-busy", "data-loading", "disabled"];
|
|
1028
|
+
const _hoisted_2 = {
|
|
1029
|
+
key: 0,
|
|
1030
|
+
class: "schemx-button__prefix"
|
|
638
1031
|
};
|
|
639
|
-
const
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
1032
|
+
const _hoisted_3 = {
|
|
1033
|
+
key: 1,
|
|
1034
|
+
class: "schemx-button__loading",
|
|
1035
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1036
|
+
width: "1em",
|
|
1037
|
+
height: "1em",
|
|
1038
|
+
viewBox: "0 0 24 24",
|
|
1039
|
+
fill: "none",
|
|
1040
|
+
stroke: "currentColor",
|
|
1041
|
+
"stroke-width": "2",
|
|
1042
|
+
"stroke-linecap": "round",
|
|
1043
|
+
"stroke-linejoin": "round"
|
|
1044
|
+
};
|
|
1045
|
+
const _hoisted_4 = {
|
|
1046
|
+
key: 4,
|
|
1047
|
+
class: "schemx-button__suffix"
|
|
644
1048
|
};
|
|
1049
|
+
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
1050
|
+
...{ name: "SchemxButton", inheritAttrs: false },
|
|
1051
|
+
__name: "index",
|
|
1052
|
+
props: {
|
|
1053
|
+
loading: { type: Boolean, default: false },
|
|
1054
|
+
loadingText: { default: void 0 },
|
|
1055
|
+
disabled: { type: Boolean, default: false },
|
|
1056
|
+
size: { default: "medium" }
|
|
1057
|
+
},
|
|
1058
|
+
setup(__props) {
|
|
1059
|
+
const props = __props;
|
|
1060
|
+
const attrs = useAttrs();
|
|
1061
|
+
const isDisabled = computed(() => props.disabled || props.loading);
|
|
1062
|
+
const buttonClass = computed(() => ["schemx-button", `schemx-button--${props.size}`]);
|
|
1063
|
+
return (_ctx, _cache) => {
|
|
1064
|
+
return openBlock(), createElementBlock("button", mergeProps(unref(attrs), {
|
|
1065
|
+
class: buttonClass.value,
|
|
1066
|
+
"aria-busy": props.loading || void 0,
|
|
1067
|
+
"data-loading": props.loading || void 0,
|
|
1068
|
+
disabled: isDisabled.value
|
|
1069
|
+
}), [
|
|
1070
|
+
_ctx.$slots.prefix ? (openBlock(), createElementBlock("span", _hoisted_2, [
|
|
1071
|
+
renderSlot(_ctx.$slots, "prefix")
|
|
1072
|
+
])) : createCommentVNode("", true),
|
|
1073
|
+
props.loading ? (openBlock(), createElementBlock("svg", _hoisted_3, [..._cache[0] || (_cache[0] = [
|
|
1074
|
+
createStaticVNode('<path d="M12 2v4"></path><path d="m16.2 7.8 2.9-2.9"></path><path d="M18 12h4"></path><path d="m16.2 16.2 2.9 2.9"></path><path d="M12 18v4"></path><path d="m4.9 19.1 2.9-2.9"></path><path d="M2 12h4"></path><path d="m4.9 4.9 2.9 2.9"></path>', 8)
|
|
1075
|
+
])])) : createCommentVNode("", true),
|
|
1076
|
+
props.loading && props.loadingText ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [
|
|
1077
|
+
createTextVNode(toDisplayString(props.loadingText), 1)
|
|
1078
|
+
], 64)) : renderSlot(_ctx.$slots, "default", {}, void 0, void 0, 3),
|
|
1079
|
+
_ctx.$slots.suffix ? (openBlock(), createElementBlock("span", _hoisted_4, [
|
|
1080
|
+
renderSlot(_ctx.$slots, "suffix")
|
|
1081
|
+
])) : createCommentVNode("", true)
|
|
1082
|
+
], 16, _hoisted_1$1);
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
});
|
|
645
1086
|
function getSectionPosition(list, currentKey) {
|
|
646
1087
|
const currentIndex = list.findIndex((item) => item.key === currentKey);
|
|
647
1088
|
if (currentIndex === -1) {
|
|
@@ -665,9 +1106,6 @@ function getSectionPosition(list, currentKey) {
|
|
|
665
1106
|
isLast: !hasPositionItemInSection(list, currentIndex, 1)
|
|
666
1107
|
};
|
|
667
1108
|
}
|
|
668
|
-
function isViewGroupSchema(item) {
|
|
669
|
-
return !!item && "children" in item;
|
|
670
|
-
}
|
|
671
1109
|
function isPositionItem(item) {
|
|
672
1110
|
return !!item && !isViewGroupSchema(item) && item.visible !== false;
|
|
673
1111
|
}
|
|
@@ -686,6 +1124,10 @@ function hasPositionItemInSection(list, startIndex, step) {
|
|
|
686
1124
|
}
|
|
687
1125
|
return false;
|
|
688
1126
|
}
|
|
1127
|
+
const _hoisted_1 = {
|
|
1128
|
+
key: 0,
|
|
1129
|
+
class: "schemx-actions"
|
|
1130
|
+
};
|
|
689
1131
|
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
690
1132
|
...{ name: "SchemxForm" },
|
|
691
1133
|
__name: "form",
|
|
@@ -694,8 +1136,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
694
1136
|
initialValues: { default: () => ({}) },
|
|
695
1137
|
modelValue: { default: () => ({}) },
|
|
696
1138
|
form: { default: void 0 },
|
|
1139
|
+
loading: { type: Boolean, default: void 0 },
|
|
1140
|
+
submitter: { type: [Boolean, Object], default: true },
|
|
1141
|
+
resetter: { type: [Boolean, Object], default: true },
|
|
697
1142
|
class: { default: "" },
|
|
698
1143
|
style: { type: [Boolean, null, String, Object, Array], default: () => ({}) },
|
|
1144
|
+
rendererProps: { default: void 0 },
|
|
699
1145
|
validatorAdapters: {},
|
|
700
1146
|
defaultRendererType: {},
|
|
701
1147
|
rendererRegistry: { default: void 0 },
|
|
@@ -703,6 +1149,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
703
1149
|
onRuleError: {},
|
|
704
1150
|
onFinish: { type: Function, default: void 0 },
|
|
705
1151
|
onFinishFailed: { type: Function, default: void 0 },
|
|
1152
|
+
onReset: { type: Function, default: void 0 },
|
|
1153
|
+
onLoadingChange: { type: Function, default: void 0 },
|
|
706
1154
|
onValuesChange: { type: Function, default: void 0 },
|
|
707
1155
|
onFieldsChange: { type: Function, default: void 0 },
|
|
708
1156
|
lifecycleHooks: {},
|
|
@@ -723,61 +1171,150 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
723
1171
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
724
1172
|
const props = __props;
|
|
725
1173
|
const emit = __emit;
|
|
1174
|
+
const slots = useSlots();
|
|
726
1175
|
const pickSchemaConfig = () => {
|
|
727
1176
|
return pick(props, defaultSchemxConfigKeys);
|
|
728
1177
|
};
|
|
729
1178
|
const formSchemaConfig = reactive(pickSchemaConfig());
|
|
730
1179
|
createFormConfigContext({ schemaConfig: formSchemaConfig });
|
|
731
|
-
const
|
|
1180
|
+
const providedForm = props.form ? props.form : useForm({
|
|
732
1181
|
schemas: props.schemas,
|
|
733
1182
|
schemaConfig: pickSchemaConfig(),
|
|
734
1183
|
initialValues: Object.keys(props.modelValue).length > 0 ? props.modelValue : props.initialValues,
|
|
1184
|
+
rendererProps: props.rendererProps,
|
|
735
1185
|
rendererRegistry: props.rendererRegistry,
|
|
736
1186
|
defaultRendererType: props.defaultRendererType,
|
|
737
1187
|
validationRuleRegistry: props.validationRuleRegistry,
|
|
738
1188
|
validatorAdapters: props.validatorAdapters,
|
|
739
|
-
|
|
1189
|
+
/**
|
|
1190
|
+
* 转发提交成功回调。
|
|
1191
|
+
*
|
|
1192
|
+
* @param values - 提交成功时的完整表单快照。
|
|
1193
|
+
*/
|
|
1194
|
+
onFinish: (values) => {
|
|
740
1195
|
var _a;
|
|
741
|
-
(_a = props.onFinish) == null ? void 0 : _a.call(props, values);
|
|
1196
|
+
return (_a = props.onFinish) == null ? void 0 : _a.call(props, values);
|
|
742
1197
|
},
|
|
743
|
-
|
|
1198
|
+
/**
|
|
1199
|
+
* 转发提交失败回调。
|
|
1200
|
+
*
|
|
1201
|
+
* @param errors - 提交失败时的字段错误集合。
|
|
1202
|
+
*/
|
|
1203
|
+
onFinishFailed: (errors) => {
|
|
744
1204
|
var _a;
|
|
745
|
-
(_a = props.onFinishFailed) == null ? void 0 : _a.call(props, errors);
|
|
1205
|
+
return (_a = props.onFinishFailed) == null ? void 0 : _a.call(props, errors);
|
|
746
1206
|
},
|
|
1207
|
+
/**
|
|
1208
|
+
* 转发完整表单重置回调。
|
|
1209
|
+
*/
|
|
1210
|
+
onReset: () => {
|
|
1211
|
+
var _a;
|
|
1212
|
+
(_a = props.onReset) == null ? void 0 : _a.call(props);
|
|
1213
|
+
},
|
|
1214
|
+
/**
|
|
1215
|
+
* 转发 Core 发出的提交 loading 状态。
|
|
1216
|
+
*
|
|
1217
|
+
* 外部传入 Form 时不会注入该回调,保持实例的创建期边界。
|
|
1218
|
+
*
|
|
1219
|
+
* @param loading - 当前是否处于提交流程中。
|
|
1220
|
+
*/
|
|
1221
|
+
onLoadingChange: (loading) => {
|
|
1222
|
+
var _a;
|
|
1223
|
+
(_a = props.onLoadingChange) == null ? void 0 : _a.call(props, loading);
|
|
1224
|
+
},
|
|
1225
|
+
/**
|
|
1226
|
+
* 转发值变化回调。
|
|
1227
|
+
*
|
|
1228
|
+
* @param changedValues - 本次变更涉及的字段值。
|
|
1229
|
+
* @param latestSnapshot - 变更后的完整表单快照。
|
|
1230
|
+
*/
|
|
747
1231
|
onValuesChange: (changedValues, latestSnapshot) => {
|
|
748
1232
|
var _a;
|
|
749
1233
|
(_a = props.onValuesChange) == null ? void 0 : _a.call(props, changedValues, latestSnapshot);
|
|
750
1234
|
},
|
|
1235
|
+
/**
|
|
1236
|
+
* 转发字段变化回调。
|
|
1237
|
+
*
|
|
1238
|
+
* @param changedPaths - 本次发生变化的字段路径。
|
|
1239
|
+
* @param allPaths - 当前已变更字段路径集合。
|
|
1240
|
+
*/
|
|
751
1241
|
onFieldsChange: (changedPaths, allPaths) => {
|
|
752
1242
|
var _a;
|
|
753
1243
|
(_a = props.onFieldsChange) == null ? void 0 : _a.call(props, changedPaths, allPaths);
|
|
754
1244
|
}
|
|
755
1245
|
});
|
|
756
|
-
|
|
1246
|
+
const isExternalForm = props.form !== void 0;
|
|
1247
|
+
const formInstance = createFormContext(providedForm);
|
|
1248
|
+
const effectiveLoading = computed(() => props.loading ?? formInstance.isLoading());
|
|
1249
|
+
const normalizeActionConfig = (action) => action === true ? {} : action || {};
|
|
1250
|
+
const submitterConfig = computed(() => normalizeActionConfig(props.submitter));
|
|
1251
|
+
const resetterConfig = computed(() => normalizeActionConfig(props.resetter));
|
|
1252
|
+
const getButtonProps = (config) => {
|
|
1253
|
+
const buttonProps = Object.fromEntries(
|
|
1254
|
+
Object.entries(config.buttonProps ?? {}).filter(
|
|
1255
|
+
([name]) => name !== "type" && name !== "onClick"
|
|
1256
|
+
)
|
|
1257
|
+
);
|
|
1258
|
+
return buttonProps;
|
|
1259
|
+
};
|
|
1260
|
+
const submitterButtonProps = computed(() => getButtonProps(submitterConfig.value));
|
|
1261
|
+
const resetterButtonProps = computed(() => getButtonProps(resetterConfig.value));
|
|
1262
|
+
const isSubmitterVisible = computed(
|
|
1263
|
+
() => props.submitter !== false && (props.submitter !== void 0 || slots.submitter)
|
|
1264
|
+
);
|
|
1265
|
+
const isResetterVisible = computed(
|
|
1266
|
+
() => props.resetter !== false && (props.resetter !== void 0 || slots.resetter)
|
|
1267
|
+
);
|
|
1268
|
+
const isActionsVisible = computed(
|
|
1269
|
+
() => isSubmitterVisible.value || isResetterVisible.value
|
|
1270
|
+
);
|
|
1271
|
+
const fieldSlots = computed(
|
|
1272
|
+
() => Object.fromEntries(
|
|
1273
|
+
Object.entries(slots).filter(
|
|
1274
|
+
([slotName]) => slotName !== "submitter" && slotName !== "resetter"
|
|
1275
|
+
)
|
|
1276
|
+
)
|
|
1277
|
+
);
|
|
1278
|
+
const isSubmitterDisabled = computed(
|
|
1279
|
+
() => effectiveLoading.value || Boolean(submitterButtonProps.value.disabled)
|
|
1280
|
+
);
|
|
1281
|
+
const isResetterDisabled = computed(
|
|
1282
|
+
() => effectiveLoading.value || Boolean(resetterButtonProps.value.disabled)
|
|
1283
|
+
);
|
|
757
1284
|
let syncingFromModel = false;
|
|
758
1285
|
watch(
|
|
759
1286
|
() => props.modelValue,
|
|
760
1287
|
(values) => {
|
|
761
1288
|
syncingFromModel = true;
|
|
762
|
-
|
|
1289
|
+
formInstance.setFieldsValue(values);
|
|
763
1290
|
syncingFromModel = false;
|
|
764
|
-
}
|
|
1291
|
+
},
|
|
1292
|
+
{ deep: true }
|
|
1293
|
+
);
|
|
1294
|
+
const handleSubmit = () => formInstance.submit();
|
|
1295
|
+
const handleReset = () => {
|
|
1296
|
+
formInstance.reset();
|
|
1297
|
+
};
|
|
1298
|
+
const formValues = useFormSelector(formInstance, (values) => values);
|
|
1299
|
+
watch(
|
|
1300
|
+
formValues,
|
|
1301
|
+
(latestSnapshot) => {
|
|
1302
|
+
if (syncingFromModel)
|
|
1303
|
+
return;
|
|
1304
|
+
emit("update:modelValue", latestSnapshot);
|
|
1305
|
+
},
|
|
1306
|
+
{ flush: "sync" }
|
|
765
1307
|
);
|
|
766
|
-
const disposeWatch = createWatch(form, (latestSnapshot) => {
|
|
767
|
-
if (syncingFromModel) return;
|
|
768
|
-
emit("update:modelValue", latestSnapshot);
|
|
769
|
-
});
|
|
770
|
-
onUnmounted(disposeWatch);
|
|
771
1308
|
watch(
|
|
772
1309
|
() => props.schemas,
|
|
773
1310
|
(schemas) => {
|
|
774
1311
|
if (!isSchemxSchemas(schemas)) {
|
|
775
|
-
|
|
1312
|
+
formInstance.setSchemas(schemas);
|
|
776
1313
|
}
|
|
777
1314
|
},
|
|
778
1315
|
{ deep: false, immediate: !!props.form }
|
|
779
1316
|
);
|
|
780
|
-
const viewSchemas = useViewSchemas(
|
|
1317
|
+
const viewSchemas = useViewSchemas(formInstance);
|
|
781
1318
|
const getFormItemClass = (schema) => {
|
|
782
1319
|
const { isFirst, isLast } = getSectionPosition(
|
|
783
1320
|
viewSchemas.value,
|
|
@@ -788,13 +1325,18 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
788
1325
|
"schemx-item-wrapper--last": isLast
|
|
789
1326
|
};
|
|
790
1327
|
};
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
1328
|
+
watch(
|
|
1329
|
+
pickSchemaConfig,
|
|
1330
|
+
(nextSchemaConfig) => {
|
|
1331
|
+
Object.assign(formSchemaConfig, nextSchemaConfig);
|
|
1332
|
+
formInstance.updateSchemaConfig(nextSchemaConfig);
|
|
1333
|
+
},
|
|
1334
|
+
{ deep: false, immediate: isExternalForm }
|
|
1335
|
+
);
|
|
796
1336
|
__expose({
|
|
797
|
-
...
|
|
1337
|
+
...formInstance,
|
|
1338
|
+
submit: handleSubmit,
|
|
1339
|
+
reset: handleReset
|
|
798
1340
|
});
|
|
799
1341
|
return (_ctx, _cache) => {
|
|
800
1342
|
return openBlock(), createElementBlock("div", {
|
|
@@ -802,12 +1344,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
802
1344
|
style: normalizeStyle(props.style)
|
|
803
1345
|
}, [
|
|
804
1346
|
(openBlock(true), createElementBlock(Fragment, null, renderList(unref(viewSchemas), (schema) => {
|
|
805
|
-
return openBlock(), createBlock(unref(FormItem), {
|
|
1347
|
+
return openBlock(), createBlock(unref(FormItem$1), {
|
|
806
1348
|
key: schema.key,
|
|
807
1349
|
schema,
|
|
808
1350
|
class: normalizeClass(getFormItemClass(schema))
|
|
809
1351
|
}, createSlots({ _: 2 }, [
|
|
810
|
-
renderList(
|
|
1352
|
+
renderList(fieldSlots.value, (_, slotName) => {
|
|
811
1353
|
return {
|
|
812
1354
|
name: slotName,
|
|
813
1355
|
fn: withCtx((slotProps) => [
|
|
@@ -816,7 +1358,42 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
|
816
1358
|
};
|
|
817
1359
|
})
|
|
818
1360
|
]), 1032, ["schema", "class"]);
|
|
819
|
-
}), 128))
|
|
1361
|
+
}), 128)),
|
|
1362
|
+
isActionsVisible.value ? (openBlock(), createElementBlock("div", _hoisted_1, [
|
|
1363
|
+
isResetterVisible.value && unref(slots).resetter ? renderSlot(_ctx.$slots, "resetter", {
|
|
1364
|
+
form: unref(formInstance),
|
|
1365
|
+
loading: effectiveLoading.value,
|
|
1366
|
+
disabled: isResetterDisabled.value,
|
|
1367
|
+
reset: handleReset
|
|
1368
|
+
}, void 0, void 0, 0) : isResetterVisible.value ? (openBlock(), createBlock(unref(_sfc_main$1), mergeProps({ key: 1 }, resetterButtonProps.value, {
|
|
1369
|
+
class: "schemx-actions-button schemx-actions-button--reset",
|
|
1370
|
+
type: "button",
|
|
1371
|
+
disabled: isResetterDisabled.value,
|
|
1372
|
+
onClick: handleReset
|
|
1373
|
+
}), {
|
|
1374
|
+
default: withCtx(() => [
|
|
1375
|
+
createTextVNode(toDisplayString(resetterConfig.value.text ?? "重置"), 1)
|
|
1376
|
+
]),
|
|
1377
|
+
_: 1
|
|
1378
|
+
}, 16, ["disabled"])) : createCommentVNode("", true),
|
|
1379
|
+
isSubmitterVisible.value && unref(slots).submitter ? renderSlot(_ctx.$slots, "submitter", {
|
|
1380
|
+
form: unref(formInstance),
|
|
1381
|
+
loading: effectiveLoading.value,
|
|
1382
|
+
disabled: isSubmitterDisabled.value,
|
|
1383
|
+
submit: handleSubmit
|
|
1384
|
+
}, void 0, void 0, 2) : isSubmitterVisible.value ? (openBlock(), createBlock(unref(_sfc_main$1), mergeProps({ key: 3 }, submitterButtonProps.value, {
|
|
1385
|
+
class: "schemx-actions-button schemx-actions-button--submit",
|
|
1386
|
+
type: "button",
|
|
1387
|
+
loading: effectiveLoading.value,
|
|
1388
|
+
disabled: isSubmitterDisabled.value,
|
|
1389
|
+
onClick: handleSubmit
|
|
1390
|
+
}), {
|
|
1391
|
+
default: withCtx(() => [
|
|
1392
|
+
createTextVNode(toDisplayString(submitterConfig.value.text ?? "提交"), 1)
|
|
1393
|
+
]),
|
|
1394
|
+
_: 1
|
|
1395
|
+
}, 16, ["loading", "disabled"])) : createCommentVNode("", true)
|
|
1396
|
+
])) : createCommentVNode("", true)
|
|
820
1397
|
], 6);
|
|
821
1398
|
};
|
|
822
1399
|
}
|
|
@@ -831,31 +1408,35 @@ const SchemxFormExport = withInstall(_sfc_main, {
|
|
|
831
1408
|
app.component("SchemxForm", _sfc_main);
|
|
832
1409
|
},
|
|
833
1410
|
/** FormItem 子组件引用 */
|
|
834
|
-
FormItem
|
|
1411
|
+
FormItem: FormItem$1
|
|
835
1412
|
});
|
|
1413
|
+
const SchemxFormExport$1 = SchemxFormExport;
|
|
1414
|
+
function normalizeDictionary(dictionary) {
|
|
1415
|
+
if (typeof dictionary === "function") {
|
|
1416
|
+
return { api: dictionary };
|
|
1417
|
+
}
|
|
1418
|
+
return dictionary;
|
|
1419
|
+
}
|
|
836
1420
|
function WithRemoteOptions(WrappedComponent) {
|
|
837
1421
|
return defineComponent({
|
|
838
1422
|
name: `WithRemoteOptions(${WrappedComponent.name || "Anonymous"})`,
|
|
839
1423
|
inheritAttrs: false,
|
|
840
1424
|
props: {
|
|
841
1425
|
dict: {
|
|
842
|
-
type: Object,
|
|
843
|
-
default: void 0
|
|
844
|
-
},
|
|
845
|
-
fieldName: {
|
|
846
|
-
type: [String, Array],
|
|
1426
|
+
type: [Object, Function],
|
|
847
1427
|
default: void 0
|
|
848
1428
|
}
|
|
849
1429
|
},
|
|
850
1430
|
setup(props, { attrs, slots }) {
|
|
851
|
-
const
|
|
852
|
-
const
|
|
1431
|
+
const dictionary = normalizeDictionary(props.dict);
|
|
1432
|
+
const fieldName = dictionary ? attrs.fieldName ?? useFieldContext().name : void 0;
|
|
1433
|
+
const dictResult = dictionary ? useDictionary(dictionary, fieldName) : null;
|
|
853
1434
|
const childrenProps = computed(() => {
|
|
854
1435
|
return {
|
|
855
1436
|
...attrs,
|
|
856
|
-
dict:
|
|
857
|
-
options:
|
|
858
|
-
loading:
|
|
1437
|
+
dict: dictionary,
|
|
1438
|
+
options: dictionary ? dictResult == null ? void 0 : dictResult.list.value : attrs.options,
|
|
1439
|
+
loading: dictionary ? dictResult == null ? void 0 : dictResult.loading.value : attrs.loading
|
|
859
1440
|
};
|
|
860
1441
|
});
|
|
861
1442
|
return () => h(WrappedComponent, childrenProps.value, slots);
|
|
@@ -863,22 +1444,24 @@ function WithRemoteOptions(WrappedComponent) {
|
|
|
863
1444
|
});
|
|
864
1445
|
}
|
|
865
1446
|
export {
|
|
866
|
-
|
|
867
|
-
|
|
1447
|
+
_sfc_main$1 as Button,
|
|
1448
|
+
FormGroup$1 as FormGroup,
|
|
1449
|
+
FormItem$1 as FormItem,
|
|
868
1450
|
WithRemoteOptions,
|
|
869
1451
|
createFieldContext,
|
|
870
1452
|
createFormConfigContext,
|
|
871
1453
|
createFormContext,
|
|
872
|
-
SchemxFormExport as default,
|
|
1454
|
+
SchemxFormExport$1 as default,
|
|
1455
|
+
getCoreForm,
|
|
873
1456
|
rendererRegistry,
|
|
874
|
-
SchemxFormExport as schemxForm,
|
|
1457
|
+
SchemxFormExport$1 as schemxForm,
|
|
875
1458
|
useDictionary,
|
|
876
|
-
useEffect,
|
|
877
1459
|
useField,
|
|
878
1460
|
useFieldContext,
|
|
879
1461
|
useForm,
|
|
880
1462
|
useFormConfigContext,
|
|
881
1463
|
useFormContext,
|
|
1464
|
+
useFormSelector,
|
|
882
1465
|
useStableRef,
|
|
883
1466
|
useViewSchemas,
|
|
884
1467
|
useWatch,
|