@flowgram.ai/form-materials 0.4.0 → 0.4.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.
Files changed (39) hide show
  1. package/dist/esm/index.js +723 -401
  2. package/dist/esm/index.js.map +1 -1
  3. package/dist/index.d.mts +132 -29
  4. package/dist/index.d.ts +132 -29
  5. package/dist/index.js +839 -510
  6. package/dist/index.js.map +1 -1
  7. package/package.json +6 -5
  8. package/src/components/batch-outputs/index.tsx +3 -2
  9. package/src/components/dynamic-value-input/hooks.ts +1 -1
  10. package/src/components/dynamic-value-input/index.tsx +1 -1
  11. package/src/components/dynamic-value-input/styles.tsx +14 -4
  12. package/src/components/index.ts +2 -0
  13. package/src/components/inputs-values/index.tsx +3 -3
  14. package/src/components/inputs-values/styles.tsx +1 -1
  15. package/src/components/inputs-values-tree/hooks/use-child-list.tsx +71 -0
  16. package/src/components/inputs-values-tree/index.tsx +56 -0
  17. package/src/components/inputs-values-tree/row.tsx +163 -0
  18. package/src/components/inputs-values-tree/styles.tsx +128 -0
  19. package/src/components/inputs-values-tree/types.ts +21 -0
  20. package/src/components/json-schema-editor/default-value.tsx +1 -3
  21. package/src/components/json-schema-editor/hooks.tsx +13 -2
  22. package/src/components/json-schema-editor/index.tsx +17 -57
  23. package/src/components/json-schema-editor/styles.tsx +12 -55
  24. package/src/components/json-schema-editor/types.ts +0 -1
  25. package/src/components/prompt-editor/index.tsx +10 -3
  26. package/src/effects/auto-rename-ref/index.ts +7 -54
  27. package/src/form-plugins/infer-inputs-plugin/index.ts +3 -75
  28. package/src/hooks/use-object-list/index.tsx +34 -6
  29. package/src/plugins/json-schema-preset/manager.ts +1 -0
  30. package/src/plugins/json-schema-preset/type-definition/string.tsx +18 -9
  31. package/src/shared/flow-value/index.ts +6 -0
  32. package/src/shared/flow-value/schema.ts +38 -0
  33. package/src/shared/flow-value/utils.ts +201 -0
  34. package/src/shared/index.ts +1 -0
  35. package/src/typings/flow-value/index.ts +2 -0
  36. package/src/components/json-schema-editor/components/blur-input.tsx +0 -27
  37. package/src/plugins/disable-declaration-plugin/config.json +0 -5
  38. package/src/plugins/json-schema-preset/config.json +0 -9
  39. /package/src/components/{inputs-values/components/blur-input.tsx → blur-input/index.tsx} +0 -0
@@ -18,6 +18,7 @@ import {
18
18
  } from '@douyinfe/semi-icons';
19
19
 
20
20
  import { InjectTypeSelector } from '@/components/type-selector';
21
+ import { BlurInput } from '@/components/blur-input';
21
22
 
22
23
  import { ConfigType, PropertyValueType } from './types';
23
24
  import {
@@ -28,10 +29,10 @@ import {
28
29
  UIContainer,
29
30
  UIExpandDetail,
30
31
  UILabel,
31
- UIProperties,
32
- UIPropertyLeft,
33
- UIPropertyMain,
34
- UIPropertyRight,
32
+ UITreeItems,
33
+ UITreeItemLeft,
34
+ UITreeItemMain,
35
+ UITreeItemRight,
35
36
  UIRequired,
36
37
  UIType,
37
38
  } from './styles';
@@ -39,7 +40,6 @@ import { UIName } from './styles';
39
40
  import { DefaultValueWrapper, UIRow } from './styles';
40
41
  import { usePropertiesEdit } from './hooks';
41
42
  import { DefaultValue } from './default-value';
42
- import { BlurInput } from './components/blur-input';
43
43
 
44
44
  const DEFAULT = { type: 'object' };
45
45
 
@@ -58,14 +58,13 @@ export function JsonSchemaEditor(props: {
58
58
 
59
59
  return (
60
60
  <UIContainer className={props.className}>
61
- <UIProperties>
62
- {propertyList.map((_property, index) => (
61
+ <UITreeItems>
62
+ {propertyList.map((_property) => (
63
63
  <PropertyEdit
64
64
  readonly={readonly}
65
65
  key={_property.key}
66
66
  value={_property}
67
67
  config={config}
68
- $index={index}
69
68
  onChange={(_v) => {
70
69
  onEditProperty(_property.key!, _v);
71
70
  }}
@@ -74,7 +73,7 @@ export function JsonSchemaEditor(props: {
74
73
  }}
75
74
  />
76
75
  ))}
77
- </UIProperties>
76
+ </UITreeItems>
78
77
  <Button
79
78
  disabled={readonly}
80
79
  size="small"
@@ -95,27 +94,9 @@ function PropertyEdit(props: {
95
94
  onRemove?: () => void;
96
95
  readonly?: boolean;
97
96
  $isLast?: boolean;
98
- $index?: number;
99
- $isFirst?: boolean;
100
- $parentExpand?: boolean;
101
- $parentType?: string;
102
- $showLine?: boolean;
103
97
  $level?: number; // 添加层级属性
104
98
  }) {
105
- const {
106
- value,
107
- config,
108
- readonly,
109
- $level = 0,
110
- onChange: onChangeProps,
111
- onRemove,
112
- $index,
113
- $isFirst,
114
- $isLast,
115
- $parentExpand = false,
116
- $parentType = '',
117
- $showLine,
118
- } = props;
99
+ const { value, config, readonly, $level = 0, onChange: onChangeProps, onRemove, $isLast } = props;
119
100
 
120
101
  const [expand, setExpand] = useState(false);
121
102
  const [collapse, setCollapse] = useState(false);
@@ -138,29 +119,15 @@ function PropertyEdit(props: {
138
119
 
139
120
  return (
140
121
  <>
141
- <UIPropertyLeft
142
- type={type}
143
- $index={$index}
144
- $isFirst={$isFirst}
145
- $isLast={$isLast}
146
- $showLine={$showLine}
147
- $isExpand={expand}
148
- $parentExpand={$parentExpand}
149
- $parentType={$parentType}
150
- >
122
+ <UITreeItemLeft $isLast={$isLast} $showLine={$level > 0} $showCollapse={showCollapse}>
151
123
  {showCollapse && (
152
124
  <UICollapseTrigger onClick={() => setCollapse((_collapse) => !_collapse)}>
153
125
  {collapse ? <IconChevronDown size="small" /> : <IconChevronRight size="small" />}
154
126
  </UICollapseTrigger>
155
127
  )}
156
- </UIPropertyLeft>
157
- <UIPropertyRight>
158
- <UIPropertyMain
159
- $showCollapse={showCollapse}
160
- $collapse={collapse}
161
- $expand={expand}
162
- type={type}
163
- >
128
+ </UITreeItemLeft>
129
+ <UITreeItemRight>
130
+ <UITreeItemMain>
164
131
  <UIRow>
165
132
  <UIName>
166
133
  <BlurInput
@@ -242,9 +209,7 @@ function PropertyEdit(props: {
242
209
  <DefaultValue
243
210
  value={defaultValue}
244
211
  schema={value}
245
- type={type}
246
212
  placeholder={config?.defaultValuePlaceholder ?? I18n.t('Default Value')}
247
- jsonFormatText={config?.jsonFormatText}
248
213
  onChange={(value) => onChange('default', value)}
249
214
  />
250
215
  </DefaultValueWrapper>
@@ -252,10 +217,10 @@ function PropertyEdit(props: {
252
217
  )}
253
218
  </UIExpandDetail>
254
219
  )}
255
- </UIPropertyMain>
220
+ </UITreeItemMain>
256
221
  {showCollapse && (
257
222
  <UICollapsible $collapse={collapse}>
258
- <UIProperties $shrink={true}>
223
+ <UITreeItems $shrink={true}>
259
224
  {propertyList.map((_property, index) => (
260
225
  <PropertyEdit
261
226
  readonly={readonly}
@@ -263,8 +228,6 @@ function PropertyEdit(props: {
263
228
  value={_property}
264
229
  config={config}
265
230
  $level={$level + 1} // 传递递增的层级
266
- $parentExpand={expand}
267
- $parentType={type}
268
231
  onChange={(_v) => {
269
232
  onEditProperty(_property.key!, _v);
270
233
  }}
@@ -272,15 +235,12 @@ function PropertyEdit(props: {
272
235
  onRemoveProperty(_property.key!);
273
236
  }}
274
237
  $isLast={index === propertyList.length - 1}
275
- $isFirst={index === 0}
276
- $index={index}
277
- $showLine={true}
278
238
  />
279
239
  ))}
280
- </UIProperties>
240
+ </UITreeItems>
281
241
  </UICollapsible>
282
242
  )}
283
- </UIPropertyRight>
243
+ </UITreeItemRight>
284
244
  </>
285
245
  );
286
246
  }
@@ -39,37 +39,30 @@ export const UILabel = styled.div`
39
39
  margin-bottom: 2px;
40
40
  `;
41
41
 
42
- export const UIProperties = styled.div<{ $shrink?: boolean }>`
42
+ export const UITreeItems = styled.div<{ $shrink?: boolean }>`
43
43
  display: grid;
44
44
  grid-template-columns: auto 1fr;
45
45
 
46
46
  ${({ $shrink }) =>
47
47
  $shrink &&
48
48
  css`
49
- padding-left: 10px;
49
+ padding-left: 3px;
50
50
  margin-top: 10px;
51
51
  `}
52
52
  `;
53
53
 
54
- export const UIPropertyLeft = styled.div<{
54
+ export const UITreeItemLeft = styled.div<{
55
55
  $isLast?: boolean;
56
56
  $showLine?: boolean;
57
- $isExpand?: boolean;
58
- type?: string;
59
- $isFirst?: boolean;
60
- $index?: number;
61
- $parentExpand?: boolean;
62
- $parentType?: string;
57
+ $showCollapse?: boolean;
63
58
  }>`
64
59
  grid-column: 1;
65
60
  position: relative;
66
61
  width: 16px;
67
62
 
68
- ${({ $showLine, $isLast, $parentType }) => {
69
- let height = '100%';
70
- if ($parentType && $isLast) {
71
- height = '24px';
72
- }
63
+ ${({ $showLine, $isLast, $showCollapse }) => {
64
+ let height = $isLast ? '24px' : '100%';
65
+ let width = $showCollapse ? '12px' : '30px';
73
66
 
74
67
  return (
75
68
  $showLine &&
@@ -79,7 +72,7 @@ export const UIPropertyLeft = styled.div<{
79
72
  content: '';
80
73
  height: ${height};
81
74
  position: absolute;
82
- left: -22px;
75
+ left: -14px;
83
76
  top: -16px;
84
77
  width: 1px;
85
78
  background: #d9d9d9;
@@ -90,9 +83,9 @@ export const UIPropertyLeft = styled.div<{
90
83
  /* 横线 */
91
84
  content: '';
92
85
  position: absolute;
93
- left: -22px; // 横线起点和竖线对齐
86
+ left: -14px; // 横线起点和竖线对齐
94
87
  top: 8px; // 跟随你的行高调整
95
- width: 18px; // 横线长度
88
+ width: ${width}; // 横线长度
96
89
  height: 1px;
97
90
  background: #d9d9d9;
98
91
  display: block;
@@ -102,7 +95,7 @@ export const UIPropertyLeft = styled.div<{
102
95
  }}
103
96
  `;
104
97
 
105
- export const UIPropertyRight = styled.div`
98
+ export const UITreeItemRight = styled.div`
106
99
  grid-column: 2;
107
100
  margin-bottom: 10px;
108
101
 
@@ -111,47 +104,11 @@ export const UIPropertyRight = styled.div`
111
104
  }
112
105
  `;
113
106
 
114
- export const UIPropertyMain = styled.div<{
115
- $expand?: boolean;
116
- type?: string;
117
- $collapse?: boolean;
118
- $showCollapse?: boolean;
119
- }>`
107
+ export const UITreeItemMain = styled.div<{}>`
120
108
  display: flex;
121
109
  flex-direction: column;
122
110
  gap: 10px;
123
111
  position: relative;
124
-
125
- ${({ $expand, type, $collapse, $showCollapse }) => {
126
- const beforeElement = `
127
- &::before {
128
- /* 竖线 */
129
- content: '';
130
- height: 100%;
131
- position: absolute;
132
- left: -12px;
133
- top: 18px;
134
- width: 1px;
135
- background: #d9d9d9;
136
- display: block;
137
- }`;
138
-
139
- return (
140
- $expand &&
141
- css`
142
- background-color: #f5f5f5;
143
- padding: 10px;
144
- border-radius: 4px;
145
-
146
- ${$showCollapse &&
147
- $collapse &&
148
- (type === 'array' || type === 'object') &&
149
- css`
150
- ${beforeElement}
151
- `}
152
- `
153
- );
154
- }}
155
112
  `;
156
113
 
157
114
  export const UICollapsible = styled.div<{ $collapse?: boolean }>`
@@ -22,5 +22,4 @@ export interface ConfigType {
22
22
  defaultValueTitle?: string;
23
23
  defaultValuePlaceholder?: string;
24
24
  addButtonText?: string;
25
- jsonFormatText?: string;
26
25
  }
@@ -5,7 +5,7 @@
5
5
 
6
6
  import React, { useEffect, useRef } from 'react';
7
7
 
8
- import { Renderer, EditorProvider, ActiveLinePlaceholder } from '@coze-editor/editor/react';
8
+ import { Renderer, EditorProvider, ActiveLinePlaceholder, InferValues } from '@coze-editor/editor/react';
9
9
  import preset, { EditorAPI } from '@coze-editor/editor/preset-prompt';
10
10
 
11
11
  import { PropsType } from './types';
@@ -14,9 +14,14 @@ import MarkdownHighlight from './extensions/markdown';
14
14
  import LanguageSupport from './extensions/language-support';
15
15
  import JinjaHighlight from './extensions/jinja';
16
16
 
17
- export type PromptEditorPropsType = PropsType;
17
+ type Preset = typeof preset;
18
+ type Options = Partial<InferValues<Preset[number]>>;
18
19
 
19
- export function PromptEditor(props: PropsType) {
20
+ export interface PromptEditorPropsType extends PropsType {
21
+ options?: Options;
22
+ }
23
+
24
+ export function PromptEditor(props: PromptEditorPropsType) {
20
25
  const {
21
26
  value,
22
27
  onChange,
@@ -27,6 +32,7 @@ export function PromptEditor(props: PropsType) {
27
32
  hasError,
28
33
  children,
29
34
  disableMarkdownHighlight,
35
+ options,
30
36
  } = props || {};
31
37
 
32
38
  const editorRef = useRef<EditorAPI | null>(null);
@@ -51,6 +57,7 @@ export function PromptEditor(props: PropsType) {
51
57
  readOnly: readonly,
52
58
  editable: !readonly,
53
59
  placeholder,
60
+ ...options
54
61
  }}
55
62
  onChange={(e) => {
56
63
  onChange({ type: 'template', content: e.value });
@@ -3,7 +3,6 @@
3
3
  * SPDX-License-Identifier: MIT
4
4
  */
5
5
 
6
- import { isArray, isObject, uniq } from 'lodash';
7
6
  import {
8
7
  DataEvent,
9
8
  Effect,
@@ -12,6 +11,7 @@ import {
12
11
  } from '@flowgram.ai/editor';
13
12
 
14
13
  import { IFlowRefValue, IFlowTemplateValue } from '@/typings';
14
+ import { FlowValueUtils } from '@/shared';
15
15
 
16
16
  /**
17
17
  * Auto rename ref when form item's key is renamed
@@ -52,7 +52,7 @@ export const autoRenameRefEffect: EffectOptions[] = [
52
52
  }
53
53
  } else if (_v.type === 'template') {
54
54
  // template auto rename
55
- const templateKeyPaths = getTemplateKeyPaths(_v);
55
+ const templateKeyPaths = FlowValueUtils.getTemplateKeyPaths(_v);
56
56
  let hasMatch = false;
57
57
 
58
58
  templateKeyPaths.forEach((_keyPath) => {
@@ -93,34 +93,6 @@ function isKeyPathMatch(keyPath: string[] = [], targetKeyPath: string[]) {
93
93
  return targetKeyPath.every((_key, index) => _key === keyPath[index]);
94
94
  }
95
95
 
96
- /**
97
- * get template key paths
98
- * @param value
99
- * @returns
100
- */
101
- function getTemplateKeyPaths(value: IFlowTemplateValue) {
102
- // find all keyPath wrapped in {{}}
103
- const keyPathReg = /{{(.*?)}}/g;
104
- return uniq(value.content?.match(keyPathReg) || []).map((_keyPath) =>
105
- _keyPath.slice(2, -2).split('.')
106
- );
107
- }
108
-
109
- /**
110
- * If value is ref
111
- * @param value
112
- * @returns
113
- */
114
- function isRef(value: any): value is IFlowRefValue {
115
- return (
116
- value?.type === 'ref' && Array.isArray(value?.content) && typeof value?.content[0] === 'string'
117
- );
118
- }
119
-
120
- function isTemplate(value: any): value is IFlowTemplateValue {
121
- return value?.type === 'template' && typeof value?.content === 'string';
122
- }
123
-
124
96
  /**
125
97
  * Traverse value to find ref
126
98
  * @param value
@@ -132,29 +104,10 @@ function traverseRef(
132
104
  value: any,
133
105
  cb: (name: string, _v: IFlowRefValue | IFlowTemplateValue) => void
134
106
  ) {
135
- if (isObject(value)) {
136
- if (isRef(value)) {
137
- cb(name, value);
138
- return;
139
- }
140
-
141
- if (isTemplate(value)) {
142
- cb(name, value);
143
- return;
144
- }
145
-
146
- Object.entries(value).forEach(([_key, _value]) => {
147
- traverseRef(`${name}.${_key}`, _value, cb);
148
- });
149
- return;
150
- }
151
-
152
- if (isArray(value)) {
153
- value.forEach((_value, idx) => {
154
- traverseRef(`${name}[${idx}]`, _value, cb);
155
- });
156
- return;
107
+ for (const { value: _v, path } of FlowValueUtils.traverse(value, {
108
+ includeTypes: ['ref', 'template'],
109
+ path: name,
110
+ })) {
111
+ cb(path, _v as IFlowRefValue | IFlowTemplateValue);
157
112
  }
158
-
159
- return;
160
113
  }
@@ -4,15 +4,9 @@
4
4
  */
5
5
 
6
6
  import { get, set } from 'lodash';
7
- import { JsonSchemaUtils, IJsonSchema } from '@flowgram.ai/json-schema';
8
- import {
9
- defineFormPluginCreator,
10
- getNodePrivateScope,
11
- getNodeScope,
12
- Scope,
13
- } from '@flowgram.ai/editor';
7
+ import { defineFormPluginCreator, getNodePrivateScope, getNodeScope } from '@flowgram.ai/editor';
14
8
 
15
- import { IFlowConstantValue, IFlowRefValue, IFlowTemplateValue } from '@/typings';
9
+ import { FlowValueUtils } from '@/shared';
16
10
 
17
11
  interface InputConfig {
18
12
  sourceKey: string;
@@ -30,7 +24,7 @@ export const createInferInputsPlugin = defineFormPluginCreator<InputConfig>({
30
24
  set(
31
25
  formData,
32
26
  targetKey,
33
- infer(
27
+ FlowValueUtils.inferJsonSchema(
34
28
  get(formData, sourceKey),
35
29
  scope === 'private' ? getNodePrivateScope(ctx.node) : getNodeScope(ctx.node)
36
30
  )
@@ -40,69 +34,3 @@ export const createInferInputsPlugin = defineFormPluginCreator<InputConfig>({
40
34
  });
41
35
  },
42
36
  });
43
-
44
- function isRef(value: any): value is IFlowRefValue {
45
- return (
46
- value?.type === 'ref' && Array.isArray(value?.content) && typeof value?.content[0] === 'string'
47
- );
48
- }
49
-
50
- function isTemplate(value: any): value is IFlowTemplateValue {
51
- return value?.type === 'template' && typeof value?.content === 'string';
52
- }
53
-
54
- function isConstant(value: any): value is IFlowConstantValue {
55
- return value?.type === 'constant' && typeof value?.content !== 'undefined';
56
- }
57
-
58
- const infer = (values: any, scope: Scope): IJsonSchema | undefined => {
59
- if (typeof values === 'object') {
60
- if (isConstant(values)) {
61
- if (values?.schema) {
62
- return values.schema;
63
- }
64
-
65
- if (typeof values.content === 'string') {
66
- return {
67
- type: 'string',
68
- };
69
- }
70
-
71
- if (typeof values.content === 'number') {
72
- return {
73
- type: 'number',
74
- };
75
- }
76
-
77
- if (typeof values.content === 'boolean') {
78
- return {
79
- type: 'boolean',
80
- };
81
- }
82
- }
83
-
84
- if (isRef(values)) {
85
- const variable = scope.available.getByKeyPath(values?.content);
86
- const schema = variable?.type ? JsonSchemaUtils.astToSchema(variable?.type) : undefined;
87
-
88
- return schema;
89
- }
90
-
91
- if (isTemplate(values)) {
92
- return {
93
- type: 'string',
94
- };
95
- }
96
-
97
- return {
98
- type: 'object',
99
- properties: Object.keys(values).reduce((acc, key) => {
100
- const schema = infer(values[key], scope);
101
- if (schema) {
102
- acc[key] = schema;
103
- }
104
- return acc;
105
- }, {} as Record<string, IJsonSchema>),
106
- };
107
- }
108
- };
@@ -3,7 +3,7 @@
3
3
  * SPDX-License-Identifier: MIT
4
4
  */
5
5
 
6
- import { useEffect, useState } from 'react';
6
+ import { useEffect, useRef, useState } from 'react';
7
7
 
8
8
  import { nanoid } from 'nanoid';
9
9
  import { difference, get, isObject, set } from 'lodash';
@@ -27,14 +27,30 @@ export function useObjectList<ValueType>({
27
27
  }: {
28
28
  value?: ObjectType<ValueType>;
29
29
  onChange: (value?: ObjectType<ValueType>) => void;
30
- sortIndexKey?: string;
30
+ sortIndexKey?: string | ((item: ValueType | undefined) => string);
31
31
  }) {
32
32
  const [list, setList] = useState<ListItem<ValueType>[]>([]);
33
33
 
34
+ const effectVersion = useRef(0);
35
+ const changeVersion = useRef(0);
36
+
37
+ const getSortIndex = (value?: ValueType) => {
38
+ if (typeof sortIndexKey === 'function') {
39
+ return get(value, sortIndexKey(value)) || 0;
40
+ }
41
+ return get(value, sortIndexKey || '') || 0;
42
+ };
43
+
34
44
  useEffect(() => {
45
+ effectVersion.current = effectVersion.current + 1;
46
+ if (effectVersion.current === changeVersion.current) {
47
+ return;
48
+ }
49
+ effectVersion.current = changeVersion.current;
50
+
35
51
  setList((_prevList) => {
36
52
  const newKeys = Object.entries(value || {})
37
- .sort((a, b) => get(a[1], sortIndexKey || 0) - get(b[1], sortIndexKey || 0))
53
+ .sort((a, b) => getSortIndex(a[1]) - getSortIndex(b[1]))
38
54
  .map(([key]) => key);
39
55
 
40
56
  const oldKeys = _prevList.map((item) => item.key).filter(Boolean) as string[];
@@ -57,16 +73,19 @@ export function useObjectList<ValueType>({
57
73
  });
58
74
  }, [value]);
59
75
 
60
- const add = () => {
76
+ const add = (defaultValue?: ValueType) => {
61
77
  setList((prevList) => [
62
78
  ...prevList,
63
79
  {
64
80
  id: genId(),
81
+ value: defaultValue,
65
82
  },
66
83
  ]);
67
84
  };
68
85
 
69
86
  const updateValue = (itemId: string, value: ValueType) => {
87
+ changeVersion.current = changeVersion.current + 1;
88
+
70
89
  setList((prevList) => {
71
90
  const nextList = prevList.map((_item) => {
72
91
  if (_item.id === itemId) {
@@ -84,8 +103,13 @@ export function useObjectList<ValueType>({
84
103
  .filter((item) => item.key)
85
104
  .map((item) => [item.key!, item.value])
86
105
  .map((_res, idx) => {
87
- if (isObject(_res[1]) && sortIndexKey) {
88
- set(_res[1], sortIndexKey, idx);
106
+ const indexKey =
107
+ typeof sortIndexKey === 'function'
108
+ ? sortIndexKey(_res[1] as ValueType | undefined)
109
+ : sortIndexKey;
110
+
111
+ if (isObject(_res[1]) && indexKey) {
112
+ set(_res[1], indexKey, idx);
89
113
  }
90
114
  return _res;
91
115
  })
@@ -97,6 +121,8 @@ export function useObjectList<ValueType>({
97
121
  };
98
122
 
99
123
  const updateKey = (itemId: string, key: string) => {
124
+ changeVersion.current = changeVersion.current + 1;
125
+
100
126
  setList((prevList) => {
101
127
  const nextList = prevList.map((_item) => {
102
128
  if (_item.id === itemId) {
@@ -119,6 +145,8 @@ export function useObjectList<ValueType>({
119
145
  };
120
146
 
121
147
  const remove = (itemId: string) => {
148
+ changeVersion.current = changeVersion.current + 1;
149
+
122
150
  setList((prevList) => {
123
151
  const nextList = prevList.filter((_item) => _item.id !== itemId);
124
152
 
@@ -9,6 +9,7 @@ export interface ConstantRendererProps<Value = any> {
9
9
  value?: Value;
10
10
  onChange?: (value: Value) => void;
11
11
  readonly?: boolean;
12
+ [key: string]: any;
12
13
  }
13
14
  export interface JsonSchemaTypeRegistry<Value = any> extends OriginJsonSchemaTypeRegistry {
14
15
  /**
@@ -7,18 +7,27 @@
7
7
  import React from 'react';
8
8
 
9
9
  import { I18n } from '@flowgram.ai/editor';
10
- import { Input } from '@douyinfe/semi-ui';
10
+ import { Input, TextArea } from '@douyinfe/semi-ui';
11
11
 
12
12
  import { type JsonSchemaTypeRegistry } from '../manager';
13
13
 
14
14
  export const stringRegistry: Partial<JsonSchemaTypeRegistry> = {
15
15
  type: 'string',
16
- ConstantRenderer: (props) => (
17
- <Input
18
- placeholder={I18n.t('Please Input String')}
19
- size="small"
20
- disabled={props.readonly}
21
- {...props}
22
- />
23
- ),
16
+ ConstantRenderer: (props) =>
17
+ props?.enableMultiLineStr ? (
18
+ <TextArea
19
+ autosize
20
+ rows={1}
21
+ placeholder={I18n.t('Please Input String')}
22
+ disabled={props.readonly}
23
+ {...props}
24
+ />
25
+ ) : (
26
+ <Input
27
+ size="small"
28
+ placeholder={I18n.t('Please Input String')}
29
+ disabled={props.readonly}
30
+ {...props}
31
+ />
32
+ ),
24
33
  };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export * from './utils';