@flowgram.ai/form-materials 0.1.0-alpha.12 → 0.1.0-alpha.14

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 (164) hide show
  1. package/bin/index.ts +4 -29
  2. package/bin/materials.ts +56 -87
  3. package/bin/project.ts +4 -0
  4. package/bin/utils/import.ts +127 -0
  5. package/bin/utils/traverse-file.ts +60 -0
  6. package/dist/esm/chunk-727SU246.js +13 -0
  7. package/dist/esm/chunk-727SU246.js.map +1 -0
  8. package/dist/esm/chunk-DEZUEMUM.js +284 -0
  9. package/dist/esm/chunk-DEZUEMUM.js.map +1 -0
  10. package/dist/esm/chunk-DUOXDOUE.js +477 -0
  11. package/dist/esm/chunk-DUOXDOUE.js.map +1 -0
  12. package/dist/esm/editor-6UMULJYB.js +180 -0
  13. package/dist/esm/editor-6UMULJYB.js.map +1 -0
  14. package/dist/esm/editor-EYOQTGMT.js +282 -0
  15. package/dist/esm/editor-EYOQTGMT.js.map +1 -0
  16. package/dist/esm/editor-OXPGKPF5.js +167 -0
  17. package/dist/esm/editor-OXPGKPF5.js.map +1 -0
  18. package/dist/esm/editor-VO6YAXRC.js +249 -0
  19. package/dist/esm/editor-VO6YAXRC.js.map +1 -0
  20. package/dist/esm/editor-XYLKTB6L.js +365 -0
  21. package/dist/esm/editor-XYLKTB6L.js.map +1 -0
  22. package/dist/esm/index.js +1186 -2456
  23. package/dist/esm/index.js.map +1 -1
  24. package/dist/index.d.mts +363 -70
  25. package/dist/index.d.ts +363 -70
  26. package/dist/index.js +4064 -2887
  27. package/dist/index.js.map +1 -1
  28. package/package.json +9 -8
  29. package/src/components/assign-row/index.tsx +4 -4
  30. package/src/components/assign-rows/index.tsx +1 -1
  31. package/src/components/batch-outputs/index.tsx +7 -5
  32. package/src/components/batch-outputs/types.ts +1 -1
  33. package/src/components/batch-variable-selector/index.tsx +1 -1
  34. package/src/components/code-editor/editor.tsx +89 -0
  35. package/src/components/code-editor/index.tsx +5 -89
  36. package/src/components/code-editor/language-features.ts +18 -18
  37. package/src/components/code-editor/theme/dark.ts +49 -30
  38. package/src/components/code-editor/theme/light.ts +56 -32
  39. package/src/components/code-editor-mini/index.tsx +2 -2
  40. package/src/components/condition-row/constants.ts +10 -2
  41. package/src/components/condition-row/hooks/useOp.tsx +13 -9
  42. package/src/components/condition-row/hooks/useRule.ts +8 -4
  43. package/src/components/condition-row/index.tsx +31 -10
  44. package/src/components/condition-row/types.ts +5 -7
  45. package/src/components/constant-input/index.tsx +5 -2
  46. package/src/components/constant-input/types.ts +1 -1
  47. package/src/components/db-condition-row/hooks/use-left.tsx +66 -0
  48. package/src/components/db-condition-row/hooks/use-op.tsx +59 -0
  49. package/src/components/db-condition-row/index.tsx +93 -0
  50. package/src/components/db-condition-row/styles.tsx +43 -0
  51. package/src/components/db-condition-row/types.ts +34 -0
  52. package/src/components/display-flow-value/index.tsx +4 -14
  53. package/src/components/display-inputs-values/index.tsx +46 -7
  54. package/src/components/display-outputs/index.tsx +2 -1
  55. package/src/components/display-schema-tag/index.tsx +3 -2
  56. package/src/components/display-schema-tree/index.tsx +2 -1
  57. package/src/components/dynamic-value-input/hooks.ts +25 -4
  58. package/src/components/dynamic-value-input/index.tsx +33 -20
  59. package/src/components/dynamic-value-input/styles.tsx +14 -4
  60. package/src/components/index.ts +3 -0
  61. package/src/components/inputs-values/index.tsx +21 -8
  62. package/src/components/inputs-values/styles.tsx +1 -1
  63. package/src/components/inputs-values/types.ts +3 -3
  64. package/src/components/inputs-values-tree/hooks/use-child-list.tsx +76 -0
  65. package/src/components/inputs-values-tree/index.tsx +62 -0
  66. package/src/components/inputs-values-tree/row.tsx +177 -0
  67. package/src/components/inputs-values-tree/styles.tsx +128 -0
  68. package/src/components/inputs-values-tree/types.ts +21 -0
  69. package/src/components/json-editor-with-variables/editor.tsx +69 -0
  70. package/src/components/json-editor-with-variables/extensions/variable-tag.tsx +6 -5
  71. package/src/components/json-editor-with-variables/extensions/variable-tree.tsx +1 -1
  72. package/src/components/json-editor-with-variables/index.tsx +5 -58
  73. package/src/components/json-schema-editor/default-value.tsx +12 -108
  74. package/src/components/json-schema-editor/hooks.tsx +63 -93
  75. package/src/components/json-schema-editor/index.tsx +36 -70
  76. package/src/components/json-schema-editor/styles.tsx +12 -84
  77. package/src/components/json-schema-editor/types.ts +0 -1
  78. package/src/components/prompt-editor/editor.tsx +81 -0
  79. package/src/components/prompt-editor/index.tsx +5 -62
  80. package/src/components/prompt-editor/types.tsx +1 -1
  81. package/src/components/prompt-editor-with-inputs/editor.tsx +25 -0
  82. package/src/components/prompt-editor-with-inputs/extensions/inputs-tree.tsx +13 -1
  83. package/src/components/prompt-editor-with-inputs/index.tsx +5 -15
  84. package/src/components/prompt-editor-with-inputs/inputs-picker.tsx +34 -17
  85. package/src/components/prompt-editor-with-variables/editor.tsx +22 -0
  86. package/src/components/prompt-editor-with-variables/extensions/variable-tag.tsx +12 -20
  87. package/src/components/prompt-editor-with-variables/extensions/variable-tree.tsx +14 -2
  88. package/src/components/prompt-editor-with-variables/index.tsx +5 -12
  89. package/src/components/type-selector/index.tsx +21 -9
  90. package/src/components/variable-selector/context.tsx +28 -0
  91. package/src/components/variable-selector/index.tsx +19 -6
  92. package/src/components/variable-selector/use-variable-tree.tsx +4 -4
  93. package/src/effects/auto-rename-ref/index.ts +8 -55
  94. package/src/effects/listen-ref-schema-change/index.ts +1 -1
  95. package/src/effects/listen-ref-value-change/index.ts +1 -1
  96. package/src/effects/provide-batch-input/index.ts +1 -1
  97. package/src/effects/validate-when-variable-sync/index.ts +1 -1
  98. package/src/form-plugins/batch-outputs-plugin/index.ts +1 -1
  99. package/src/form-plugins/infer-assign-plugin/index.ts +2 -2
  100. package/src/form-plugins/infer-inputs-plugin/index.ts +4 -76
  101. package/src/hooks/use-object-list/index.tsx +35 -7
  102. package/src/index.ts +1 -0
  103. package/src/plugins/json-schema-preset/manager.ts +1 -0
  104. package/src/plugins/json-schema-preset/type-definition/array.tsx +3 -1
  105. package/src/plugins/json-schema-preset/type-definition/boolean.tsx +4 -3
  106. package/src/plugins/json-schema-preset/type-definition/date-time.tsx +25 -0
  107. package/src/plugins/json-schema-preset/type-definition/index.tsx +2 -0
  108. package/src/plugins/json-schema-preset/type-definition/integer.tsx +2 -1
  109. package/src/plugins/json-schema-preset/type-definition/number.tsx +2 -1
  110. package/src/plugins/json-schema-preset/type-definition/object.tsx +3 -1
  111. package/src/plugins/json-schema-preset/type-definition/string.tsx +19 -4
  112. package/src/shared/flow-value/index.ts +6 -0
  113. package/src/shared/flow-value/schema.ts +38 -0
  114. package/src/shared/flow-value/utils.ts +201 -0
  115. package/src/shared/format-legacy-refs/index.ts +1 -1
  116. package/src/shared/index.ts +4 -0
  117. package/src/shared/inject-material/README.md +170 -0
  118. package/src/shared/inject-material/README.zh.md +174 -0
  119. package/src/shared/inject-material/index.tsx +87 -0
  120. package/src/shared/lazy-suspense/index.tsx +28 -0
  121. package/src/shared/polyfill-create-root/index.tsx +33 -0
  122. package/src/typings/flow-value/index.ts +3 -1
  123. package/src/validate/validate-flow-value/index.tsx +4 -16
  124. package/src/components/assign-row/config.json +0 -11
  125. package/src/components/assign-rows/config.json +0 -11
  126. package/src/components/batch-outputs/config.json +0 -13
  127. package/src/components/batch-variable-selector/config.json +0 -9
  128. package/src/components/code-editor/config.json +0 -10
  129. package/src/components/code-editor-mini/config.json +0 -7
  130. package/src/components/condition-row/config.json +0 -13
  131. package/src/components/constant-input/config.json +0 -9
  132. package/src/components/display-flow-value/config.json +0 -8
  133. package/src/components/display-inputs-values/config.json +0 -9
  134. package/src/components/display-outputs/config.json +0 -10
  135. package/src/components/display-schema-tag/config.json +0 -10
  136. package/src/components/display-schema-tree/config.json +0 -11
  137. package/src/components/dynamic-value-input/config.json +0 -14
  138. package/src/components/inputs-values/config.json +0 -13
  139. package/src/components/json-editor-with-variables/config.json +0 -13
  140. package/src/components/json-schema-editor/components/blur-input.tsx +0 -27
  141. package/src/components/json-schema-editor/config.json +0 -13
  142. package/src/components/json-schema-editor/utils.ts +0 -29
  143. package/src/components/prompt-editor/config.json +0 -9
  144. package/src/components/prompt-editor-with-inputs/config.json +0 -13
  145. package/src/components/prompt-editor-with-variables/config.json +0 -13
  146. package/src/components/type-selector/config.json +0 -9
  147. package/src/components/variable-selector/config.json +0 -9
  148. package/src/effects/auto-rename-ref/config.json +0 -5
  149. package/src/effects/listen-ref-schema-change/config.json +0 -10
  150. package/src/effects/listen-ref-value-change/config.json +0 -9
  151. package/src/effects/provide-batch-input/config.json +0 -5
  152. package/src/effects/provide-json-schema-outputs/config.json +0 -7
  153. package/src/effects/sync-variable-title/config.json +0 -5
  154. package/src/effects/validate-when-variable-sync/config.json +0 -5
  155. package/src/form-plugins/batch-outputs-plugin/config.json +0 -7
  156. package/src/form-plugins/infer-assign-plugin/config.json +0 -7
  157. package/src/form-plugins/infer-inputs-plugin/config.json +0 -9
  158. package/src/hooks/use-object-list/config.json +0 -8
  159. package/src/plugins/disable-declaration-plugin/config.json +0 -5
  160. package/src/plugins/json-schema-preset/config.json +0 -9
  161. package/src/shared/format-legacy-refs/config.json +0 -5
  162. package/src/typings/flow-value/config.json +0 -7
  163. package/src/validate/validate-flow-value/config.json +0 -7
  164. /package/src/components/{inputs-values/components/blur-input.tsx → blur-input/index.tsx} +0 -0
@@ -7,7 +7,8 @@ import React from 'react';
7
7
 
8
8
  import { IJsonSchema, JsonSchemaTypeManager } from '@flowgram.ai/json-schema';
9
9
 
10
- import { useTypeManager } from '../../plugins';
10
+ import { useTypeManager } from '@/plugins';
11
+
11
12
  import { HorizontalLine, TreeItem, TreeLevel, TreeRow, TreeTitle } from './styles';
12
13
 
13
14
  interface PropsType {
@@ -3,12 +3,12 @@
3
3
  * SPDX-License-Identifier: MIT
4
4
  */
5
5
 
6
- import { useMemo, useState } from 'react';
6
+ import { useEffect, useMemo, useRef, useState } from 'react';
7
7
 
8
8
  import { IJsonSchema } from '@flowgram.ai/json-schema';
9
9
  import { useScopeAvailable } from '@flowgram.ai/editor';
10
10
 
11
- import { IFlowConstantRefValue } from '../../typings/flow-value';
11
+ import { IFlowConstantRefValue } from '@/typings';
12
12
 
13
13
  export function useRefVariable(value?: IFlowConstantRefValue) {
14
14
  const available = useScopeAvailable();
@@ -33,9 +33,30 @@ export function useSelectSchema(
33
33
  defaultSelectSchema = value?.schema || defaultSelectSchema;
34
34
  }
35
35
 
36
+ const changeVersion = useRef(0);
37
+ const effectVersion = useRef(0);
38
+
36
39
  const [selectSchema, setSelectSchema] = useState(defaultSelectSchema);
37
40
 
38
- return [selectSchema, setSelectSchema] as const;
41
+ useEffect(() => {
42
+ effectVersion.current += 1;
43
+ if (changeVersion.current === effectVersion.current) {
44
+ return;
45
+ }
46
+ effectVersion.current = changeVersion.current;
47
+
48
+ if (value?.type === 'constant' && value?.schema) {
49
+ setSelectSchema(value?.schema);
50
+ return;
51
+ }
52
+ }, [value]);
53
+
54
+ const setSelectSchemaWithVersionUpdate = (schema: IJsonSchema) => {
55
+ setSelectSchema(schema);
56
+ changeVersion.current += 1;
57
+ };
58
+
59
+ return [selectSchema, setSelectSchemaWithVersionUpdate] as const;
39
60
  }
40
61
 
41
62
  export function useIncludeSchema(schemaFromProps?: IJsonSchema) {
@@ -46,7 +67,7 @@ export function useIncludeSchema(schemaFromProps?: IJsonSchema) {
46
67
  if (schemaFromProps?.type === 'number') {
47
68
  return [schemaFromProps, { type: 'integer' }];
48
69
  }
49
- return { ...schemaFromProps, extra: { ...schemaFromProps?.extra, weak: true } };
70
+ return { ...schemaFromProps, extra: { weak: true, ...schemaFromProps?.extra } };
50
71
  }, [schemaFromProps]);
51
72
 
52
73
  return includeSchema;
@@ -5,15 +5,21 @@
5
5
 
6
6
  import React from 'react';
7
7
 
8
- import { JsonSchemaUtils, IJsonSchema } from '@flowgram.ai/json-schema';
8
+ import {
9
+ JsonSchemaUtils,
10
+ IJsonSchema,
11
+ useTypeManager,
12
+ type JsonSchemaTypeManager,
13
+ } from '@flowgram.ai/json-schema';
9
14
  import { IconButton } from '@douyinfe/semi-ui';
10
15
  import { IconSetting } from '@douyinfe/semi-icons';
11
16
 
12
- import { VariableSelector } from '../variable-selector';
13
- import { TypeSelector } from '../type-selector';
14
- import { Strategy } from '../constant-input/types';
15
- import { ConstantInput } from '../constant-input';
16
- import { IFlowConstantRefValue } from '../../typings/flow-value';
17
+ import { IFlowConstantRefValue, IFlowConstantValue } from '@/typings';
18
+ import { createInjectMaterial } from '@/shared';
19
+ import { InjectVariableSelector } from '@/components/variable-selector';
20
+ import { TypeSelector } from '@/components/type-selector';
21
+ import { ConstantInput, ConstantInputStrategy } from '@/components/constant-input';
22
+
17
23
  import { UIContainer, UIMain, UITrigger, UIType } from './styles';
18
24
  import { useIncludeSchema, useRefVariable, useSelectSchema } from './hooks';
19
25
 
@@ -25,12 +31,18 @@ interface PropsType {
25
31
  style?: React.CSSProperties;
26
32
  schema?: IJsonSchema;
27
33
  constantProps?: {
28
- strategies?: Strategy[];
34
+ strategies?: ConstantInputStrategy[];
29
35
  schema?: IJsonSchema; // set schema of constant input only
30
36
  [key: string]: any;
31
37
  };
32
38
  }
33
39
 
40
+ const DEFAULT_VALUE: IFlowConstantValue = {
41
+ type: 'constant',
42
+ content: '',
43
+ schema: { type: 'string' },
44
+ };
45
+
34
46
  export function DynamicValueInput({
35
47
  value,
36
48
  onChange,
@@ -43,6 +55,8 @@ export function DynamicValueInput({
43
55
  const [selectSchema, setSelectSchema] = useSelectSchema(schemaFromProps, constantProps, value);
44
56
  const includeSchema = useIncludeSchema(schemaFromProps);
45
57
 
58
+ const typeManager = useTypeManager() as JsonSchemaTypeManager;
59
+
46
60
  const renderTypeSelector = () => {
47
61
  if (schemaFromProps) {
48
62
  return <TypeSelector value={schemaFromProps} readonly={true} />;
@@ -59,24 +73,20 @@ export function DynamicValueInput({
59
73
  value={selectSchema}
60
74
  onChange={(_v) => {
61
75
  setSelectSchema(_v || { type: 'string' });
62
- let content;
63
76
 
77
+ const schema = _v || { type: 'string' };
78
+ let content = typeManager.getDefaultValue(schema);
64
79
  if (_v?.type === 'object') {
65
80
  content = '{}';
66
81
  }
67
-
68
82
  if (_v?.type === 'array') {
69
83
  content = '[]';
70
84
  }
71
85
 
72
- if (_v?.type === 'boolean') {
73
- content = false;
74
- }
75
-
76
86
  onChange({
77
87
  type: 'constant',
78
88
  content,
79
- schema: _v || { type: 'string' },
89
+ schema,
80
90
  });
81
91
  }}
82
92
  readonly={readonly}
@@ -88,10 +98,10 @@ export function DynamicValueInput({
88
98
  if (value?.type === 'ref') {
89
99
  // Display Variable Or Delete
90
100
  return (
91
- <VariableSelector
101
+ <InjectVariableSelector
92
102
  style={{ width: '100%' }}
93
103
  value={value?.content}
94
- onChange={(_v) => onChange(_v ? { type: 'ref', content: _v } : undefined)}
104
+ onChange={(_v) => onChange(_v ? { type: 'ref', content: _v } : DEFAULT_VALUE)}
95
105
  includeSchema={includeSchema}
96
106
  readonly={readonly}
97
107
  />
@@ -106,22 +116,22 @@ export function DynamicValueInput({
106
116
  onChange={(_v) => onChange({ type: 'constant', content: _v, schema: constantSchema })}
107
117
  schema={constantSchema || { type: 'string' }}
108
118
  readonly={readonly}
109
- strategies={[...(constantProps?.strategies || [])]}
110
119
  fallbackRenderer={() => (
111
- <VariableSelector
120
+ <InjectVariableSelector
112
121
  style={{ width: '100%' }}
113
- onChange={(_v) => onChange(_v ? { type: 'ref', content: _v } : undefined)}
122
+ onChange={(_v) => onChange(_v ? { type: 'ref', content: _v } : DEFAULT_VALUE)}
114
123
  includeSchema={includeSchema}
115
124
  readonly={readonly}
116
125
  />
117
126
  )}
118
127
  {...constantProps}
128
+ strategies={[...(constantProps?.strategies || [])]}
119
129
  />
120
130
  );
121
131
  };
122
132
 
123
133
  const renderTrigger = () => (
124
- <VariableSelector
134
+ <InjectVariableSelector
125
135
  style={{ width: '100%' }}
126
136
  value={value?.type === 'ref' ? value?.content : undefined}
127
137
  onChange={(_v) => onChange({ type: 'ref', content: _v })}
@@ -141,3 +151,6 @@ export function DynamicValueInput({
141
151
  </UIContainer>
142
152
  );
143
153
  }
154
+
155
+ DynamicValueInput.renderKey = 'dynamic-value-input-render-key';
156
+ export const InjectDynamicValueInput = createInjectMaterial(DynamicValueInput);
@@ -20,6 +20,8 @@ export const UIMain = styled.div`
20
20
  flex-grow: 1;
21
21
  overflow: hidden;
22
22
  min-width: 0;
23
+ border-left: 1px solid var(--semi-color-border);
24
+ border-right: 1px solid var(--semi-color-border);
23
25
 
24
26
  & .semi-tree-select,
25
27
  & .semi-input-number,
@@ -33,19 +35,27 @@ export const UIMain = styled.div`
33
35
  border: none;
34
36
  border-radius: 0;
35
37
  }
38
+
39
+ & .semi-input-textarea-wrapper {
40
+ border: none;
41
+ border-radius: 0;
42
+ }
43
+
44
+ & .semi-input-textarea {
45
+ padding: 2px 6px;
46
+ border: none;
47
+ border-radius: 0;
48
+ word-break: break-all;
49
+ }
36
50
  `;
37
51
 
38
52
  export const UIType = styled.div`
39
- border-right: 1px solid #e5e5e5;
40
-
41
53
  & .semi-button {
42
54
  border-radius: 0;
43
55
  }
44
56
  `;
45
57
 
46
58
  export const UITrigger = styled.div`
47
- border-left: 1px solid #e5e5e5;
48
-
49
59
  & .semi-button {
50
60
  border-radius: 0;
51
61
  }
@@ -10,6 +10,7 @@ export * from './batch-variable-selector';
10
10
  export * from './constant-input';
11
11
  export * from './dynamic-value-input';
12
12
  export * from './condition-row';
13
+ export * from './db-condition-row';
13
14
  export * from './batch-outputs';
14
15
  export * from './prompt-editor';
15
16
  export * from './prompt-editor-with-variables';
@@ -25,3 +26,5 @@ export * from './display-flow-value';
25
26
  export * from './display-inputs-values';
26
27
  export * from './assign-rows';
27
28
  export * from './assign-row';
29
+ export * from './blur-input';
30
+ export * from './inputs-values-tree';
@@ -5,15 +5,17 @@
5
5
 
6
6
  import React from 'react';
7
7
 
8
+ import { I18n } from '@flowgram.ai/editor';
8
9
  import { Button, IconButton } from '@douyinfe/semi-ui';
9
10
  import { IconDelete, IconPlus } from '@douyinfe/semi-icons';
10
11
 
12
+ import { IFlowConstantRefValue, IFlowValue } from '@/typings';
13
+ import { useObjectList } from '@/hooks';
14
+ import { InjectDynamicValueInput } from '@/components/dynamic-value-input';
15
+ import { BlurInput } from '@/components/blur-input';
16
+
11
17
  import { PropsType } from './types';
12
- import { DynamicValueInput } from '../dynamic-value-input';
13
- import { IFlowConstantRefValue, IFlowValue } from '../../typings';
14
- import { useObjectList } from '../../hooks';
15
18
  import { UIRow, UIRows } from './styles';
16
- import { BlurInput } from './components/blur-input';
17
19
 
18
20
  export function InputsValues({
19
21
  value,
@@ -41,9 +43,9 @@ export function InputsValues({
41
43
  size="small"
42
44
  value={item.key}
43
45
  onChange={(v) => updateKey(item.id, v)}
44
- placeholder="Input Key"
46
+ placeholder={I18n.t('Input Key')}
45
47
  />
46
- <DynamicValueInput
48
+ <InjectDynamicValueInput
47
49
  style={{ flexGrow: 1 }}
48
50
  readonly={readonly}
49
51
  value={item.value as IFlowConstantRefValue}
@@ -65,8 +67,19 @@ export function InputsValues({
65
67
  </UIRow>
66
68
  ))}
67
69
  </UIRows>
68
- <Button disabled={readonly} icon={<IconPlus />} size="small" onClick={add}>
69
- Add
70
+ <Button
71
+ disabled={readonly}
72
+ icon={<IconPlus />}
73
+ size="small"
74
+ onClick={() =>
75
+ add({
76
+ type: 'constant',
77
+ content: '',
78
+ schema: { type: 'string' },
79
+ })
80
+ }
81
+ >
82
+ {I18n.t('Add')}
70
83
  </Button>
71
84
  </div>
72
85
  );
@@ -14,6 +14,6 @@ export const UIRows = styled.div`
14
14
 
15
15
  export const UIRow = styled.div`
16
16
  display: flex;
17
- align-items: center;
17
+ align-items: flex-start;
18
18
  gap: 5px;
19
19
  `;
@@ -5,8 +5,8 @@
5
5
 
6
6
  import { IJsonSchema } from '@flowgram.ai/json-schema';
7
7
 
8
- import { Strategy } from '../constant-input/types';
9
- import { IFlowValue } from '../../typings';
8
+ import { IFlowValue } from '@/typings';
9
+ import { ConstantInputStrategy } from '@/components/constant-input';
10
10
 
11
11
  export interface PropsType {
12
12
  value?: Record<string, IFlowValue | undefined>;
@@ -16,7 +16,7 @@ export interface PropsType {
16
16
  schema?: IJsonSchema;
17
17
  style?: React.CSSProperties;
18
18
  constantProps?: {
19
- strategies?: Strategy[];
19
+ strategies?: ConstantInputStrategy[];
20
20
  [key: string]: any;
21
21
  };
22
22
  }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import { useMemo } from 'react';
7
+
8
+ import { isPlainObject } from 'lodash-es';
9
+
10
+ import { FlowValueUtils } from '@/shared';
11
+ import { useObjectList } from '@/hooks';
12
+
13
+ interface ListItem {
14
+ id: string;
15
+ key?: string;
16
+ value?: any;
17
+ }
18
+
19
+ export function useChildList(
20
+ value?: any,
21
+ onChange?: (value: any) => void
22
+ ): {
23
+ canAddField: boolean;
24
+ hasChildren: boolean;
25
+ list: ListItem[];
26
+ add: (defaultValue?: any) => void;
27
+ updateKey: (id: string, key: string) => void;
28
+ updateValue: (id: string, value: any) => void;
29
+ remove: (id: string) => void;
30
+ } {
31
+ const canAddField = useMemo(() => {
32
+ if (!isPlainObject(value)) {
33
+ return false;
34
+ }
35
+
36
+ if (FlowValueUtils.isFlowValue(value)) {
37
+ // Constant Object Value Can Add child fields
38
+ return FlowValueUtils.isConstant(value) && value?.schema?.type === 'object';
39
+ }
40
+
41
+ return true;
42
+ }, [value]);
43
+
44
+ const objectListValue = useMemo(() => {
45
+ if (isPlainObject(value)) {
46
+ if (FlowValueUtils.isFlowValue(value)) {
47
+ return undefined;
48
+ }
49
+ return value;
50
+ }
51
+ return undefined;
52
+ }, [value]);
53
+
54
+ const { list, add, updateKey, updateValue, remove } = useObjectList<any>({
55
+ value: objectListValue,
56
+ onChange: (value) => {
57
+ onChange?.(value);
58
+ },
59
+ sortIndexKey: (value) => (FlowValueUtils.isFlowValue(value) ? 'extra.index' : ''),
60
+ });
61
+
62
+ const hasChildren = useMemo(
63
+ () => canAddField && (list.length > 0 || Object.keys(objectListValue || {}).length > 0),
64
+ [canAddField, list.length, Object.keys(objectListValue || {}).length]
65
+ );
66
+
67
+ return {
68
+ canAddField,
69
+ hasChildren,
70
+ list,
71
+ add,
72
+ updateKey,
73
+ updateValue,
74
+ remove,
75
+ };
76
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import React from 'react';
7
+
8
+ import { I18n } from '@flowgram.ai/editor';
9
+ import { Button } from '@douyinfe/semi-ui';
10
+ import { IconPlus } from '@douyinfe/semi-icons';
11
+
12
+ import { FlowValueUtils } from '@/shared';
13
+ import { useObjectList } from '@/hooks';
14
+
15
+ import { PropsType } from './types';
16
+ import { UITreeItems } from './styles';
17
+ import { InputValueRow } from './row';
18
+
19
+ export function InputsValuesTree(props: PropsType) {
20
+ const { value, onChange, readonly, hasError, constantProps } = props;
21
+
22
+ const { list, updateKey, updateValue, remove, add } = useObjectList({
23
+ value,
24
+ onChange,
25
+ sortIndexKey: (value) => (FlowValueUtils.isFlowValue(value) ? 'extra.index' : ''),
26
+ });
27
+
28
+ return (
29
+ <div>
30
+ <UITreeItems>
31
+ {list.map((item) => (
32
+ <InputValueRow
33
+ key={item.id}
34
+ keyName={item.key}
35
+ value={item.value}
36
+ onUpdateKey={(key) => updateKey(item.id, key)}
37
+ onUpdateValue={(value) => updateValue(item.id, value)}
38
+ onRemove={() => remove(item.id)}
39
+ readonly={readonly}
40
+ hasError={hasError}
41
+ constantProps={constantProps}
42
+ />
43
+ ))}
44
+ </UITreeItems>
45
+ <Button
46
+ style={{ marginTop: 10, marginLeft: 16 }}
47
+ disabled={readonly}
48
+ icon={<IconPlus />}
49
+ size="small"
50
+ onClick={() => {
51
+ add({
52
+ type: 'constant',
53
+ content: '',
54
+ schema: { type: 'string' },
55
+ });
56
+ }}
57
+ >
58
+ {I18n.t('Add')}
59
+ </Button>
60
+ </div>
61
+ );
62
+ }
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import React, { useMemo, useState } from 'react';
7
+
8
+ import { I18n } from '@flowgram.ai/editor';
9
+ import { IconButton, Input } from '@douyinfe/semi-ui';
10
+ import { IconChevronDown, IconChevronRight, IconDelete } from '@douyinfe/semi-icons';
11
+
12
+ import { IFlowConstantValue } from '@/typings';
13
+ import { ConstantInputStrategy } from '@/components/constant-input';
14
+
15
+ import { PropsType } from './types';
16
+ import {
17
+ IconAddChildren,
18
+ UIActions,
19
+ UICollapseTrigger,
20
+ UICollapsible,
21
+ UIRow,
22
+ UITreeItemLeft,
23
+ UITreeItemMain,
24
+ UITreeItemRight,
25
+ UITreeItems,
26
+ } from './styles';
27
+ import { useChildList } from './hooks/use-child-list';
28
+ import { InjectDynamicValueInput } from '../dynamic-value-input';
29
+ import { BlurInput } from '../blur-input';
30
+
31
+ const AddObjectChildStrategy: ConstantInputStrategy = {
32
+ hit: (schema) => schema.type === 'object',
33
+ Renderer: () => (
34
+ <Input
35
+ size="small"
36
+ disabled
37
+ style={{ pointerEvents: 'none' }}
38
+ value={I18n.t('Configure via child fields')}
39
+ />
40
+ ),
41
+ };
42
+
43
+ export function InputValueRow(
44
+ props: {
45
+ keyName?: string;
46
+ value?: any;
47
+ onUpdateKey: (key: string) => void;
48
+ onUpdateValue: (value: any) => void;
49
+ onRemove?: () => void;
50
+ $isLast?: boolean;
51
+ $level?: number;
52
+ } & Pick<PropsType, 'constantProps' | 'hasError' | 'readonly'>
53
+ ) {
54
+ const {
55
+ keyName,
56
+ value,
57
+ $level = 0,
58
+ onUpdateKey,
59
+ onUpdateValue,
60
+ $isLast,
61
+ onRemove,
62
+ constantProps,
63
+ hasError,
64
+ readonly,
65
+ } = props;
66
+ const [collapse, setCollapse] = useState(false);
67
+
68
+ const { canAddField, hasChildren, list, add, updateKey, updateValue, remove } = useChildList(
69
+ value,
70
+ onUpdateValue
71
+ );
72
+
73
+ const strategies = useMemo(
74
+ () => [...(hasChildren ? [AddObjectChildStrategy] : []), ...(constantProps?.strategies || [])],
75
+ [hasChildren, constantProps?.strategies]
76
+ );
77
+
78
+ const flowDisplayValue = useMemo(
79
+ () =>
80
+ hasChildren
81
+ ? ({
82
+ type: 'constant',
83
+ schema: { type: 'object' },
84
+ } as IFlowConstantValue)
85
+ : value,
86
+ [hasChildren, value]
87
+ );
88
+
89
+ return (
90
+ <>
91
+ <UITreeItemLeft $isLast={$isLast} $showLine={$level > 0} $showCollapse={hasChildren}>
92
+ {hasChildren && (
93
+ <UICollapseTrigger onClick={() => setCollapse((_collapse) => !_collapse)}>
94
+ {collapse ? <IconChevronDown size="small" /> : <IconChevronRight size="small" />}
95
+ </UICollapseTrigger>
96
+ )}
97
+ </UITreeItemLeft>
98
+ <UITreeItemRight>
99
+ <UITreeItemMain>
100
+ <UIRow>
101
+ <BlurInput
102
+ style={{ width: 100, minWidth: 100, maxWidth: 100 }}
103
+ disabled={readonly}
104
+ size="small"
105
+ value={keyName}
106
+ onChange={(v) => onUpdateKey?.(v)}
107
+ placeholder={I18n.t('Input Key')}
108
+ />
109
+ <InjectDynamicValueInput
110
+ style={{ flexGrow: 1 }}
111
+ readonly={readonly}
112
+ value={flowDisplayValue}
113
+ onChange={(v) => onUpdateValue(v)}
114
+ hasError={hasError}
115
+ constantProps={{
116
+ ...constantProps,
117
+ strategies,
118
+ }}
119
+ />
120
+ <UIActions>
121
+ {canAddField && (
122
+ <IconButton
123
+ disabled={readonly}
124
+ size="small"
125
+ theme="borderless"
126
+ icon={<IconAddChildren />}
127
+ onClick={() => {
128
+ add({
129
+ type: 'constant',
130
+ content: '',
131
+ schema: { type: 'string' },
132
+ });
133
+ setCollapse(true);
134
+ }}
135
+ />
136
+ )}
137
+ <IconButton
138
+ disabled={readonly}
139
+ theme="borderless"
140
+ icon={<IconDelete size="small" />}
141
+ size="small"
142
+ onClick={() => onRemove?.()}
143
+ />
144
+ </UIActions>
145
+ </UIRow>
146
+ </UITreeItemMain>
147
+ {hasChildren && (
148
+ <UICollapsible $collapse={collapse}>
149
+ <UITreeItems $shrink={true}>
150
+ {list.map((_item, index) => (
151
+ <InputValueRow
152
+ readonly={readonly}
153
+ hasError={hasError}
154
+ constantProps={constantProps}
155
+ key={_item.id}
156
+ keyName={_item.key}
157
+ value={_item.value}
158
+ $level={$level + 1} // 传递递增的层级
159
+ onUpdateValue={(_v) => {
160
+ updateValue(_item.id, _v);
161
+ }}
162
+ onUpdateKey={(k) => {
163
+ updateKey(_item.id, k);
164
+ }}
165
+ onRemove={() => {
166
+ remove(_item.id);
167
+ }}
168
+ $isLast={index === list.length - 1}
169
+ />
170
+ ))}
171
+ </UITreeItems>
172
+ </UICollapsible>
173
+ )}
174
+ </UITreeItemRight>
175
+ </>
176
+ );
177
+ }