@cloudbase/weda-ui 3.19.0 → 3.20.1
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/dist/configs/components/wd-form.d.ts +2 -2
- package/dist/configs/components/wd-form.js +2 -2
- package/dist/configs/components/wd-table.d.ts +3 -3
- package/dist/configs/index.d.ts +6 -6
- package/dist/configs/type-utils/type-form.d.ts +2 -2
- package/dist/style/weda-ui.min.css +1 -1
- package/dist/web/components/form-input-hooks/index.d.ts +3 -1
- package/dist/web/components/form-input-hooks/index.js +93 -54
- package/dist/web/components/form-rich-text/index.d.ts +3 -3
- package/dist/web/components/form-rich-text/index.js +8 -4
- package/dist/web/components/formdetail/index.d.ts +1 -1
- package/dist/web/components/formdetail/index.js +28 -42
- package/dist/web/components/richText/index.js +9 -3
- package/dist/web/components/wd-form/contexts/form-field-arr-context.d.ts +21 -0
- package/dist/web/components/wd-form/contexts/form-field-arr-context.js +10 -0
- package/dist/web/components/wd-form/contexts/form-field-context.d.ts +19 -0
- package/dist/web/components/wd-form/contexts/form-field-context.js +10 -0
- package/dist/web/components/wd-form/contexts/form-field-obj-context.d.ts +13 -0
- package/dist/web/components/wd-form/contexts/form-field-obj-context.js +10 -0
- package/dist/web/components/wd-form/index.d.ts +4 -4
- package/dist/web/components/wd-form/index.js +142 -191
- package/dist/web/components/wd-form-item/wd-form-item.d.ts +2 -2
- package/dist/web/components/wd-form-item/wd-form-item.js +96 -14
- package/dist/web/components/wd-form-obj/base-form-obj.js +66 -197
- package/dist/web/components/wd-input/wd-input.js +1 -1
- package/dist/web/components/wd-input-number/wd-input-number.js +43 -17
- package/dist/web/components/wd-rich-text/wd-rich-text.d.ts +1 -1
- package/dist/web/components/wd-rich-text/wd-rich-text.js +7 -3
- package/dist/web/components/wd-select/select/selectUI.js +9 -2
- package/dist/web/utils/widget-api/index.d.ts +0 -14
- package/dist/web/utils/widget-api/index.js +0 -7
- package/package.json +1 -1
|
@@ -1,18 +1,47 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import React, { useState } from 'react';
|
|
2
3
|
import classNames from '../../utils/classnames';
|
|
3
4
|
import { useConfig } from '../../utils/config-context';
|
|
4
5
|
import { WdIcon } from '../wd-icon';
|
|
6
|
+
import { WdCard } from '../wd-card';
|
|
5
7
|
import { WdBubble } from '../wd-bubble';
|
|
6
8
|
import { WdFormItemReadOnly } from './wd-form-item-read-only';
|
|
7
9
|
import { usePlatform, textToString } from '../../utils/platform';
|
|
8
|
-
import { useLabelAlign, useLayout, useSize, convertPx, convertIconSize
|
|
10
|
+
import { useLabelAlign, useLayout, useSize, convertPx, convertIconSize } from '../../utils/hooks/useFormLegacy';
|
|
9
11
|
import { X_RUNTIME_DEFAULT } from '../../../configs/type-utils/x-runtime-default';
|
|
12
|
+
// 标题部分,含必填、提示
|
|
13
|
+
const Label = React.memo(function Label({ labelCls, labelStyle, itemWrap, inputId, labelRoot, label, labelTips, iconSize, LabelAdornment, }) {
|
|
14
|
+
return (_jsxs("div", { className: labelCls, style: labelStyle, children: [_jsxs("label", { className: `${itemWrap}__label-content`, htmlFor: inputId, children: [_jsx("span", { className: `${itemWrap}__label-text ${labelRoot}-text`, title: label, children: textToString(label) }), labelTips && (_jsx("span", { className: `${itemWrap}__label-explain`, children: _jsx(WdBubble, { style: { display: 'inline' }, bubbleChildren: _jsx(WdIcon, { name: "td:help-circle", size: iconSize }), bubbleContent: textToString(labelTips), promptTheme: "dark" }) }))] }), LabelAdornment && _jsx("div", { className: `${itemWrap}__label-adornment`, children: LabelAdornment })] }));
|
|
15
|
+
});
|
|
16
|
+
// // 输入部分
|
|
17
|
+
const Item = React.memo(function Item({ itemWrap, testId, controlWrapCls, readOnly, before, after, readValue, readBeforeAfter, format, value, children, }) {
|
|
18
|
+
return (_jsx("div", { className: `${itemWrap}__control`, "data-testid": testId, children: _jsx("div", { className: controlWrapCls, children: _jsx(WdFormItemReadOnly, { readOnly: readOnly, readValue: readValue, version: "wd", before: before, after: after, readBeforeAfter: readBeforeAfter, format: format, value: value, children: children }) }) }));
|
|
19
|
+
});
|
|
20
|
+
const LabelContainer = React.memo(function LabelContainer(props) {
|
|
21
|
+
const { mode, labelProps, itemProps, children } = props || {};
|
|
22
|
+
const cardRef = React.createRef();
|
|
23
|
+
const [iconName, setIconName] = useState('chevronup');
|
|
24
|
+
const headerSlot = (_jsxs(_Fragment, { children: [_jsx(WdIcon, { name: iconName, events: {
|
|
25
|
+
tap: () => {
|
|
26
|
+
setIconName(iconName === 'chevrondown' ? 'chevronup' : 'chevrondown');
|
|
27
|
+
},
|
|
28
|
+
} }), _jsx(Label, { ...labelProps })] }));
|
|
29
|
+
if (mode === 'custom' || mode === 'table') {
|
|
30
|
+
return _jsx(Item, { ...itemProps, children: children });
|
|
31
|
+
}
|
|
32
|
+
const contentSlot = _jsx(Item, { ...itemProps, children: children });
|
|
33
|
+
return (_jsx(WdCard, { ref: cardRef, className: iconName === 'chevrondown' ? 'wd-card-content__hidden' : '', showContent: true, headerSlot: headerSlot, contentSlot: contentSlot, events: { tap: () => { } } }));
|
|
34
|
+
});
|
|
35
|
+
const LabelContainerComp = React.memo(function LabelContainerComp({ isRoot, isH5, mode, labelProps, itemProps, children, }) {
|
|
36
|
+
const showLabel = isRoot && !isH5;
|
|
37
|
+
return (_jsxs(_Fragment, { children: [showLabel && _jsx(Label, { ...labelProps }), _jsx(LabelContainer, { isRoot: isRoot, labelProps: labelProps, itemProps: itemProps, mode: mode, children: children })] }));
|
|
38
|
+
});
|
|
10
39
|
/**
|
|
11
40
|
* 表单项包裹,包括标题、文本提示、校验
|
|
12
41
|
*/
|
|
13
42
|
// eslint-disable-next-line complexity
|
|
14
|
-
export function WdFormItem(props) {
|
|
15
|
-
const { id, className, style, label, labelVisible = X_RUNTIME_DEFAULT.labelVisible, labelTips = X_RUNTIME_DEFAULT.labelTips, labelWidth: _labelWidth = X_RUNTIME_DEFAULT.labelWidth, labelWrap = X_RUNTIME_DEFAULT.labelWrap, extra = X_RUNTIME_DEFAULT.extra, required = X_RUNTIME_DEFAULT.required, readOnly, children, testId, requiredFlag = X_RUNTIME_DEFAULT.requiredFlag, validateState, validateErrorMsg, readValue, borderedH5 = X_RUNTIME_DEFAULT.borderedH5, borderedPc = X_RUNTIME_DEFAULT.borderedPc, classRoot, controlAlign, inputId, isWdFormDetail, before, after, readBeforeAfter = true, visible = true,
|
|
43
|
+
export const WdFormItem = React.memo(function WdFormItem(props) {
|
|
44
|
+
const { id, className, style, label, labelVisible = X_RUNTIME_DEFAULT.labelVisible, labelTips = X_RUNTIME_DEFAULT.labelTips, labelWidth: _labelWidth = X_RUNTIME_DEFAULT.labelWidth, labelWrap = X_RUNTIME_DEFAULT.labelWrap, extra = X_RUNTIME_DEFAULT.extra, required = X_RUNTIME_DEFAULT.required, readOnly, children, testId, requiredFlag = X_RUNTIME_DEFAULT.requiredFlag, validateState, validateErrorMsg, readValue, borderedH5 = X_RUNTIME_DEFAULT.borderedH5, borderedPc = X_RUNTIME_DEFAULT.borderedPc, classRoot, controlAlign, inputId, isWdFormDetail, before, after, readBeforeAfter = true, visible = true, hasLabelContainer = null, isRoot = true, LabelAdornment, format, value, } = props;
|
|
16
45
|
const { classPrefix } = useConfig();
|
|
17
46
|
const platform = usePlatform();
|
|
18
47
|
const isH5 = platform === 'h5';
|
|
@@ -27,9 +56,7 @@ export function WdFormItem(props) {
|
|
|
27
56
|
// 样式前缀定义
|
|
28
57
|
const root = `${classPrefix}-${classRoot}`;
|
|
29
58
|
const item = `${classPrefix}-form-item`;
|
|
30
|
-
const itemLayout = isWdFormDetail
|
|
31
|
-
? `${classPrefix}-form-item--detail`
|
|
32
|
-
: `${item}-`;
|
|
59
|
+
const itemLayout = isWdFormDetail ? `${classPrefix}-form-item--detail` : `${item}-`;
|
|
33
60
|
const itemWrap = `${classPrefix}-form-item-wrap`;
|
|
34
61
|
const labelRoot = `${root}__label`;
|
|
35
62
|
// 表单项样式
|
|
@@ -53,9 +80,45 @@ export function WdFormItem(props) {
|
|
|
53
80
|
[`${itemWrap}__control-wrap--right`]: controlAlign === 'right',
|
|
54
81
|
});
|
|
55
82
|
// 输入部分
|
|
56
|
-
const Item = (
|
|
83
|
+
// const Item = (
|
|
84
|
+
// <div className={`${itemWrap}__control`} data-testid={testId}>
|
|
85
|
+
// <div className={controlWrapCls}>
|
|
86
|
+
// <WdFormItemReadOnly
|
|
87
|
+
// readOnly={readOnly}
|
|
88
|
+
// readValue={readValue}
|
|
89
|
+
// version="wd"
|
|
90
|
+
// before={before}
|
|
91
|
+
// after={after}
|
|
92
|
+
// readBeforeAfter={readBeforeAfter}
|
|
93
|
+
// format={format}
|
|
94
|
+
// value={value}
|
|
95
|
+
// >
|
|
96
|
+
// {children}
|
|
97
|
+
// </WdFormItemReadOnly>
|
|
98
|
+
// </div>
|
|
99
|
+
// </div>
|
|
100
|
+
// );
|
|
57
101
|
// 标题部分,含必填、提示
|
|
58
|
-
const Label = labelVisible && (
|
|
102
|
+
// const Label = labelVisible && (
|
|
103
|
+
// <div className={labelCls} style={labelStyle}>
|
|
104
|
+
// <label className={`${itemWrap}__label-content`} htmlFor={inputId}>
|
|
105
|
+
// <span className={`${itemWrap}__label-text ${labelRoot}-text`} title={label}>
|
|
106
|
+
// {textToString(label)}
|
|
107
|
+
// </span>
|
|
108
|
+
// {labelTips && (
|
|
109
|
+
// <span className={`${itemWrap}__label-explain`}>
|
|
110
|
+
// <WdBubble
|
|
111
|
+
// style={{ display: 'inline' }}
|
|
112
|
+
// bubbleChildren={<WdIcon name="td:help-circle" size={iconSize} />}
|
|
113
|
+
// bubbleContent={textToString(labelTips)}
|
|
114
|
+
// promptTheme="dark"
|
|
115
|
+
// />
|
|
116
|
+
// </span>
|
|
117
|
+
// )}
|
|
118
|
+
// </label>
|
|
119
|
+
// {LabelAdornment && <div className={`${itemWrap}__label-adornment`}>{LabelAdornment}</div>}
|
|
120
|
+
// </div>
|
|
121
|
+
// );
|
|
59
122
|
// 下方空白替代(改为距左对齐)
|
|
60
123
|
// const LabelSpace = labelVisible && layout === 'horizontal' && (
|
|
61
124
|
// <div className={labelCls} style={labelStyle}></div>
|
|
@@ -64,11 +127,30 @@ export function WdFormItem(props) {
|
|
|
64
127
|
const Help = extra && (_jsx("p", { className: `${item}__help`, children: _jsx("span", { className: `${item}__help-text ${root}__help`, children: textToString(extra) }) }));
|
|
65
128
|
// 校验提示文字部分
|
|
66
129
|
const Message = validateErrorMsg && (_jsx("p", { className: `${item}__help`, children: _jsx("span", { className: `${classPrefix}-g-text-${validateState} ${root}__error`, children: textToString(validateErrorMsg) }) }));
|
|
130
|
+
const labelProps = {
|
|
131
|
+
labelCls,
|
|
132
|
+
labelStyle,
|
|
133
|
+
itemWrap,
|
|
134
|
+
inputId,
|
|
135
|
+
labelRoot,
|
|
136
|
+
label,
|
|
137
|
+
labelTips,
|
|
138
|
+
iconSize,
|
|
139
|
+
LabelAdornment,
|
|
140
|
+
};
|
|
141
|
+
const itemProps = {
|
|
142
|
+
itemWrap,
|
|
143
|
+
testId,
|
|
144
|
+
controlWrapCls,
|
|
145
|
+
readOnly,
|
|
146
|
+
readValue,
|
|
147
|
+
readBeforeAfter,
|
|
148
|
+
format,
|
|
149
|
+
value,
|
|
150
|
+
before,
|
|
151
|
+
after,
|
|
152
|
+
};
|
|
67
153
|
if (!visible)
|
|
68
154
|
return null;
|
|
69
|
-
return (_jsxs("div", { className: cls, id: isRoot ? id : null, style: style, children: [_jsx("div", { className: itemWrap, children:
|
|
70
|
-
}
|
|
71
|
-
const LabelContainerComp = ({ isRoot, isH5, Label, Item, LabelContainer, mode, }) => {
|
|
72
|
-
const showLabel = isRoot && !isH5;
|
|
73
|
-
return (_jsxs(_Fragment, { children: [showLabel && Label, _jsx(LabelContainer, { isRoot: isRoot, Label: Label, Item: Item, mode: mode })] }));
|
|
74
|
-
};
|
|
155
|
+
return (_jsxs("div", { className: cls, id: isRoot ? id : null, style: style, children: [_jsx("div", { className: itemWrap, children: hasLabelContainer ? (_jsx(LabelContainerComp, { isRoot: isRoot, isH5: isH5, mode: props === null || props === void 0 ? void 0 : props.mode, labelProps: labelProps, itemProps: itemProps, children: children })) : (_jsxs(_Fragment, { children: [labelVisible && _jsx(Label, { ...labelProps }), _jsx(Item, { ...itemProps, children: children })] })) }), Message, Help] }));
|
|
156
|
+
});
|
|
@@ -1,45 +1,22 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-magic-numbers */
|
|
3
|
-
import
|
|
3
|
+
import { forwardRef, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
4
|
+
import { useDeepCompareEffect } from '@react-hookz/web';
|
|
4
5
|
import { useConfig } from '../../utils/config-context';
|
|
5
6
|
import { WdFormItem } from '../wd-form-item';
|
|
6
7
|
import { usePlatform } from '../../utils/platform';
|
|
7
8
|
import classNames from '../../utils/classnames';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
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
12
|
import lodashSet from 'lodash.set';
|
|
11
13
|
import lodashGet from 'lodash.get';
|
|
12
|
-
import { useFormInputTrait
|
|
14
|
+
import { useFormInputTrait } from '../form-input-hooks';
|
|
13
15
|
import { deepClone } from '../../utils/tool';
|
|
14
16
|
import isObjectEqual from '../../utils/isObjectEqual';
|
|
15
|
-
import { WdIcon } from '../wd-icon';
|
|
16
|
-
import { WdCard } from '../wd-card';
|
|
17
17
|
import '../style';
|
|
18
18
|
import useDebouncedCallback from '../../utils/hooks/use-debounced-callback';
|
|
19
|
-
import { useMap } from '@react-hookz/web';
|
|
20
|
-
import { isNil } from '../../utils/lodash';
|
|
21
19
|
const classRoot = 'form-obj';
|
|
22
|
-
/**
|
|
23
|
-
* 获取待操作的数据路径,嵌套表单中子组件的名称是按lodashSet形式拼接的,在更新嵌套表单值时,要去除掉当前嵌套表单的路径名称
|
|
24
|
-
* @param operateName 待操作的表单项名称
|
|
25
|
-
* @param currentName 当前表单项名称
|
|
26
|
-
* @returns
|
|
27
|
-
*/
|
|
28
|
-
const getValueName = (operateName, currentName) => operateName.replace(new RegExp(`^${currentName}(\\.)?`), '');
|
|
29
|
-
const LabelContainer = (props) => {
|
|
30
|
-
const { Label, Item, mode } = props || {};
|
|
31
|
-
const cardRef = React.createRef();
|
|
32
|
-
const [iconName, setIconName] = useState('chevronup');
|
|
33
|
-
const headerSlot = (_jsxs(_Fragment, { children: [_jsx(WdIcon, { name: iconName, events: {
|
|
34
|
-
tap: () => {
|
|
35
|
-
setIconName(iconName === 'chevrondown' ? 'chevronup' : 'chevrondown');
|
|
36
|
-
},
|
|
37
|
-
} }), Label] }));
|
|
38
|
-
if (mode === 'custom' || mode === 'table') {
|
|
39
|
-
return _jsx(_Fragment, { children: Item });
|
|
40
|
-
}
|
|
41
|
-
return (_jsx(WdCard, { ref: cardRef, className: iconName === 'chevrondown' ? 'wd-card-content__hidden' : '', showContent: true, headerSlot: headerSlot, contentSlot: Item, events: { tap: () => { } } }));
|
|
42
|
-
};
|
|
43
20
|
export const BaseFormObj = forwardRef(function BaseFormObj(props, ref) {
|
|
44
21
|
const { classPrefix } = useConfig();
|
|
45
22
|
const platform = usePlatform();
|
|
@@ -51,24 +28,14 @@ export const BaseFormObj = forwardRef(function BaseFormObj(props, ref) {
|
|
|
51
28
|
...props,
|
|
52
29
|
classRoot,
|
|
53
30
|
className: classNames(props.className, `${classPrefix}-form-obj-item`),
|
|
54
|
-
|
|
31
|
+
hasLabelContainer: true,
|
|
55
32
|
};
|
|
56
|
-
const initValue = { arr: [], obj: {} }[props.objType];
|
|
57
33
|
// 嵌套表单状态
|
|
58
34
|
const [status, updateStatus] = useState('edit');
|
|
59
35
|
const [innerHandle, setInnerHandle] = useState({});
|
|
60
36
|
const inputRef = useRef({});
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
// 父级普通表单对象
|
|
64
|
-
const parentForm = useParentForm(props.$widget);
|
|
65
|
-
// 父级嵌套表单对象
|
|
66
|
-
const parentFormObj = useFormObjWidget();
|
|
67
|
-
// 嵌套表单内的子组件实例对象集合,在form-input-hooks中会调用addFormItem添加关联上
|
|
68
|
-
const formsItemMap = useMap([]);
|
|
69
|
-
const { name, value, readOnly, disabled, visible,
|
|
70
|
-
// onChange: _onChange,
|
|
71
|
-
} = useFormInputTrait({
|
|
37
|
+
const [isInformObjContainer, setIsInformObjContainer] = useState(false);
|
|
38
|
+
const { name, value: objValue, readOnly, disabled, visible, onChange: _onChange, namePath, isInformContainer: _isInformContainer, } = useFormInputTrait({
|
|
72
39
|
label: props.label,
|
|
73
40
|
value: props.value,
|
|
74
41
|
name: props.name,
|
|
@@ -83,9 +50,16 @@ export const BaseFormObj = forwardRef(function BaseFormObj(props, ref) {
|
|
|
83
50
|
onChange: noop,
|
|
84
51
|
$node: props.$node,
|
|
85
52
|
});
|
|
53
|
+
const valueRef = useRef(props.value);
|
|
54
|
+
useDeepCompareEffect(() => {
|
|
55
|
+
if (isObjectEqual(valueRef.current, objValue)) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
triggerOnDataChange(objValue);
|
|
59
|
+
}, [objValue]);
|
|
86
60
|
useEffect(() => {
|
|
87
|
-
|
|
88
|
-
}, [
|
|
61
|
+
setIsInformObjContainer(true);
|
|
62
|
+
}, []);
|
|
89
63
|
useEffect(() => {
|
|
90
64
|
if (readOnly) {
|
|
91
65
|
updateStatus('readOnly');
|
|
@@ -102,41 +76,31 @@ export const BaseFormObj = forwardRef(function BaseFormObj(props, ref) {
|
|
|
102
76
|
*/
|
|
103
77
|
const triggerOnDataChange = useDebouncedCallback(useCallback((value) => {
|
|
104
78
|
var _a, _b;
|
|
79
|
+
valueRef.current = value;
|
|
105
80
|
(_b = (_a = props.events) === null || _a === void 0 ? void 0 : _a.onDataChange) === null || _b === void 0 ? void 0 : _b.call(_a, { data: value });
|
|
106
81
|
}, [props.events]), 500);
|
|
107
|
-
|
|
108
|
-
* 不在表单容器中使用时,更新子组件值
|
|
109
|
-
*/
|
|
110
|
-
const updateChildValue = useDebouncedCallback(useCallback((value) => {
|
|
111
|
-
formsItemMap.forEach((items, childName) => {
|
|
112
|
-
var _a;
|
|
113
|
-
const newValue = lodashGet(value, getValueName(childName, name));
|
|
114
|
-
if (!Array.isArray(items)) {
|
|
115
|
-
items = [items];
|
|
116
|
-
}
|
|
117
|
-
(_a = items === null || items === void 0 ? void 0 : items.forEach) === null || _a === void 0 ? void 0 : _a.call(items, (item) => {
|
|
118
|
-
if (item.setValue && !isObjectEqual(item.value, newValue)) {
|
|
119
|
-
item.setValue(newValue);
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
}, [formsItemMap, name]), 0);
|
|
124
|
-
const dealArrChange = (params, objValue) => {
|
|
82
|
+
const dealArrChange = useCallback((params, objValue) => {
|
|
125
83
|
let value;
|
|
126
84
|
// 顶层为数组类型
|
|
127
|
-
if (
|
|
85
|
+
if (['add', 'remove'].includes(params.type)) {
|
|
128
86
|
value = deepClone(objValue);
|
|
87
|
+
const _addDefaultValue = deepClone(props.addDefaultValue);
|
|
129
88
|
// 触发添加操作,则增加一个undefined值
|
|
130
89
|
if (params.type === 'add') {
|
|
131
|
-
|
|
90
|
+
if (Array.isArray(objValue)) {
|
|
91
|
+
value.push(_addDefaultValue);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
value = [].concat(_addDefaultValue);
|
|
95
|
+
}
|
|
132
96
|
}
|
|
133
97
|
// 触发删除操作,则删除对应索引的值
|
|
134
|
-
if (params.type === 'remove') {
|
|
98
|
+
if (Array.isArray(objValue) && params.type === 'remove') {
|
|
135
99
|
value = [...value.slice(0, params.value), ...value.slice(params.value + 1)];
|
|
136
100
|
}
|
|
137
101
|
}
|
|
138
102
|
return value;
|
|
139
|
-
};
|
|
103
|
+
}, [props.addDefaultValue]);
|
|
140
104
|
const dealObjChange = (params, objValue) => {
|
|
141
105
|
var _a, _b;
|
|
142
106
|
// 如果设置的是空对象,则认为是覆盖更新
|
|
@@ -152,23 +116,21 @@ export const BaseFormObj = forwardRef(function BaseFormObj(props, ref) {
|
|
|
152
116
|
/**
|
|
153
117
|
* 更新值
|
|
154
118
|
* @param params
|
|
155
|
-
* @param param1.isUpdateParentForm 是否更新父级表单,因子组件值变化调用change时不去触发父表单的更新,因为子组件自己会触发;因为外部设置了值,则触发父表单更新
|
|
156
|
-
* @param param1.isUpdateChildValue 是否更新子组件值, 因子组件值变化调用change时不去触发updateChildValueWithoutForm;因为外部设置了值,则触发updateChildValueWithoutForm去更新子组件值
|
|
157
119
|
* @returns
|
|
158
120
|
*/
|
|
159
|
-
const change = useCallback((params
|
|
160
|
-
var _a, _b, _c;
|
|
121
|
+
const change = useCallback((params) => {
|
|
161
122
|
if (disabled || readOnly) {
|
|
162
123
|
return;
|
|
163
124
|
}
|
|
125
|
+
const initValue = { arr: [], obj: {} }[props.objType];
|
|
164
126
|
let value = deepClone(params.value);
|
|
165
|
-
if (props.objType === 'arr') {
|
|
166
|
-
value = dealArrChange(params, objValue) || value;
|
|
167
|
-
}
|
|
168
127
|
// 如果有更新标识,则按标识路径更新值
|
|
169
128
|
if (params.name) {
|
|
170
129
|
value = deepClone(objValue);
|
|
171
|
-
lodashSet(value,
|
|
130
|
+
lodashSet(value, params.name, params.value);
|
|
131
|
+
}
|
|
132
|
+
else if (props.objType === 'arr') {
|
|
133
|
+
value = dealArrChange(params, objValue) || value;
|
|
172
134
|
}
|
|
173
135
|
else if (props.objType === 'obj') {
|
|
174
136
|
value = dealObjChange(params, objValue) || value;
|
|
@@ -176,59 +138,12 @@ export const BaseFormObj = forwardRef(function BaseFormObj(props, ref) {
|
|
|
176
138
|
if (isObjectEqual(value, objValue) || (value === null && isObjectEqual(initValue, objValue))) {
|
|
177
139
|
return;
|
|
178
140
|
}
|
|
179
|
-
|
|
180
|
-
if (isUpdateChildValue) {
|
|
181
|
-
// 外部设置数据,同时去更新子组件的值
|
|
182
|
-
updateChildValue(value);
|
|
183
|
-
}
|
|
184
|
-
if (isUpdateParentForm) {
|
|
185
|
-
// 触发父级普通表单值更新
|
|
186
|
-
(_a = parentForm === null || parentForm === void 0 ? void 0 : parentForm.__setValueImmediate__) === null || _a === void 0 ? void 0 : _a.call(parentForm, { [name]: value }, false, true);
|
|
187
|
-
}
|
|
188
|
-
if (params.name) {
|
|
189
|
-
// 触发父级嵌套表单值更新
|
|
190
|
-
(_b = parentFormObj === null || parentFormObj === void 0 ? void 0 : parentFormObj.__setValueImmediate__) === null || _b === void 0 ? void 0 : _b.call(parentFormObj, {
|
|
191
|
-
name: params.name,
|
|
192
|
-
value: params.value,
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
else if (parentFormObj === null || parentFormObj === void 0 ? void 0 : parentFormObj.formObjName) {
|
|
196
|
-
// 外部直接调用formObj.setValue的情况下,触发父级嵌套表单值更新
|
|
197
|
-
(_c = parentFormObj === null || parentFormObj === void 0 ? void 0 : parentFormObj.__setValueImmediate__) === null || _c === void 0 ? void 0 : _c.call(parentFormObj, { name, value });
|
|
198
|
-
}
|
|
141
|
+
_onChange(value || initValue);
|
|
199
142
|
triggerOnDataChange(value);
|
|
200
|
-
},
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
const changeDebounce = useDebouncedCallback(useCallback((value, option) => {
|
|
204
|
-
change(value, option);
|
|
143
|
+
}, [disabled, readOnly, props.objType, objValue, _onChange, triggerOnDataChange, dealArrChange]);
|
|
144
|
+
const changeDebounce = useDebouncedCallback(useCallback((value) => {
|
|
145
|
+
change(value);
|
|
205
146
|
}, [change]), 300);
|
|
206
|
-
/**
|
|
207
|
-
* 子组件默认值变更,触发嵌套表单值更新
|
|
208
|
-
*/
|
|
209
|
-
const changeByChildFormObj = useCallback((params) => {
|
|
210
|
-
var _a, _b;
|
|
211
|
-
const value = deepClone(objValue);
|
|
212
|
-
lodashSet(value, getValueName(params.name, name), params.value);
|
|
213
|
-
if (isObjectEqual(value, objValue)) {
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
if (params.name) {
|
|
217
|
-
// 将值同步给父级嵌套表单
|
|
218
|
-
(_a = parentFormObj === null || parentFormObj === void 0 ? void 0 : parentFormObj.__setValueImmediate__) === null || _a === void 0 ? void 0 : _a.call(parentFormObj, {
|
|
219
|
-
name: params.name,
|
|
220
|
-
value: params.value,
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
else if (parentFormObj === null || parentFormObj === void 0 ? void 0 : parentFormObj.formObjName) {
|
|
224
|
-
// 外部直接调用formObj.setValue的情况下,触发父级嵌套表单值更新
|
|
225
|
-
(_b = parentFormObj === null || parentFormObj === void 0 ? void 0 : parentFormObj.__setValueImmediate__) === null || _b === void 0 ? void 0 : _b.call(parentFormObj, { name, value });
|
|
226
|
-
}
|
|
227
|
-
setObjValue(value || initValue);
|
|
228
|
-
triggerOnDataChange(value || initValue);
|
|
229
|
-
},
|
|
230
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
231
|
-
[objValue, name, parentFormObj]);
|
|
232
147
|
useLayoutEffect(() => {
|
|
233
148
|
if (!ref)
|
|
234
149
|
return;
|
|
@@ -239,7 +154,7 @@ export const BaseFormObj = forwardRef(function BaseFormObj(props, ref) {
|
|
|
239
154
|
* @param value
|
|
240
155
|
*/
|
|
241
156
|
setValue: (value) => {
|
|
242
|
-
changeDebounce({ name: '', value }
|
|
157
|
+
changeDebounce({ name: '', value });
|
|
243
158
|
},
|
|
244
159
|
getValue() {
|
|
245
160
|
return objValue;
|
|
@@ -253,15 +168,15 @@ export const BaseFormObj = forwardRef(function BaseFormObj(props, ref) {
|
|
|
253
168
|
...(props.objType === 'arr'
|
|
254
169
|
? {
|
|
255
170
|
add: () => {
|
|
256
|
-
change({ type: 'add' }
|
|
171
|
+
change({ type: 'add' });
|
|
257
172
|
},
|
|
258
173
|
remove: ({ index = -1 } = {}) => {
|
|
259
|
-
change({ type: 'remove', value: index }
|
|
174
|
+
change({ type: 'remove', value: index });
|
|
260
175
|
},
|
|
261
176
|
}
|
|
262
177
|
: {}),
|
|
263
178
|
change: (params) => {
|
|
264
|
-
change(params
|
|
179
|
+
change(params);
|
|
265
180
|
},
|
|
266
181
|
},
|
|
267
182
|
label: props.label,
|
|
@@ -271,72 +186,26 @@ export const BaseFormObj = forwardRef(function BaseFormObj(props, ref) {
|
|
|
271
186
|
disabled,
|
|
272
187
|
readOnly,
|
|
273
188
|
};
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
formObjName: name,
|
|
291
|
-
status,
|
|
292
|
-
/**
|
|
293
|
-
* 嵌套表单内部子组件值改变时,触发嵌套表单组件的值更新
|
|
294
|
-
* @param params.name 子组件名称
|
|
295
|
-
* @param params.value 子组件值
|
|
296
|
-
*/
|
|
297
|
-
valueChangeFromChild: (params = {}) => {
|
|
298
|
-
if (!params.name)
|
|
299
|
-
return;
|
|
300
|
-
// 由于是子组件值变更触发,所以嵌套表单值更新后不再次触发子组件值变更
|
|
301
|
-
change(params, { isUpdateChildValue: false });
|
|
302
|
-
},
|
|
303
|
-
/**
|
|
304
|
-
* 收集嵌套表单内的子组件实例,以便嵌套表单值变化时,主动触发子组件值更新
|
|
305
|
-
* @param childName 子组件名称
|
|
306
|
-
* @param formItem 子组件$widget
|
|
307
|
-
* @returns
|
|
308
|
-
*/
|
|
309
|
-
addFormItem(childName, formItem) {
|
|
310
|
-
if (isNil(childName) || !formItem || (typeof childName === 'string' && childName.length === 0)) {
|
|
311
|
-
// childName 没设置或为空串的时候不受表单容器控制
|
|
312
|
-
console.warn(`组件 #${formItem === null || formItem === void 0 ? void 0 : formItem.id} 表单key(表单输入类组件 childName 属性)没设置或为空串的时候不受表单容器控制`);
|
|
313
|
-
return noop;
|
|
314
|
-
}
|
|
315
|
-
if (formsItemMap.has(childName)) {
|
|
316
|
-
formsItemMap.get(childName).push(formItem);
|
|
317
|
-
}
|
|
318
|
-
else {
|
|
319
|
-
formsItemMap.set(childName, [formItem]);
|
|
320
|
-
}
|
|
321
|
-
return () => {
|
|
322
|
-
const items = formsItemMap.get(childName);
|
|
323
|
-
const removedArr = items.filter((item) => item !== formItem);
|
|
324
|
-
if (removedArr.length <= 0) {
|
|
325
|
-
formsItemMap.delete(childName);
|
|
326
|
-
}
|
|
327
|
-
else {
|
|
328
|
-
formsItemMap.set(childName, removedArr);
|
|
329
|
-
}
|
|
330
|
-
};
|
|
331
|
-
},
|
|
332
|
-
};
|
|
333
|
-
}, [change, formsItemMap, name, status]);
|
|
334
|
-
useEffect(() => {
|
|
335
|
-
// 如果是最顶层的嵌套表单,则去更新子组件的值,否则自己的值更新不去触发子组件值更新,因为父级普通表单会去更新
|
|
336
|
-
if (!parentFormObj) {
|
|
337
|
-
updateChildValue(objValue);
|
|
189
|
+
}, [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;
|
|
338
205
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
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 }) }) }) }));
|
|
342
211
|
});
|
|
@@ -35,7 +35,7 @@ export const WdInput = forwardRef(function WdInput(props, ref) {
|
|
|
35
35
|
const { value, // 代表组件值,含前后缀
|
|
36
36
|
onChange: _onChange, disabled, readOnly, validateErrorMsg, validateState, visible, } = useFormInputTrait(traitProps);
|
|
37
37
|
const wrapRef = useRef(null);
|
|
38
|
-
const valueRef = useRef(
|
|
38
|
+
const valueRef = useRef(null);
|
|
39
39
|
const size = useSize(props);
|
|
40
40
|
const iconSize = convertIconSize(size);
|
|
41
41
|
const { classPrefix } = useConfig();
|
|
@@ -38,10 +38,44 @@ const getRuleMessage = ({ value = undefined, max = undefined, min = undefined, v
|
|
|
38
38
|
});
|
|
39
39
|
return !maxFit ? validMsgObj.max : !minFit ? validMsgObj.min : '';
|
|
40
40
|
};
|
|
41
|
+
const coverValueFix = (value, props) => {
|
|
42
|
+
const type = (props === null || props === void 0 ? void 0 : props.format) || 'number';
|
|
43
|
+
if (value === '' && !['plus', 'minus'].includes(type))
|
|
44
|
+
return '';
|
|
45
|
+
if (value === 'null' || value === 'undefined')
|
|
46
|
+
return '';
|
|
47
|
+
let res = `${value}`;
|
|
48
|
+
if (isNumber(value) && res.includes('e')) {
|
|
49
|
+
res = `${res.startsWith('-') ? '-' : ''}${res.replace(/^-/, '').toLocaleString()}`;
|
|
50
|
+
}
|
|
51
|
+
res = res.replace(/,/g, '') || null;
|
|
52
|
+
if (res !== 'Infinity' && res !== '-Infinity') {
|
|
53
|
+
if (type === 'plus') {
|
|
54
|
+
res = strNumAddCalc(res, `${props.step}`);
|
|
55
|
+
}
|
|
56
|
+
else if (type === 'minus') {
|
|
57
|
+
res = strNumAddCalc(res, `${-props.step}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
res = dealDecimals(res, props === null || props === void 0 ? void 0 : props.decimals, type);
|
|
61
|
+
// 千分符转换
|
|
62
|
+
if ((props === null || props === void 0 ? void 0 : props.thousandShow) && res !== 'Infinity' && res !== '-Infinity') {
|
|
63
|
+
const temp = res.split('.');
|
|
64
|
+
res = `${temp[0].replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')}${temp[1] ? `.${temp[1]}` : ''}`;
|
|
65
|
+
}
|
|
66
|
+
return res;
|
|
67
|
+
};
|
|
41
68
|
export const WdInputNumber = forwardRef(function WdInputNumber(props, ref) {
|
|
42
69
|
const { clearable = X_RUNTIME_DEFAULT.clearable } = props;
|
|
43
|
-
const
|
|
44
|
-
const [showValue, setShowValue] = useState(
|
|
70
|
+
const inputValueRef = useRef(props.inputValue);
|
|
71
|
+
const [showValue, setShowValue] = useState(() => {
|
|
72
|
+
return coverValueFix(`${props.inputValue}`, props);
|
|
73
|
+
}); // 显示值
|
|
74
|
+
const [realValue, setRealValue] = useState(() => {
|
|
75
|
+
const _value = coverValueFix(`${props.inputValue}`, props);
|
|
76
|
+
const v = dealPercent(_value, props.format === 'percent' ? 'del' : '');
|
|
77
|
+
return Number(v.replace(/,/g, '')) || null;
|
|
78
|
+
}); // 真实值
|
|
45
79
|
// 最大值,用于输入值比较
|
|
46
80
|
const max = useMemo(() => {
|
|
47
81
|
return Number(props.format === 'percent' ? dealPercent(`${props.max}`, 'add') : props.max);
|
|
@@ -187,7 +221,11 @@ export const WdInputNumber = forwardRef(function WdInputNumber(props, ref) {
|
|
|
187
221
|
}, [props.decimals, props.format, props.thousandShow]);
|
|
188
222
|
// inputValue变化时,单独处理值更新
|
|
189
223
|
useEffect(() => {
|
|
224
|
+
if (inputValueRef.current === props.inputValue) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
190
227
|
dealValueChange(props.inputValue);
|
|
228
|
+
inputValueRef.current = props.inputValue;
|
|
191
229
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
192
230
|
}, [props.inputValue]);
|
|
193
231
|
// max、min变化时,去判断当前值是否超出范围
|
|
@@ -206,7 +244,7 @@ export const WdInputNumber = forwardRef(function WdInputNumber(props, ref) {
|
|
|
206
244
|
}
|
|
207
245
|
initValidate(validState, validMsg);
|
|
208
246
|
}, [showValue, props.min, props.max, max, min, initValidate, validMsgObj.max, validMsgObj.min]);
|
|
209
|
-
const valueRef = useRef(
|
|
247
|
+
const valueRef = useRef(null);
|
|
210
248
|
const [focus, setFocus] = useSyncValue(props.focus);
|
|
211
249
|
const hasClearIcon = getHasClearIcon(clearable, focus, disabled, readOnly, realValue);
|
|
212
250
|
const isRow = props.stepOption === 'both'; // 右侧调整只在pc端生效
|
|
@@ -282,24 +320,12 @@ export const WdInputNumber = forwardRef(function WdInputNumber(props, ref) {
|
|
|
282
320
|
/**
|
|
283
321
|
* 监听非输入引起的value变化,比如调用 setValue, clearValue
|
|
284
322
|
*/
|
|
285
|
-
|
|
286
|
-
if (valueRef.current
|
|
287
|
-
setIsInit(false);
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
if (!isInit) {
|
|
323
|
+
useEffect(() => {
|
|
324
|
+
if (valueRef.current !== value) {
|
|
291
325
|
setRealValue(value);
|
|
292
326
|
setShowValue(getShowValue(`${value}`, props.format));
|
|
293
327
|
valueRef.current = value;
|
|
294
328
|
}
|
|
295
|
-
// 初始化时同步真实值到表单
|
|
296
|
-
if (isNumber(realValue) && isInit) {
|
|
297
|
-
changeForm(realValue);
|
|
298
|
-
}
|
|
299
|
-
setIsInit(false);
|
|
300
|
-
};
|
|
301
|
-
useEffect(() => {
|
|
302
|
-
updateValueByListen();
|
|
303
329
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
304
330
|
}, [value]);
|
|
305
331
|
/**
|
|
@@ -5,7 +5,7 @@ import './style';
|
|
|
5
5
|
/**
|
|
6
6
|
* 富文本-标准化
|
|
7
7
|
*/
|
|
8
|
-
export declare const WdRichText: React.ForwardRefExoticComponent<WdRichTextProps & React.RefAttributes<
|
|
8
|
+
export declare const WdRichText: React.ForwardRefExoticComponent<WdRichTextProps & React.RefAttributes<unknown>>;
|
|
9
9
|
export interface WdRichTextProps extends CommonPropsType, DataType {
|
|
10
10
|
classRoot?: string;
|
|
11
11
|
acceptTypes?: any;
|