@cloudbase/weda-ui 3.22.2 → 3.23.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 (41) hide show
  1. package/dist/configs/components/wd-tabbar.d.ts +16 -0
  2. package/dist/configs/components/wd-tabbar.js +6 -0
  3. package/dist/configs/components/wd-table.d.ts +1 -0
  4. package/dist/configs/components/wd-table.js +14 -1
  5. package/dist/configs/components/wd-upload-image.js +1 -1
  6. package/dist/configs/index.d.ts +34 -0
  7. package/dist/style/index.css +27 -0
  8. package/dist/style/index.scss +1 -1
  9. package/dist/style/weda-ui.min.css +2 -2
  10. package/dist/web/components/form-input-hooks/index.d.ts +0 -1
  11. package/dist/web/components/form-input-hooks/index.js +8 -14
  12. package/dist/web/components/richText/index.js +1 -1
  13. package/dist/web/components/wd-form/contexts/form-field-context.d.ts +6 -2
  14. package/dist/web/components/wd-form/contexts/form-field-context.js +18 -2
  15. package/dist/web/components/wd-form/contexts/form-field-obj-context.d.ts +2 -2
  16. package/dist/web/components/wd-form/contexts/form-field-obj-context.js +2 -2
  17. package/dist/web/components/wd-form/hoc/form-container-decorator.d.ts +11 -0
  18. package/dist/web/components/wd-form/hoc/form-container-decorator.js +61 -0
  19. package/dist/web/components/wd-form/index.d.ts +4 -49
  20. package/dist/web/components/wd-form/index.js +61 -72
  21. package/dist/web/components/wd-form-obj/base-form-obj.d.ts +5 -1
  22. package/dist/web/components/wd-form-obj/base-form-obj.js +19 -38
  23. package/dist/web/components/wd-input/wd-input.d.ts +2 -0
  24. package/dist/web/components/wd-input/wd-input.js +70 -18
  25. package/dist/web/components/wd-input-number/wd-input-number.js +15 -15
  26. package/dist/web/components/wd-tabbar/wd-tabbar.js +4 -6
  27. package/dist/web/components/wd-table/components/FieldRender/index.d.ts +9 -1
  28. package/dist/web/components/wd-table/components/FieldRender/index.js +33 -4
  29. package/dist/web/components/wd-table/components/FilterFieldsPanel/Fields.d.ts +3 -1
  30. package/dist/web/components/wd-table/components/FilterFieldsPanel/Fields.js +7 -3
  31. package/dist/web/components/wd-table/components/FilterFieldsPanel/FilterFieldItem.js +4 -1
  32. package/dist/web/components/wd-table/components/FilterFieldsPanel/filterFieldsGenerate.d.ts +6 -15
  33. package/dist/web/components/wd-table/components/FilterFieldsPanel/filterFieldsGenerate.js +47 -16
  34. package/dist/web/components/wd-table/components/FilterFieldsPanel/index.js +15 -5
  35. package/dist/web/components/wd-table/utils/index.d.ts +5 -2
  36. package/dist/web/components/wd-table/utils/index.js +12 -1
  37. package/dist/web/components/wd-table/wd-table.d.ts +5 -19
  38. package/dist/web/components/wd-table/wd-table.js +22 -2
  39. package/dist/web/components/wd-tree/utils.js +1 -1
  40. package/dist/web/utils/hooks/useFormLegacy.js +5 -12
  41. package/package.json +5 -5
@@ -0,0 +1,61 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React, { useState, useCallback } from 'react';
3
+ import lodashSet from 'lodash.set';
4
+ import lodashGet from 'lodash.get';
5
+ import { deepClone } from '../../../utils/tool';
6
+ import isObjectEqual from '../../../utils/isObjectEqual';
7
+ import { emptyObject, emptyArray, NOT_EXISTED_VALUE } from '../../../utils/constant';
8
+ import { FormFieldProvider, useFormField } from '../contexts/form-field-context';
9
+ /**
10
+ * 表单容器装饰器高阶组件
11
+ * 用于包装组件,提供表单容器上下文
12
+ * @param Component 需要包装的组件
13
+ * @returns 包装后的组件,支持透传ref
14
+ */
15
+ export function withFormContainer(Component) {
16
+ const WithFormContainer = React.forwardRef((props, ref) => {
17
+ var _a;
18
+ const { ...componentProps } = props;
19
+ const formField = useFormField();
20
+ const _formFieldValues = (_a = props.initialValues) !== null && _a !== void 0 ? _a : props.value;
21
+ const [formFieldsValue, setFormFieldsValue] = useState(_formFieldValues !== null && _formFieldValues !== void 0 ? _formFieldValues : ((props === null || props === void 0 ? void 0 : props.objType) === 'arr' ? emptyArray : emptyObject));
22
+ const [isReadyToCalculate, setIsReadyToCalculate] = useState(true);
23
+ const getFieldValue = useCallback(({ namePath, initialValue }) => {
24
+ const value = lodashGet(formFieldsValue, namePath, NOT_EXISTED_VALUE);
25
+ if (value !== NOT_EXISTED_VALUE) {
26
+ return value;
27
+ }
28
+ else {
29
+ // 设置初始值,兼容表单项变量绑定场景
30
+ // form的初始值>formArr/formObj/formDetail>field
31
+ if (initialValue !== undefined) {
32
+ return initialValue;
33
+ }
34
+ return null;
35
+ }
36
+ }, [formFieldsValue]);
37
+ const setFieldValue = useCallback(({ namePath, value }) => {
38
+ setFormFieldsValue((formData) => {
39
+ if (typeof formData !== 'object' || formData === null) {
40
+ console.warn('setValue data need expect a object but got null', formData);
41
+ return formData;
42
+ }
43
+ // 获取当前值并比较
44
+ const _value = lodashGet(formData, namePath, NOT_EXISTED_VALUE);
45
+ if (isObjectEqual(_value, value))
46
+ return formData;
47
+ const _formData = deepClone(formData);
48
+ lodashSet(_formData, namePath, value);
49
+ return _formData;
50
+ });
51
+ }, []);
52
+ // 在表单容器内直接渲染原始组件
53
+ if (formField) {
54
+ return _jsx(Component, { ...props, ref: ref, isInformContainer: true });
55
+ }
56
+ return (_jsx(FormFieldProvider, { setFieldValue: setFieldValue, getFieldValue: getFieldValue, isInformContainer: true, formFieldsValue: formFieldsValue, setFormFieldsValue: setFormFieldsValue, isReadyToCalculate: isReadyToCalculate, setIsReadyToCalculate: setIsReadyToCalculate, children: _jsx(Component, { ...componentProps, formFieldsValue: formFieldsValue, ref: ref }) }));
57
+ });
58
+ // 设置显示名称,方便调试
59
+ WithFormContainer.displayName = `withFormContainer(${Component.displayName || Component.name || 'Component'})`;
60
+ return WithFormContainer;
61
+ }
@@ -6,53 +6,8 @@ import '../style';
6
6
  export type WdFromProps = CommonPropsType & DataType & EventsType & {
7
7
  appCloud: typeof tcbAppCloud;
8
8
  };
9
- declare const _default: React.MemoExoticComponent<React.ForwardRefExoticComponent<CommonPropsType & {
10
- _id?: string;
11
- value: Record<string, any>;
12
- formType: "create" | "edit" | "read";
13
- contentSlot: React.ReactNode;
14
- layout: "vertical" | "horizontal";
15
- dataSourceName: string;
16
- labelAlign: "left" | "right";
17
- datasourceType: "connector" | "custom-connector" | "model" | "expression";
18
- methodGetItem: string;
19
- paramGetItem: Record<string, unknown>;
20
- methodCreate: string;
21
- methodUpdate: string;
22
- isDisabledSubmit: boolean;
23
- formType_bind: boolean;
24
- fields: {
25
- name: string;
26
- componentType: string;
27
- }[];
28
- colNum: never;
29
- lgWidth: "lg" | "sm" | "md" | "hundred";
30
- initialValues: Record<string, unknown>;
31
- } & {
32
- events: {
33
- submit: (eventDetail: unknown, ...args: unknown[]) => unknown;
34
- validateSuccess: (eventDetail: {
35
- errors: Record<string, string>;
36
- }, ...args: unknown[]) => unknown;
37
- validateFail: (eventDetail: {
38
- errors: Record<string, string>;
39
- }, ...args: unknown[]) => unknown;
40
- queryEmpty: (eventDetail: {
41
- data: Record<string, any>;
42
- }, ...args: unknown[]) => unknown;
43
- querySuccess: (eventDetail: {
44
- data: Record<string, any>;
45
- }, ...args: unknown[]) => unknown;
46
- queryFail: (eventDetail: {
47
- error: {
48
- requestid?: string;
49
- code: string;
50
- message: string;
51
- original: any;
52
- };
53
- }, ...args: unknown[]) => unknown;
54
- };
55
- } & {
56
- appCloud: typeof tcbAppCloud;
57
- } & React.RefAttributes<unknown>>>;
9
+ declare const _default: React.MemoExoticComponent<React.ForwardRefExoticComponent<Pick<{
10
+ [key: string]: any;
11
+ initialValues?: any;
12
+ }, string | number> & React.RefAttributes<unknown>>>;
58
13
  export default _default;
@@ -19,7 +19,6 @@ import { useDataSource } from '../../utils/hooks/useDataSource';
19
19
  import { WdForm as FormUi } from './wd-form';
20
20
  import StatusContent from '../statusContent';
21
21
  import { deepClone } from '../../utils/tool';
22
- import isObjectEqual from '../../utils/isObjectEqual';
23
22
  import { convertMethodParam } from '../../utils/hooks/useFormLegacy';
24
23
  import '../style';
25
24
  import { getErrorObjectFromValidateResult, convertFormData } from './form-utils';
@@ -27,13 +26,15 @@ import { isNil } from '../../utils/lodash';
27
26
  import { FormTypeProvider } from './contexts/form-type-context';
28
27
  import { FormLayoutProvider } from './contexts/form-layout-context';
29
28
  import { FormWidgetProvider } from './contexts/form-widget-context';
30
- import { FormFieldProvider } from './contexts/form-field-context';
29
+ import { useFormField } from './contexts/form-field-context';
30
+ // eslint-disable-next-line tree-shaking/no-side-effects-in-initialization
31
+ import { withFormContainer } from './hoc/form-container-decorator';
31
32
  import { useSyncValue } from '../../utils/hooks/useSyncValue';
32
33
  import useDebouncedCallback from '../../utils/hooks/use-debounced-callback';
33
34
  const SET_VALUE_DEBOUNCE_TIMEOUT = 250;
34
35
  const logger = debug('wd-form');
35
- const WdForm = React.forwardRef(function WdForm(props, ref) {
36
- var _a, _b, _c;
36
+ const WdForm = withFormContainer(React.forwardRef(function WdForm(props, ref) {
37
+ var _a, _b;
37
38
  const { className, id, style, contentSlot: contentSlotEl, layout = 'horizontal', formType = 'create', _id, datasourceType = 'model', dataSourceName, methodGetItem, methodCreate, methodUpdate, paramGetItem, appCloud = tcbAppCloud, lgWidth, labelAlign = 'left', initialValues: _initialValues,
38
39
  // 兼容流程setValue调用,其他地方别用
39
40
  $node, $widget, } = props;
@@ -74,16 +75,32 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
74
75
  const [initialValues, setInitialValues] = useState((_b = deepClone(_initialValues)) !== null && _b !== void 0 ? _b : emptyObject);
75
76
  const [propsValue] = useSyncValue(props.value);
76
77
  // 表单值
77
- const [formData, setFormData] = useState((_c = deepClone(_initialValues)) !== null && _c !== void 0 ? _c : emptyObject);
78
+ // const [formData, setFormData] = useState<Record<string, unknown>>(deepClone(_initialValues) ?? emptyObject);
79
+ const formField = useFormField();
80
+ const { setFormFieldsValue, formFieldsValue, setIsReadyToCalculate } = formField || {};
78
81
  // 转换后表单值,仅保留已挂载表单项的值
79
- const formFieldsValue = useMemo(() => {
80
- return convertFormData(formData, formItemMapList, fieldInitValueCache);
81
- }, [formData, formItemMapList, fieldInitValueCache]);
82
+ const formFieldConvertValues = useMemo(() => {
83
+ return convertFormData(formFieldsValue, formItemMapList, fieldInitValueCache);
84
+ }, [formFieldsValue, formItemMapList, fieldInitValueCache]);
82
85
  useDebouncedEffect(() => {
83
86
  var _a, _b;
84
87
  // 表单容器上挂载的表单项的值
85
- (_b = (_a = eventsRef === null || eventsRef === void 0 ? void 0 : eventsRef.current) === null || _a === void 0 ? void 0 : _a.onDataChange) === null || _b === void 0 ? void 0 : _b.call(_a, { data: formFieldsValue });
86
- }, [formFieldsValue],
88
+ (_b = (_a = eventsRef === null || eventsRef === void 0 ? void 0 : eventsRef.current) === null || _a === void 0 ? void 0 : _a.onDataChange) === null || _b === void 0 ? void 0 : _b.call(_a, { data: formFieldConvertValues });
89
+ }, [formFieldConvertValues],
90
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
91
+ SET_VALUE_DEBOUNCE_TIMEOUT);
92
+ useEffect(() => {
93
+ if (['edit', 'read'].includes(formType) && !hasSetInitValueRef.current) {
94
+ // 表单容器编辑和只读状态下,接口返回数据后具备相应数据计算条件
95
+ setIsReadyToCalculate(false);
96
+ }
97
+ }, [formType, setIsReadyToCalculate]);
98
+ useDebouncedEffect(() => {
99
+ // 在编辑/只读场景下,当所有依赖表单数据全部完成时,允许触发计算逻辑
100
+ if (['edit', 'read'].includes(formType) && hasSetInitValueRef.current) {
101
+ setIsReadyToCalculate(true);
102
+ }
103
+ }, [hasSetInitValueRef.current, formType],
87
104
  // eslint-disable-next-line @typescript-eslint/no-magic-numbers
88
105
  SET_VALUE_DEBOUNCE_TIMEOUT);
89
106
  const eventsRef = useSyncedRef(props.events);
@@ -182,9 +199,9 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
182
199
  if (Object.keys(errorObj !== null && errorObj !== void 0 ? errorObj : {}).length === 0) {
183
200
  validateSuccess({ errors: {} });
184
201
  const extra = ['read', 'edit'].includes(formType) && _id ? { _id } : {};
185
- submit && submit(deepClone({ ...extra, ...formFieldsValue }));
202
+ submit && submit(deepClone({ ...extra, ...formFieldConvertValues }));
186
203
  // 流程用了;
187
- return formFieldsValue;
204
+ return formFieldConvertValues;
188
205
  }
189
206
  else {
190
207
  setErrors(errorObj);
@@ -199,19 +216,30 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
199
216
  const r = await submitPromiseCache.current;
200
217
  submitPromiseCache.current = null;
201
218
  return r;
202
- }, [_id, eventsRef, formFieldsValue, formType, isDisabledSubmit, validate]);
219
+ }, [_id, eventsRef, formFieldConvertValues, formType, isDisabledSubmit, validate]);
203
220
  const submit = useDebouncedCallback(submitHandler, SET_VALUE_DEBOUNCE_TIMEOUT, {
204
221
  // eslint-disable-next-line @typescript-eslint/no-magic-numbers
205
222
  maxWait: SET_VALUE_DEBOUNCE_TIMEOUT,
206
223
  trailing: true,
207
224
  });
208
- const setValue = useCallback((data) => {
225
+ const setValue = useCallback((data, notMerge = false) => {
226
+ // notMerge 默认false,表示与之前的表单值合并
209
227
  if (typeof data !== 'object' || data === null) {
210
228
  console.warn('setValue data need expect a object but got null', data);
211
229
  return;
212
230
  }
213
- setFormData(data);
214
- }, []);
231
+ if (notMerge) {
232
+ setFormFieldsValue(data);
233
+ }
234
+ else {
235
+ setFormFieldsValue((formFieldsValue) => ({ ...formFieldsValue, ...data }));
236
+ }
237
+ }, [setFormFieldsValue]);
238
+ const setValueDebounce = useDebouncedCallback(setValue, SET_VALUE_DEBOUNCE_TIMEOUT, {
239
+ // eslint-disable-next-line @typescript-eslint/no-magic-numbers
240
+ maxWait: SET_VALUE_DEBOUNCE_TIMEOUT * 2,
241
+ trailing: true,
242
+ });
215
243
  const clearValidate = useCallback(() => {
216
244
  formsItemMap.forEach((items) => {
217
245
  items.forEach((item) => {
@@ -223,10 +251,6 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
223
251
  });
224
252
  });
225
253
  }, [formsItemMap]);
226
- const [isInformContainer, setIsInformContainer] = React.useState(false);
227
- React.useEffect(() => {
228
- setIsInformContainer(true);
229
- }, []);
230
254
  useMountEffect(() => {
231
255
  logger.debug('formItemMap', formsItemMap);
232
256
  });
@@ -291,19 +315,14 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
291
315
  // eslint-disable-next-line react-hooks/exhaustive-deps
292
316
  [formsItemMap]);
293
317
  const { data: formInitValueToSet } = useInitValueFromRemote(datasourceType, dataSourceProfile, fetchedInitialValues);
294
- const setValueDebounce = useDebouncedCallback(setValue, SET_VALUE_DEBOUNCE_TIMEOUT, {
295
- // eslint-disable-next-line @typescript-eslint/no-magic-numbers
296
- maxWait: SET_VALUE_DEBOUNCE_TIMEOUT * 2,
297
- trailing: true,
298
- });
299
318
  useEffect(() => {
300
319
  if (initValueLoadingStatus !== 'done' || !fetchedInitialValues)
301
320
  return;
302
321
  if (!initValueFetchError && formInitValueToSet) {
303
322
  /*
304
- 错误处理放在了 @link {onInitialValuesError}
305
- 下面是可以拿到data了
306
- */
323
+ 错误处理放在了 @link {onInitialValuesError}
324
+ 下面是可以拿到data了
325
+ */
307
326
  // TODO: 有哪些key可以暴露
308
327
  setInitialValues((original) => {
309
328
  if (hasSetInitValueRef.current) {
@@ -326,7 +345,7 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
326
345
  }, [authValue, isDataModel, initDataSourceFieldsWithAuth, formItemMapKey]);
327
346
  const submitParams = useRemoteParamsFromValue({
328
347
  dataSourceProfile,
329
- formData: formFieldsValue,
348
+ formData: formFieldConvertValues,
330
349
  formType,
331
350
  _id,
332
351
  });
@@ -378,23 +397,22 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
378
397
  setValue(val, opts = { notMerge: false }) {
379
398
  const value = convertMethodParam(val);
380
399
  // notMerge 默认false,表示与之前的表单值合并
381
- if (opts.notMerge) {
382
- setValueDebounce(value);
383
- }
384
- else {
385
- const _formData = deepClone(formData);
386
- setValueDebounce({ ..._formData, ...value });
387
- }
400
+ setValueDebounce(value, opts.notMerge);
388
401
  },
389
402
  reset() {
390
403
  setValueDebounce(initialValues);
391
404
  },
392
405
  clearValue({ isImmediate = false } = {}) {
406
+ // 创建一个对象,将所有表单项的值设为 undefined
407
+ const emptyValues = formItemMapList.reduce((acc, key) => {
408
+ acc[key] = null;
409
+ return acc;
410
+ }, {});
393
411
  if (isImmediate) {
394
- setValue({});
412
+ setValue(emptyValues);
395
413
  }
396
414
  else {
397
- setValueDebounce({});
415
+ setValueDebounce(emptyValues);
398
416
  }
399
417
  },
400
418
  async validate() {
@@ -422,7 +440,7 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
422
440
  authValue,
423
441
  layout,
424
442
  dataSourceName,
425
- value: formFieldsValue,
443
+ value: formFieldConvertValues,
426
444
  remoteValue: fetchedInitialValues,
427
445
  dataSourceProfile,
428
446
  errors,
@@ -444,7 +462,7 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
444
462
  authValue,
445
463
  layout,
446
464
  dataSourceName,
447
- formFieldsValue,
465
+ formFieldConvertValues,
448
466
  fetchedInitialValues,
449
467
  dataSourceProfile,
450
468
  errors,
@@ -459,7 +477,7 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
459
477
  fieldInitValueCache,
460
478
  formsItemMap,
461
479
  setValueDebounce,
462
- formData,
480
+ formItemMapList,
463
481
  setValue,
464
482
  validate,
465
483
  eventsRef,
@@ -489,38 +507,9 @@ const WdForm = React.forwardRef(function WdForm(props, ref) {
489
507
  const labelPosition = useMemo(() => {
490
508
  return `${layout}-${labelAlign}`;
491
509
  }, [layout, labelAlign]);
492
- const getFieldValue = useCallback(({ namePath, initialValue }) => {
493
- const value = lodashGet(formData, namePath, NOT_EXISTED_VALUE);
494
- if (value !== NOT_EXISTED_VALUE) {
495
- return value;
496
- }
497
- else {
498
- // 设置初始值,兼容表单项变量绑定场景
499
- // form的初始值>formArr/formObj/formDetail>field
500
- if (initialValue !== undefined) {
501
- return initialValue;
502
- }
503
- return null;
504
- }
505
- }, [formData]);
506
- const setFieldValue = useCallback(({ namePath, value }) => {
507
- setFormData((formData) => {
508
- const _formData = deepClone(formData);
509
- const _value = lodashGet(_formData, namePath, NOT_EXISTED_VALUE);
510
- if (isObjectEqual(_value, value)) {
511
- return _formData;
512
- }
513
- lodashSet(_formData, namePath, value);
514
- if (typeof _formData !== 'object' || _formData === null) {
515
- console.warn('setValue data need expect a object but got null', _formData);
516
- return formData;
517
- }
518
- return _formData;
519
- });
520
- }, []);
521
510
  if (initValueLoadingStatus === 'loading' && !fetchedInitialValues) {
522
511
  return _jsx(StatusContent, { emptyText: '数据加载中,请稍候...', component: "table", icon: "loading" });
523
512
  }
524
- return (_jsx(FormWidgetProvider, { "$widget": $widget, children: _jsx(FormLayoutProvider, { layout: layout, children: _jsx(FormTypeProvider, { formType: formType, children: _jsx(FormFieldProvider, { setFieldValue: setFieldValue, isInformContainer: isInformContainer, getFieldValue: getFieldValue, children: _jsx(FormUi, { layout: layout, className: cls, style: style, id: id, lgWidth: lgWidth, labelPosition: labelPosition, children: initValueFetchError ? (_jsx(StatusContent, { emptyText: '数据加载失败', errorObj: initValueFetchError, icon: 'error', isH5: isH5 })) : (contentSlot) }) }) }) }) }));
525
- });
513
+ return (_jsx(FormWidgetProvider, { "$widget": $widget, children: _jsx(FormLayoutProvider, { layout: layout, children: _jsx(FormTypeProvider, { formType: formType, children: _jsx(FormUi, { layout: layout, className: cls, style: style, id: id, lgWidth: lgWidth, labelPosition: labelPosition, children: initValueFetchError ? (_jsx(StatusContent, { emptyText: '数据加载失败', errorObj: initValueFetchError, icon: 'error', isH5: isH5 })) : (contentSlot) }) }) }) }));
514
+ }));
526
515
  export default React.memo(WdForm);
@@ -3,12 +3,16 @@ import type { CommonPropsType } from '../../types';
3
3
  import type { DataType as ObjDataType } from '../../../configs/components/wd-form-obj';
4
4
  import type { DataType as ArrDataType } from '../../../configs/components/wd-form-arr';
5
5
  import '../style';
6
- export declare const BaseFormObj: React.ForwardRefExoticComponent<BaseFormObjProps & React.RefAttributes<any>>;
6
+ export declare const BaseFormObj: React.ForwardRefExoticComponent<Pick<{
7
+ [key: string]: any;
8
+ initialValues?: any;
9
+ }, string | number> & React.RefAttributes<unknown>>;
7
10
  type DataType = ObjDataType & ArrDataType;
8
11
  export interface BaseFormObjProps extends CommonPropsType, DataType {
9
12
  disabled: boolean;
10
13
  readOnly: boolean;
11
14
  objType: 'arr' | 'obj';
12
15
  isRoot?: boolean;
16
+ isInformContainer?: boolean;
13
17
  }
14
18
  export {};
@@ -1,23 +1,24 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  /* eslint-disable @typescript-eslint/no-magic-numbers */
3
- import { forwardRef, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
3
+ import { forwardRef, useCallback, useEffect, useLayoutEffect, useRef, useState, useMemo } from 'react';
4
4
  import { useDeepCompareEffect } from '@react-hookz/web';
5
5
  import { useConfig } from '../../utils/config-context';
6
6
  import { WdFormItem } from '../wd-form-item';
7
7
  import { usePlatform } from '../../utils/platform';
8
8
  import classNames from '../../utils/classnames';
9
9
  import { FormFieldObjProvider } from '../wd-form/contexts/form-field-obj-context';
10
- import { FormFieldProvider } from '../wd-form/contexts/form-field-context';
11
- import { noop, NOT_EXISTED_VALUE } from '../../utils/constant';
10
+ import { useFormField } from '../wd-form/contexts/form-field-context';
11
+ import { noop } from '../../utils/constant';
12
12
  import lodashSet from 'lodash.set';
13
- import lodashGet from 'lodash.get';
14
13
  import { useFormInputTrait } from '../form-input-hooks';
15
14
  import { deepClone } from '../../utils/tool';
16
15
  import isObjectEqual from '../../utils/isObjectEqual';
16
+ // eslint-disable-next-line tree-shaking/no-side-effects-in-initialization
17
+ import { withFormContainer } from '../wd-form/hoc/form-container-decorator';
17
18
  import '../style';
18
19
  import useDebouncedCallback from '../../utils/hooks/use-debounced-callback';
19
20
  const classRoot = 'form-obj';
20
- export const BaseFormObj = forwardRef(function BaseFormObj(props, ref) {
21
+ export const BaseFormObj = withFormContainer(forwardRef(function BaseFormObj(props, ref) {
21
22
  const { classPrefix } = useConfig();
22
23
  const platform = usePlatform();
23
24
  const cls = classNames({
@@ -34,8 +35,9 @@ export const BaseFormObj = forwardRef(function BaseFormObj(props, ref) {
34
35
  const [status, updateStatus] = useState('edit');
35
36
  const [innerHandle, setInnerHandle] = useState({});
36
37
  const inputRef = useRef({});
37
- const [isInformObjContainer, setIsInformObjContainer] = useState(false);
38
- const { name, value: objValue, readOnly, disabled, visible, onChange: _onChange, namePath, isInformContainer: _isInformContainer, } = useFormInputTrait({
38
+ const formField = useFormField();
39
+ const { setFormFieldsValue, formFieldsValue } = formField || {};
40
+ const { name, value: _objValue, readOnly, disabled, visible, onChange: _onChange, namePath, } = useFormInputTrait({
39
41
  label: props.label,
40
42
  value: props.value,
41
43
  name: props.name,
@@ -47,9 +49,10 @@ export const BaseFormObj = forwardRef(function BaseFormObj(props, ref) {
47
49
  requiredMsg: '',
48
50
  $widget: props.$widget,
49
51
  setInnerHandle,
50
- onChange: noop,
52
+ onChange: props.isInformContainer ? noop : setFormFieldsValue,
51
53
  $node: props.$node,
52
54
  });
55
+ const objValue = useMemo(() => (props.isInformContainer ? _objValue : formFieldsValue), [_objValue, formFieldsValue, props.isInformContainer]);
53
56
  const valueRef = useRef(props.value);
54
57
  useDeepCompareEffect(() => {
55
58
  if (isObjectEqual(valueRef.current, objValue)) {
@@ -57,9 +60,6 @@ export const BaseFormObj = forwardRef(function BaseFormObj(props, ref) {
57
60
  }
58
61
  triggerOnDataChange(objValue);
59
62
  }, [objValue]);
60
- useEffect(() => {
61
- setIsInformObjContainer(true);
62
- }, []);
63
63
  useEffect(() => {
64
64
  if (readOnly) {
65
65
  updateStatus('readOnly');
@@ -78,7 +78,7 @@ export const BaseFormObj = forwardRef(function BaseFormObj(props, ref) {
78
78
  var _a, _b;
79
79
  valueRef.current = value;
80
80
  (_b = (_a = props.events) === null || _a === void 0 ? void 0 : _a.onDataChange) === null || _b === void 0 ? void 0 : _b.call(_a, { data: value });
81
- }, [props.events]), 500);
81
+ }, [props.events]), 250);
82
82
  const dealArrChange = useCallback((params, objValue) => {
83
83
  let value;
84
84
  // 顶层为数组类型
@@ -138,12 +138,13 @@ export const BaseFormObj = forwardRef(function BaseFormObj(props, ref) {
138
138
  if (isObjectEqual(value, objValue) || (value === null && isObjectEqual(initValue, objValue))) {
139
139
  return;
140
140
  }
141
- _onChange(value || initValue);
142
- triggerOnDataChange(value);
143
- }, [disabled, readOnly, props.objType, objValue, _onChange, triggerOnDataChange, dealArrChange]);
141
+ if (_onChange) {
142
+ _onChange(value || initValue);
143
+ }
144
+ }, [disabled, readOnly, props.objType, objValue, _onChange, dealArrChange]);
144
145
  const changeDebounce = useDebouncedCallback(useCallback((value) => {
145
146
  change(value);
146
- }, [change]), 300);
147
+ }, [change]), 250);
147
148
  useLayoutEffect(() => {
148
149
  if (!ref)
149
150
  return;
@@ -187,25 +188,5 @@ export const BaseFormObj = forwardRef(function BaseFormObj(props, ref) {
187
188
  readOnly,
188
189
  };
189
190
  }, [innerHandle, props.label, name, objValue, visible, disabled, readOnly, props.objType, change, ref, changeDebounce]);
190
- const setFieldValue = useCallback(({ namePath, value }) => {
191
- change({ name: namePath, value });
192
- }, [change]);
193
- const getFieldValue = useCallback(({ namePath, initialValue }) => {
194
- const value = lodashGet(objValue, namePath, NOT_EXISTED_VALUE);
195
- if (value !== NOT_EXISTED_VALUE) {
196
- return value;
197
- }
198
- else {
199
- // 设置初始值,兼容表单项变量绑定场景
200
- // form的初始值>formArr/formObj/formDetail>field
201
- if (initialValue !== undefined) {
202
- return initialValue;
203
- }
204
- return null;
205
- }
206
- }, [objValue]);
207
- if (_isInformContainer) {
208
- return (_jsx(FormFieldObjProvider, { namePath: namePath, status: status, objType: props.objType, children: _jsx(WdFormItem, { ...formItemProps, children: _jsx("fieldset", { className: cls, id: props.id, style: props.style, role: "container", "data-testid": "formObj", children: props.children }) }) }));
209
- }
210
- return (_jsx(FormFieldProvider, { setFieldValue: setFieldValue, isInformContainer: isInformObjContainer, getFieldValue: getFieldValue, children: _jsx(FormFieldObjProvider, { namePath: namePath, status: status, children: _jsx(WdFormItem, { ...formItemProps, children: _jsx("fieldset", { className: cls, id: props.id, style: props.style, role: "container", "data-testid": "formObj", children: props.children }) }) }) }));
211
- });
191
+ return (_jsx(FormFieldObjProvider, { namePath: namePath, status: status, isChildField: props.isInformContainer, children: _jsx(WdFormItem, { ...formItemProps, children: _jsx("fieldset", { className: cls, id: props.id, style: props.style, role: "container", "data-testid": "formObj", children: props.children }) }) }));
192
+ }));
@@ -67,9 +67,11 @@ export declare const WdInput: React.ForwardRefExoticComponent<CommonPropsType &
67
67
  wrapClassName?: string;
68
68
  classRoot?: string;
69
69
  inputPattern?: RegExp;
70
+ isTagInput?: boolean;
70
71
  } & React.RefAttributes<any>>;
71
72
  export type WdInputProps = CommonPropsType & DataType & EventsType & {
72
73
  wrapClassName?: string;
73
74
  classRoot?: string;
74
75
  inputPattern?: RegExp;
76
+ isTagInput?: boolean;
75
77
  };