@flowgram.ai/form-materials 0.2.5 → 0.2.7
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/esm/index.js +413 -190
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +425 -202
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/components/json-schema-editor/default-value.tsx +130 -0
- package/src/components/json-schema-editor/index.tsx +64 -7
- package/src/components/json-schema-editor/styles.tsx +127 -37
- package/src/components/json-schema-editor/types.ts +3 -0
- package/src/components/json-schema-editor/utils.ts +24 -0
- package/src/components/variable-selector/index.tsx +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowgram.ai/form-materials",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"homepage": "https://flowgram.ai/",
|
|
5
5
|
"repository": "https://github.com/bytedance/flowgram.ai",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,16 +21,16 @@
|
|
|
21
21
|
"src"
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@douyinfe/semi-icons": "^2.
|
|
25
|
-
"@douyinfe/semi-illustrations": "^2.
|
|
26
|
-
"@douyinfe/semi-ui": "^2.
|
|
24
|
+
"@douyinfe/semi-icons": "^2.80.0",
|
|
25
|
+
"@douyinfe/semi-illustrations": "^2.80.0",
|
|
26
|
+
"@douyinfe/semi-ui": "^2.80.0",
|
|
27
27
|
"lodash": "^4.17.21",
|
|
28
28
|
"nanoid": "^4.0.2",
|
|
29
29
|
"commander": "^11.0.0",
|
|
30
30
|
"chalk": "^5.3.0",
|
|
31
31
|
"inquirer": "^9.2.7",
|
|
32
32
|
"immer": "~10.1.1",
|
|
33
|
-
"@flowgram.ai/editor": "0.2.
|
|
33
|
+
"@flowgram.ai/editor": "0.2.7"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/lodash": "^4.14.137",
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"tsup": "^8.0.1",
|
|
47
47
|
"typescript": "^5.0.4",
|
|
48
48
|
"vitest": "^0.34.6",
|
|
49
|
-
"@flowgram.ai/eslint-config": "0.2.
|
|
50
|
-
"@flowgram.ai/ts-config": "0.2.
|
|
49
|
+
"@flowgram.ai/eslint-config": "0.2.7",
|
|
50
|
+
"@flowgram.ai/ts-config": "0.2.7"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"react": ">=16.8",
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import React, { useRef, useState, useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
import { IconButton, JsonViewer, Tooltip } from '@douyinfe/semi-ui';
|
|
4
|
+
import { IconBrackets } from '@douyinfe/semi-icons';
|
|
5
|
+
|
|
6
|
+
import { getValueType } from './utils';
|
|
7
|
+
import {
|
|
8
|
+
ConstantInputWrapper,
|
|
9
|
+
JSONHeader,
|
|
10
|
+
JSONHeaderLeft,
|
|
11
|
+
JSONHeaderRight,
|
|
12
|
+
JSONViewerWrapper,
|
|
13
|
+
} from './styles';
|
|
14
|
+
import { ConstantInput } from '../constant-input';
|
|
15
|
+
import { IJsonSchema } from '../../typings';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* 根据不同的数据类型渲染对应的默认值输入组件。
|
|
19
|
+
* @param props - 组件属性,包括 value, type, placeholder, onChange。
|
|
20
|
+
* @returns 返回对应类型的输入组件或 null。
|
|
21
|
+
*/
|
|
22
|
+
export function DefaultValue(props: {
|
|
23
|
+
value: any;
|
|
24
|
+
schema?: IJsonSchema;
|
|
25
|
+
name?: string;
|
|
26
|
+
type?: string;
|
|
27
|
+
placeholder?: string;
|
|
28
|
+
jsonFormatText?: string;
|
|
29
|
+
onChange: (value: any) => void;
|
|
30
|
+
}) {
|
|
31
|
+
const { value, schema, type, onChange, placeholder, jsonFormatText } = props;
|
|
32
|
+
|
|
33
|
+
const wrapperRef = useRef<HTMLDivElement>(null);
|
|
34
|
+
const JsonViewerRef = useRef<JsonViewer>(null);
|
|
35
|
+
|
|
36
|
+
// 为 JsonViewer 添加状态管理
|
|
37
|
+
const [internalJsonValue, setInternalJsonValue] = useState<string>(
|
|
38
|
+
getValueType(value) === 'string' ? value : ''
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// 使用 useCallback 创建稳定的回调函数
|
|
42
|
+
const handleJsonChange = useCallback((val: string) => {
|
|
43
|
+
// 只在值真正改变时才更新状态
|
|
44
|
+
if (val !== internalJsonValue) {
|
|
45
|
+
setInternalJsonValue(val);
|
|
46
|
+
}
|
|
47
|
+
}, []);
|
|
48
|
+
|
|
49
|
+
// 处理编辑完成事件
|
|
50
|
+
const handleEditComplete = useCallback(() => {
|
|
51
|
+
// 只有当存在key,编辑完成时才触发父组件的 onChange
|
|
52
|
+
onChange(internalJsonValue);
|
|
53
|
+
// 确保在更新后移除焦点
|
|
54
|
+
requestAnimationFrame(() => {
|
|
55
|
+
// JsonViewerRef.current?.format();
|
|
56
|
+
wrapperRef.current?.blur();
|
|
57
|
+
});
|
|
58
|
+
setJsonReadOnly(true);
|
|
59
|
+
}, [internalJsonValue, onChange]);
|
|
60
|
+
|
|
61
|
+
const [jsonReadOnly, setJsonReadOnly] = useState<boolean>(true);
|
|
62
|
+
|
|
63
|
+
const handleFormatJson = useCallback(() => {
|
|
64
|
+
try {
|
|
65
|
+
const parsed = JSON.parse(internalJsonValue);
|
|
66
|
+
const formatted = JSON.stringify(parsed, null, 4);
|
|
67
|
+
setInternalJsonValue(formatted);
|
|
68
|
+
onChange(formatted);
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.error('Invalid JSON:', error);
|
|
71
|
+
}
|
|
72
|
+
}, [internalJsonValue, onChange]);
|
|
73
|
+
|
|
74
|
+
return type === 'object' ? (
|
|
75
|
+
<>
|
|
76
|
+
<JSONHeader>
|
|
77
|
+
<JSONHeaderLeft>json</JSONHeaderLeft>
|
|
78
|
+
<JSONHeaderRight>
|
|
79
|
+
<Tooltip content={jsonFormatText ?? 'Format'}>
|
|
80
|
+
<IconButton
|
|
81
|
+
icon={<IconBrackets style={{ color: 'var(--semi-color-primary)' }} />}
|
|
82
|
+
size="small"
|
|
83
|
+
type="tertiary"
|
|
84
|
+
theme="borderless"
|
|
85
|
+
onClick={handleFormatJson}
|
|
86
|
+
/>
|
|
87
|
+
</Tooltip>
|
|
88
|
+
</JSONHeaderRight>
|
|
89
|
+
</JSONHeader>
|
|
90
|
+
|
|
91
|
+
<JSONViewerWrapper
|
|
92
|
+
ref={wrapperRef}
|
|
93
|
+
tabIndex={-1}
|
|
94
|
+
onBlur={(e) => {
|
|
95
|
+
if (wrapperRef.current && !wrapperRef.current?.contains(e.relatedTarget as Node)) {
|
|
96
|
+
handleEditComplete();
|
|
97
|
+
}
|
|
98
|
+
}}
|
|
99
|
+
onClick={(e: React.MouseEvent) => {
|
|
100
|
+
setJsonReadOnly(false);
|
|
101
|
+
}}
|
|
102
|
+
>
|
|
103
|
+
<JsonViewer
|
|
104
|
+
ref={JsonViewerRef}
|
|
105
|
+
value={getValueType(value) === 'string' ? value : ''}
|
|
106
|
+
height={120}
|
|
107
|
+
width="100%"
|
|
108
|
+
showSearch={false}
|
|
109
|
+
options={{
|
|
110
|
+
readOnly: jsonReadOnly,
|
|
111
|
+
formatOptions: { tabSize: 4, insertSpaces: true, eol: '\n' },
|
|
112
|
+
}}
|
|
113
|
+
style={{
|
|
114
|
+
padding: 0,
|
|
115
|
+
}}
|
|
116
|
+
onChange={handleJsonChange}
|
|
117
|
+
/>
|
|
118
|
+
</JSONViewerWrapper>
|
|
119
|
+
</>
|
|
120
|
+
) : (
|
|
121
|
+
<ConstantInputWrapper>
|
|
122
|
+
<ConstantInput
|
|
123
|
+
value={value}
|
|
124
|
+
onChange={(_v) => onChange(_v)}
|
|
125
|
+
schema={schema || { type: 'string' }}
|
|
126
|
+
placeholder={placeholder ?? 'Default value if parameter is not provided'}
|
|
127
|
+
/>
|
|
128
|
+
</ConstantInputWrapper>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
@@ -29,8 +29,9 @@ import {
|
|
|
29
29
|
UIType,
|
|
30
30
|
} from './styles';
|
|
31
31
|
import { UIName } from './styles';
|
|
32
|
-
import { UIRow } from './styles';
|
|
32
|
+
import { DefaultValueWrapper, UIRow } from './styles';
|
|
33
33
|
import { usePropertiesEdit } from './hooks';
|
|
34
|
+
import { DefaultValue } from './default-value';
|
|
34
35
|
import { BlurInput } from './components/blur-input';
|
|
35
36
|
|
|
36
37
|
export function JsonSchemaEditor(props: {
|
|
@@ -47,11 +48,12 @@ export function JsonSchemaEditor(props: {
|
|
|
47
48
|
return (
|
|
48
49
|
<UIContainer>
|
|
49
50
|
<UIProperties>
|
|
50
|
-
{propertyList.map((_property) => (
|
|
51
|
+
{propertyList.map((_property, index) => (
|
|
51
52
|
<PropertyEdit
|
|
52
53
|
key={_property.key}
|
|
53
54
|
value={_property}
|
|
54
55
|
config={config}
|
|
56
|
+
$index={index}
|
|
55
57
|
onChange={(_v) => {
|
|
56
58
|
onEditProperty(_property.key!, _v);
|
|
57
59
|
}}
|
|
@@ -74,14 +76,31 @@ function PropertyEdit(props: {
|
|
|
74
76
|
onChange?: (value: PropertyValueType) => void;
|
|
75
77
|
onRemove?: () => void;
|
|
76
78
|
$isLast?: boolean;
|
|
79
|
+
$index?: number;
|
|
80
|
+
$isFirst?: boolean;
|
|
81
|
+
$parentExpand?: boolean;
|
|
82
|
+
$parentType?: string;
|
|
77
83
|
$showLine?: boolean;
|
|
84
|
+
$level?: number; // 添加层级属性
|
|
78
85
|
}) {
|
|
79
|
-
const {
|
|
86
|
+
const {
|
|
87
|
+
value,
|
|
88
|
+
config,
|
|
89
|
+
$level = 0,
|
|
90
|
+
onChange: onChangeProps,
|
|
91
|
+
onRemove,
|
|
92
|
+
$index,
|
|
93
|
+
$isFirst,
|
|
94
|
+
$isLast,
|
|
95
|
+
$parentExpand = false,
|
|
96
|
+
$parentType = '',
|
|
97
|
+
$showLine,
|
|
98
|
+
} = props;
|
|
80
99
|
|
|
81
100
|
const [expand, setExpand] = useState(false);
|
|
82
101
|
const [collapse, setCollapse] = useState(false);
|
|
83
102
|
|
|
84
|
-
const { name, type, items, description, isPropertyRequired } = value || {};
|
|
103
|
+
const { name, type, items, default: defaultValue, description, isPropertyRequired } = value || {};
|
|
85
104
|
|
|
86
105
|
const typeSelectorValue = useMemo(() => ({ type, items }), [type, items]);
|
|
87
106
|
|
|
@@ -99,7 +118,16 @@ function PropertyEdit(props: {
|
|
|
99
118
|
|
|
100
119
|
return (
|
|
101
120
|
<>
|
|
102
|
-
<UIPropertyLeft
|
|
121
|
+
<UIPropertyLeft
|
|
122
|
+
type={type}
|
|
123
|
+
$index={$index}
|
|
124
|
+
$isFirst={$isFirst}
|
|
125
|
+
$isLast={$isLast}
|
|
126
|
+
$showLine={$showLine}
|
|
127
|
+
$isExpand={expand}
|
|
128
|
+
$parentExpand={$parentExpand}
|
|
129
|
+
$parentType={$parentType}
|
|
130
|
+
>
|
|
103
131
|
{showCollapse && (
|
|
104
132
|
<UICollapseTrigger onClick={() => setCollapse((_collapse) => !_collapse)}>
|
|
105
133
|
{collapse ? <IconChevronDown size="small" /> : <IconChevronRight size="small" />}
|
|
@@ -107,7 +135,12 @@ function PropertyEdit(props: {
|
|
|
107
135
|
)}
|
|
108
136
|
</UIPropertyLeft>
|
|
109
137
|
<UIPropertyRight>
|
|
110
|
-
<UIPropertyMain
|
|
138
|
+
<UIPropertyMain
|
|
139
|
+
$showCollapse={showCollapse}
|
|
140
|
+
$collapse={collapse}
|
|
141
|
+
$expand={expand}
|
|
142
|
+
type={type}
|
|
143
|
+
>
|
|
111
144
|
<UIRow>
|
|
112
145
|
<UIName>
|
|
113
146
|
<BlurInput
|
|
@@ -139,7 +172,9 @@ function PropertyEdit(props: {
|
|
|
139
172
|
size="small"
|
|
140
173
|
theme="borderless"
|
|
141
174
|
icon={expand ? <IconShrink size="small" /> : <IconExpand size="small" />}
|
|
142
|
-
onClick={() =>
|
|
175
|
+
onClick={() => {
|
|
176
|
+
setExpand((_expand) => !_expand);
|
|
177
|
+
}}
|
|
143
178
|
/>
|
|
144
179
|
{isDrilldownObject && (
|
|
145
180
|
<IconButton
|
|
@@ -169,6 +204,23 @@ function PropertyEdit(props: {
|
|
|
169
204
|
onChange={(value) => onChange('description', value)}
|
|
170
205
|
placeholder={config?.descPlaceholder ?? 'Help LLM to understand the property'}
|
|
171
206
|
/>
|
|
207
|
+
{$level === 0 && type && type !== 'array' && (
|
|
208
|
+
<>
|
|
209
|
+
<UILabel style={{ marginTop: 10 }}>
|
|
210
|
+
{config?.defaultValueTitle ?? 'Default Value'}
|
|
211
|
+
</UILabel>
|
|
212
|
+
<DefaultValueWrapper>
|
|
213
|
+
<DefaultValue
|
|
214
|
+
value={defaultValue}
|
|
215
|
+
schema={value}
|
|
216
|
+
type={type}
|
|
217
|
+
placeholder={config?.defaultValuePlaceholder}
|
|
218
|
+
jsonFormatText={config?.jsonFormatText}
|
|
219
|
+
onChange={(value) => onChange('default', value)}
|
|
220
|
+
/>
|
|
221
|
+
</DefaultValueWrapper>
|
|
222
|
+
</>
|
|
223
|
+
)}
|
|
172
224
|
</UIExpandDetail>
|
|
173
225
|
)}
|
|
174
226
|
</UIPropertyMain>
|
|
@@ -180,6 +232,9 @@ function PropertyEdit(props: {
|
|
|
180
232
|
key={_property.key}
|
|
181
233
|
value={_property}
|
|
182
234
|
config={config}
|
|
235
|
+
$level={$level + 1} // 传递递增的层级
|
|
236
|
+
$parentExpand={expand}
|
|
237
|
+
$parentType={type}
|
|
183
238
|
onChange={(_v) => {
|
|
184
239
|
onEditProperty(_property.key!, _v);
|
|
185
240
|
}}
|
|
@@ -187,6 +242,8 @@ function PropertyEdit(props: {
|
|
|
187
242
|
onRemoveProperty(_property.key!);
|
|
188
243
|
}}
|
|
189
244
|
$isLast={index === propertyList.length - 1}
|
|
245
|
+
$isFirst={index === 0}
|
|
246
|
+
$index={index}
|
|
190
247
|
$showLine={true}
|
|
191
248
|
/>
|
|
192
249
|
))}
|
|
@@ -46,37 +46,55 @@ export const UIProperties = styled.div<{ $shrink?: boolean }>`
|
|
|
46
46
|
`}
|
|
47
47
|
`;
|
|
48
48
|
|
|
49
|
-
export const UIPropertyLeft = styled.div<{
|
|
49
|
+
export const UIPropertyLeft = styled.div<{
|
|
50
|
+
$isLast?: boolean;
|
|
51
|
+
$showLine?: boolean;
|
|
52
|
+
$isExpand?: boolean;
|
|
53
|
+
type?: string;
|
|
54
|
+
$isFirst?: boolean;
|
|
55
|
+
$index?: number;
|
|
56
|
+
$parentExpand?: boolean;
|
|
57
|
+
$parentType?: string;
|
|
58
|
+
}>`
|
|
50
59
|
grid-column: 1;
|
|
51
60
|
position: relative;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
61
|
+
width: 16px;
|
|
62
|
+
|
|
63
|
+
${({ $showLine, $isLast, $parentType }) => {
|
|
64
|
+
let height = '100%';
|
|
65
|
+
if ($parentType && $isLast) {
|
|
66
|
+
height = '24px';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
$showLine &&
|
|
71
|
+
css`
|
|
72
|
+
&::before {
|
|
73
|
+
/* 竖线 */
|
|
74
|
+
content: '';
|
|
75
|
+
height: ${height};
|
|
76
|
+
position: absolute;
|
|
77
|
+
left: -22px;
|
|
78
|
+
top: -16px;
|
|
79
|
+
width: 1px;
|
|
80
|
+
background: #d9d9d9;
|
|
81
|
+
display: block;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
&::after {
|
|
85
|
+
/* 横线 */
|
|
86
|
+
content: '';
|
|
87
|
+
position: absolute;
|
|
88
|
+
left: -22px; // 横线起点和竖线对齐
|
|
89
|
+
top: 8px; // 跟随你的行高调整
|
|
90
|
+
width: 18px; // 横线长度
|
|
91
|
+
height: 1px;
|
|
92
|
+
background: #d9d9d9;
|
|
93
|
+
display: block;
|
|
94
|
+
}
|
|
95
|
+
`
|
|
96
|
+
);
|
|
97
|
+
}}
|
|
80
98
|
`;
|
|
81
99
|
|
|
82
100
|
export const UIPropertyRight = styled.div`
|
|
@@ -88,18 +106,47 @@ export const UIPropertyRight = styled.div`
|
|
|
88
106
|
}
|
|
89
107
|
`;
|
|
90
108
|
|
|
91
|
-
export const UIPropertyMain = styled.div<{
|
|
109
|
+
export const UIPropertyMain = styled.div<{
|
|
110
|
+
$expand?: boolean;
|
|
111
|
+
type?: string;
|
|
112
|
+
$collapse?: boolean;
|
|
113
|
+
$showCollapse?: boolean;
|
|
114
|
+
}>`
|
|
92
115
|
display: flex;
|
|
93
116
|
flex-direction: column;
|
|
94
117
|
gap: 10px;
|
|
118
|
+
position: relative;
|
|
95
119
|
|
|
96
|
-
${({ $expand }) =>
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
120
|
+
${({ $expand, type, $collapse, $showCollapse }) => {
|
|
121
|
+
const beforeElement = `
|
|
122
|
+
&::before {
|
|
123
|
+
/* 竖线 */
|
|
124
|
+
content: '';
|
|
125
|
+
height: 100%;
|
|
126
|
+
position: absolute;
|
|
127
|
+
left: -12px;
|
|
128
|
+
top: 18px;
|
|
129
|
+
width: 1px;
|
|
130
|
+
background: #d9d9d9;
|
|
131
|
+
display: block;
|
|
132
|
+
}`;
|
|
133
|
+
|
|
134
|
+
return (
|
|
135
|
+
$expand &&
|
|
136
|
+
css`
|
|
137
|
+
background-color: #f5f5f5;
|
|
138
|
+
padding: 10px;
|
|
139
|
+
border-radius: 4px;
|
|
140
|
+
|
|
141
|
+
${$showCollapse &&
|
|
142
|
+
$collapse &&
|
|
143
|
+
(type === 'array' || type === 'object') &&
|
|
144
|
+
css`
|
|
145
|
+
${beforeElement}
|
|
146
|
+
`}
|
|
147
|
+
`
|
|
148
|
+
);
|
|
149
|
+
}}
|
|
103
150
|
`;
|
|
104
151
|
|
|
105
152
|
export const UICollapsible = styled.div<{ $collapse?: boolean }>`
|
|
@@ -143,3 +190,46 @@ const iconAddChildrenSvg = (
|
|
|
143
190
|
);
|
|
144
191
|
|
|
145
192
|
export const IconAddChildren = () => <Icon size="small" svg={iconAddChildrenSvg} />;
|
|
193
|
+
|
|
194
|
+
export const DefaultValueWrapper = styled.div`
|
|
195
|
+
margin: 0;
|
|
196
|
+
`;
|
|
197
|
+
|
|
198
|
+
export const JSONViewerWrapper = styled.div`
|
|
199
|
+
padding: 0 0 24px;
|
|
200
|
+
&:first-child {
|
|
201
|
+
margin-top: 0px;
|
|
202
|
+
}
|
|
203
|
+
`;
|
|
204
|
+
|
|
205
|
+
export const JSONHeader = styled.div`
|
|
206
|
+
display: flex;
|
|
207
|
+
justify-content: space-between;
|
|
208
|
+
align-items: center;
|
|
209
|
+
background-color: var(--semi-color-fill-0);
|
|
210
|
+
border-radius: 6px 6px 0 0;
|
|
211
|
+
height: 36px;
|
|
212
|
+
padding: 0 8px 0 12px;
|
|
213
|
+
`;
|
|
214
|
+
|
|
215
|
+
export const JSONHeaderLeft = styled.div`
|
|
216
|
+
display: flex;
|
|
217
|
+
align-items: center;
|
|
218
|
+
gap: 10px;
|
|
219
|
+
`;
|
|
220
|
+
|
|
221
|
+
export const JSONHeaderRight = styled.div`
|
|
222
|
+
display: flex;
|
|
223
|
+
align-items: center;
|
|
224
|
+
gap: 10px;
|
|
225
|
+
`;
|
|
226
|
+
|
|
227
|
+
export const ConstantInputWrapper = styled.div`
|
|
228
|
+
flex-grow: 1;
|
|
229
|
+
|
|
230
|
+
& .semi-tree-select,
|
|
231
|
+
& .semi-input-number,
|
|
232
|
+
& .semi-select {
|
|
233
|
+
width: 100%;
|
|
234
|
+
}
|
|
235
|
+
`;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Return the corresponding string description according to the type of the input value.根据输入值的类型返回对应的字符串描述。
|
|
3
|
+
* @param value - 需要判断类型的值。The value whose type needs to be judged.
|
|
4
|
+
* @returns 返回值的类型字符串 The type string of the return value('string', 'integer', 'number', 'boolean', 'object', 'array', 'other')。
|
|
5
|
+
*/
|
|
6
|
+
export function getValueType(value: any): string {
|
|
7
|
+
const type = typeof value;
|
|
8
|
+
|
|
9
|
+
if (type === 'string') {
|
|
10
|
+
return 'string';
|
|
11
|
+
} else if (type === 'number') {
|
|
12
|
+
return Number.isInteger(value) ? 'integer' : 'number';
|
|
13
|
+
} else if (type === 'boolean') {
|
|
14
|
+
return 'boolean';
|
|
15
|
+
} else if (type === 'object') {
|
|
16
|
+
if (value === null) {
|
|
17
|
+
return 'other';
|
|
18
|
+
}
|
|
19
|
+
return Array.isArray(value) ? 'array' : 'object';
|
|
20
|
+
} else {
|
|
21
|
+
// undefined, function, symbol, bigint etc.
|
|
22
|
+
return 'other';
|
|
23
|
+
}
|
|
24
|
+
}
|