@flowgram.ai/form-materials 0.3.3 → 0.3.5

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 (103) hide show
  1. package/bin/index.ts +5 -19
  2. package/bin/materials.ts +31 -89
  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/index.js +431 -505
  7. package/dist/esm/index.js.map +1 -1
  8. package/dist/index.d.mts +77 -23
  9. package/dist/index.d.ts +77 -23
  10. package/dist/index.js +657 -731
  11. package/dist/index.js.map +1 -1
  12. package/package.json +5 -5
  13. package/src/components/assign-row/index.tsx +4 -4
  14. package/src/components/assign-rows/index.tsx +1 -1
  15. package/src/components/batch-outputs/index.tsx +4 -3
  16. package/src/components/batch-outputs/types.ts +1 -1
  17. package/src/components/batch-variable-selector/index.tsx +1 -1
  18. package/src/components/code-editor-mini/index.tsx +1 -1
  19. package/src/components/condition-row/constants.ts +2 -2
  20. package/src/components/condition-row/hooks/useOp.tsx +13 -9
  21. package/src/components/condition-row/hooks/useRule.ts +8 -4
  22. package/src/components/condition-row/index.tsx +27 -10
  23. package/src/components/condition-row/types.ts +5 -7
  24. package/src/components/constant-input/index.tsx +5 -2
  25. package/src/components/constant-input/types.ts +1 -1
  26. package/src/components/display-flow-value/index.tsx +2 -2
  27. package/src/components/display-inputs-values/index.tsx +3 -2
  28. package/src/components/display-outputs/index.tsx +2 -1
  29. package/src/components/display-schema-tag/index.tsx +3 -2
  30. package/src/components/display-schema-tree/index.tsx +2 -1
  31. package/src/components/dynamic-value-input/hooks.ts +1 -1
  32. package/src/components/dynamic-value-input/index.tsx +13 -9
  33. package/src/components/inputs-values/index.tsx +7 -5
  34. package/src/components/inputs-values/types.ts +3 -3
  35. package/src/components/json-editor-with-variables/extensions/variable-tree.tsx +1 -1
  36. package/src/components/json-editor-with-variables/index.tsx +2 -1
  37. package/src/components/json-schema-editor/default-value.tsx +11 -105
  38. package/src/components/json-schema-editor/hooks.tsx +53 -94
  39. package/src/components/json-schema-editor/index.tsx +18 -12
  40. package/src/components/json-schema-editor/styles.tsx +0 -29
  41. package/src/components/prompt-editor/types.tsx +1 -1
  42. package/src/components/prompt-editor-with-inputs/extensions/inputs-tree.tsx +2 -1
  43. package/src/components/prompt-editor-with-inputs/index.tsx +3 -2
  44. package/src/components/prompt-editor-with-inputs/inputs-picker.tsx +1 -1
  45. package/src/components/prompt-editor-with-variables/extensions/variable-tree.tsx +1 -1
  46. package/src/components/prompt-editor-with-variables/index.tsx +2 -1
  47. package/src/components/type-selector/index.tsx +9 -7
  48. package/src/components/variable-selector/index.tsx +9 -5
  49. package/src/components/variable-selector/use-variable-tree.tsx +1 -1
  50. package/src/effects/auto-rename-ref/index.ts +1 -1
  51. package/src/effects/listen-ref-schema-change/index.ts +1 -1
  52. package/src/effects/listen-ref-value-change/index.ts +1 -1
  53. package/src/effects/provide-batch-input/index.ts +1 -1
  54. package/src/form-plugins/batch-outputs-plugin/index.ts +1 -1
  55. package/src/form-plugins/infer-assign-plugin/index.ts +1 -1
  56. package/src/form-plugins/infer-inputs-plugin/index.ts +1 -1
  57. package/src/plugins/json-schema-preset/type-definition/array.tsx +3 -1
  58. package/src/plugins/json-schema-preset/type-definition/boolean.tsx +4 -3
  59. package/src/plugins/json-schema-preset/type-definition/integer.tsx +2 -1
  60. package/src/plugins/json-schema-preset/type-definition/number.tsx +2 -1
  61. package/src/plugins/json-schema-preset/type-definition/object.tsx +3 -1
  62. package/src/plugins/json-schema-preset/type-definition/string.tsx +7 -1
  63. package/src/shared/index.ts +1 -0
  64. package/src/shared/inject-material/README.md +170 -0
  65. package/src/shared/inject-material/README.zh.md +174 -0
  66. package/src/shared/inject-material/index.tsx +87 -0
  67. package/src/components/assign-row/config.json +0 -11
  68. package/src/components/assign-rows/config.json +0 -11
  69. package/src/components/batch-outputs/config.json +0 -13
  70. package/src/components/batch-variable-selector/config.json +0 -9
  71. package/src/components/code-editor/config.json +0 -10
  72. package/src/components/code-editor-mini/config.json +0 -7
  73. package/src/components/condition-row/config.json +0 -13
  74. package/src/components/constant-input/config.json +0 -9
  75. package/src/components/display-flow-value/config.json +0 -8
  76. package/src/components/display-inputs-values/config.json +0 -9
  77. package/src/components/display-outputs/config.json +0 -10
  78. package/src/components/display-schema-tag/config.json +0 -10
  79. package/src/components/display-schema-tree/config.json +0 -11
  80. package/src/components/dynamic-value-input/config.json +0 -14
  81. package/src/components/inputs-values/config.json +0 -13
  82. package/src/components/json-editor-with-variables/config.json +0 -13
  83. package/src/components/json-schema-editor/config.json +0 -13
  84. package/src/components/json-schema-editor/utils.ts +0 -29
  85. package/src/components/prompt-editor/config.json +0 -9
  86. package/src/components/prompt-editor-with-inputs/config.json +0 -13
  87. package/src/components/prompt-editor-with-variables/config.json +0 -13
  88. package/src/components/type-selector/config.json +0 -9
  89. package/src/components/variable-selector/config.json +0 -9
  90. package/src/effects/auto-rename-ref/config.json +0 -5
  91. package/src/effects/listen-ref-schema-change/config.json +0 -10
  92. package/src/effects/listen-ref-value-change/config.json +0 -9
  93. package/src/effects/provide-batch-input/config.json +0 -5
  94. package/src/effects/provide-json-schema-outputs/config.json +0 -7
  95. package/src/effects/sync-variable-title/config.json +0 -5
  96. package/src/effects/validate-when-variable-sync/config.json +0 -5
  97. package/src/form-plugins/batch-outputs-plugin/config.json +0 -7
  98. package/src/form-plugins/infer-assign-plugin/config.json +0 -7
  99. package/src/form-plugins/infer-inputs-plugin/config.json +0 -9
  100. package/src/hooks/use-object-list/config.json +0 -8
  101. package/src/shared/format-legacy-refs/config.json +0 -5
  102. package/src/typings/flow-value/config.json +0 -7
  103. package/src/validate/validate-flow-value/config.json +0 -7
@@ -13,7 +13,7 @@ import {
13
13
  getNodeScope,
14
14
  } from '@flowgram.ai/editor';
15
15
 
16
- import { IFlowRefValue } from '../../typings';
16
+ import { IFlowRefValue } from '@/typings';
17
17
 
18
18
  /**
19
19
  * Example:
@@ -12,7 +12,7 @@ import {
12
12
  getNodeScope,
13
13
  } from '@flowgram.ai/editor';
14
14
 
15
- import { IFlowRefValue } from '../../typings';
15
+ import { IFlowRefValue } from '@/typings';
16
16
 
17
17
  /**
18
18
  * Example:
@@ -11,7 +11,7 @@ import {
11
11
  getNodeForm,
12
12
  } from '@flowgram.ai/editor';
13
13
 
14
- import { IFlowRefValue } from '../../typings';
14
+ import { IFlowRefValue } from '@/typings';
15
15
 
16
16
  export const provideBatchInputEffect: EffectOptions[] = createEffectFromVariableProvider({
17
17
  private: true,
@@ -17,7 +17,7 @@ import {
17
17
  FlowNodeScopeType,
18
18
  } from '@flowgram.ai/editor';
19
19
 
20
- import { IFlowRefValue } from '../../typings';
20
+ import { IFlowRefValue } from '@/typings';
21
21
 
22
22
  export const provideBatchOutputsEffect: EffectOptions[] = createEffectFromVariableProvider({
23
23
  parse: (value: Record<string, IFlowRefValue>, ctx) => [
@@ -14,7 +14,7 @@ import {
14
14
  getNodeScope,
15
15
  } from '@flowgram.ai/editor';
16
16
 
17
- import { IFlowRefValue, IFlowValue } from '../../typings';
17
+ import { IFlowRefValue, IFlowValue } from '@/typings';
18
18
 
19
19
  type AssignValueType =
20
20
  | {
@@ -12,7 +12,7 @@ import {
12
12
  Scope,
13
13
  } from '@flowgram.ai/editor';
14
14
 
15
- import { IFlowConstantValue, IFlowRefValue, IFlowTemplateValue } from '../../typings';
15
+ import { IFlowConstantValue, IFlowRefValue, IFlowTemplateValue } from '@/typings';
16
16
 
17
17
  interface InputConfig {
18
18
  sourceKey: string;
@@ -6,6 +6,8 @@
6
6
  /* eslint-disable react/prop-types */
7
7
  import React from 'react';
8
8
 
9
+ import { I18n } from '@flowgram.ai/editor';
10
+
9
11
  import { CodeEditorMini } from '@/components/code-editor-mini';
10
12
 
11
13
  import { type JsonSchemaTypeRegistry } from '../manager';
@@ -17,7 +19,7 @@ export const arrayRegistry: Partial<JsonSchemaTypeRegistry> = {
17
19
  value={props.value}
18
20
  languageId="json"
19
21
  onChange={(v) => props.onChange?.(v)}
20
- placeholder="Please Input Array"
22
+ placeholder={I18n.t('Please Input Array')}
21
23
  readonly={props.readonly}
22
24
  />
23
25
  ),
@@ -6,6 +6,7 @@
6
6
  /* eslint-disable react/prop-types */
7
7
  import React from 'react';
8
8
 
9
+ import { I18n } from '@flowgram.ai/editor';
9
10
  import { Select } from '@douyinfe/semi-ui';
10
11
 
11
12
  import { type JsonSchemaTypeRegistry } from '../manager';
@@ -16,12 +17,12 @@ export const booleanRegistry: Partial<JsonSchemaTypeRegistry> = {
16
17
  const { value, onChange, ...rest } = props;
17
18
  return (
18
19
  <Select
19
- placeholder="Please Select Boolean"
20
+ placeholder={I18n.t('Please Select Boolean')}
20
21
  size="small"
21
22
  disabled={props.readonly}
22
23
  optionList={[
23
- { label: 'True', value: 1 },
24
- { label: 'False', value: 0 },
24
+ { label: I18n.t('True'), value: 1 },
25
+ { label: I18n.t('False'), value: 0 },
25
26
  ]}
26
27
  value={value ? 1 : 0}
27
28
  onChange={(value) => onChange?.(!!value)}
@@ -6,6 +6,7 @@
6
6
  /* eslint-disable react/prop-types */
7
7
  import React from 'react';
8
8
 
9
+ import { I18n } from '@flowgram.ai/editor';
9
10
  import { InputNumber } from '@douyinfe/semi-ui';
10
11
 
11
12
  import { type JsonSchemaTypeRegistry } from '../manager';
@@ -14,7 +15,7 @@ export const integerRegistry: Partial<JsonSchemaTypeRegistry> = {
14
15
  type: 'integer',
15
16
  ConstantRenderer: (props) => (
16
17
  <InputNumber
17
- placeholder="Please Input Integer"
18
+ placeholder={I18n.t('Please Input Integer')}
18
19
  size="small"
19
20
  disabled={props.readonly}
20
21
  precision={0}
@@ -6,6 +6,7 @@
6
6
  /* eslint-disable react/prop-types */
7
7
  import React from 'react';
8
8
 
9
+ import { I18n } from '@flowgram.ai/editor';
9
10
  import { InputNumber } from '@douyinfe/semi-ui';
10
11
 
11
12
  import { type JsonSchemaTypeRegistry } from '../manager';
@@ -14,7 +15,7 @@ export const numberRegistry: Partial<JsonSchemaTypeRegistry> = {
14
15
  type: 'number',
15
16
  ConstantRenderer: (props) => (
16
17
  <InputNumber
17
- placeholder="Please Input Number"
18
+ placeholder={I18n.t('Please Input Number')}
18
19
  size="small"
19
20
  disabled={props.readonly}
20
21
  hideButtons
@@ -6,6 +6,8 @@
6
6
  /* eslint-disable react/prop-types */
7
7
  import React from 'react';
8
8
 
9
+ import { I18n } from '@flowgram.ai/editor';
10
+
9
11
  import { CodeEditorMini } from '@/components/code-editor-mini';
10
12
 
11
13
  import { type JsonSchemaTypeRegistry } from '../manager';
@@ -17,7 +19,7 @@ export const objectRegistry: Partial<JsonSchemaTypeRegistry> = {
17
19
  value={props.value}
18
20
  onChange={(v) => props.onChange?.(v)}
19
21
  languageId="json"
20
- placeholder="Please Input Object"
22
+ placeholder={I18n.t('Please Input Object')}
21
23
  readonly={props.readonly}
22
24
  />
23
25
  ),
@@ -6,6 +6,7 @@
6
6
  /* eslint-disable react/prop-types */
7
7
  import React from 'react';
8
8
 
9
+ import { I18n } from '@flowgram.ai/editor';
9
10
  import { Input } from '@douyinfe/semi-ui';
10
11
 
11
12
  import { type JsonSchemaTypeRegistry } from '../manager';
@@ -13,6 +14,11 @@ import { type JsonSchemaTypeRegistry } from '../manager';
13
14
  export const stringRegistry: Partial<JsonSchemaTypeRegistry> = {
14
15
  type: 'string',
15
16
  ConstantRenderer: (props) => (
16
- <Input placeholder="Please Input String" size="small" disabled={props.readonly} {...props} />
17
+ <Input
18
+ placeholder={I18n.t('Please Input String')}
19
+ size="small"
20
+ disabled={props.readonly}
21
+ {...props}
22
+ />
17
23
  ),
18
24
  };
@@ -4,3 +4,4 @@
4
4
  */
5
5
 
6
6
  export * from './format-legacy-refs';
7
+ export * from './inject-material';
@@ -0,0 +1,170 @@
1
+ # InjectMaterial Component
2
+
3
+ A material component wrapper with dependency injection support for implementing dynamic component replacement mechanisms.
4
+
5
+ ## Why Dependency Injection Matters
6
+
7
+ ### ❌ Tight Coupling: Traditional Dependency Issues
8
+
9
+ ```mermaid
10
+ graph TD
11
+ A[Material A] --> B[Material B]
12
+ B --> D[Material D]
13
+ C[Material C] --> D
14
+
15
+ style D fill:#ff4757
16
+ style A fill:#ffa502
17
+ style B fill:#ffa502
18
+ style C fill:#ffa502
19
+
20
+ note["💥 Problem: D changes require modifications to A, B, C"]
21
+ ```
22
+
23
+ **Issues:** Chain reactions, high maintenance costs
24
+
25
+ ### ✅ Decoupling: Dependency Injection Solution
26
+
27
+ ```mermaid
28
+ graph TD
29
+ A[Material A] --> RenderKey[Material D RenderKey]
30
+ B[Material B] --> RenderKey
31
+ C[Material C] --> RenderKey
32
+
33
+ RenderKey -.-> BaseD[Origin D]
34
+ CustomD[Custom D] -.-> RenderKey
35
+
36
+ style RenderKey fill:#5f27cd
37
+ style BaseD fill:#2ed573
38
+ style CustomD fill:#26d0ce
39
+ style A fill:#a55eea
40
+ style B fill:#a55eea
41
+ style C fill:#a55eea
42
+
43
+ note2["✅ A, B, C depend on abstract interface, decoupled from D"]
44
+ ```
45
+
46
+ **Benefits:** Hot-swapping, parallel development, version compatibility
47
+
48
+ ## Features
49
+
50
+ - 🔧 **Dependency Injection**: Support dynamic component replacement via FlowRendererRegistry
51
+ - 🔄 **Smart Fallback**: Automatically use default component when no custom component is registered
52
+ - 🎯 **Type Safety**: Full TypeScript type inference support
53
+ - 📦 **Zero Configuration**: Works out of the box without additional setup
54
+
55
+ ## Usage
56
+
57
+ ### 1. Create Injectable Material Component
58
+
59
+ ```tsx
60
+ import { createInjectMaterial } from '@flowgram.ai/form-materials';
61
+ import { VariableSelector } from './VariableSelector';
62
+
63
+ // Create injectable material wrapper component
64
+ const InjectVariableSelector = createInjectMaterial(VariableSelector);
65
+
66
+ // Now you can use it like a regular component
67
+ function MyComponent() {
68
+ return <InjectVariableSelector value={value} onChange={handleChange} />;
69
+ }
70
+ ```
71
+
72
+ ### 2. Register Custom Components
73
+
74
+ Configure custom renderer in `use-editor-props.tsx`:
75
+
76
+ ```tsx
77
+ import { useEditorProps } from '@flowgram.ai/editor';
78
+ import { YourCustomVariableSelector } from './YourCustomVariableSelector';
79
+ import { VariableSelector } from '@flowgram.ai/form-materials';
80
+
81
+ function useCustomEditorProps() {
82
+ const editorProps = useEditorProps({
83
+ materials: {
84
+ components: {
85
+ // Use component's renderKey or component name as key
86
+ [VariableSelector.renderKey]: YourCustomVariableSelector,
87
+ [TypeSelector.renderKey]: YourCustomTypeSelector,
88
+ }
89
+ }
90
+ });
91
+
92
+ return editorProps;
93
+ }
94
+ ```
95
+
96
+ ### 3. Use Custom renderKey
97
+
98
+ If your component requires a specific renderKey:
99
+
100
+ ```tsx
101
+ const InjectCustomComponent = createInjectMaterial(MyComponent, {
102
+ renderKey: 'my-custom-key'
103
+ });
104
+
105
+ // When registering
106
+ {
107
+ materials: {
108
+ components: {
109
+ 'my-custom-key': MyCustomRenderer
110
+ }
111
+ }
112
+ }
113
+ ```
114
+
115
+ ## Sequence Diagram
116
+
117
+ Complete component registration and rendering sequence diagram:
118
+
119
+ ```mermaid
120
+ sequenceDiagram
121
+ participant App as Application
122
+ participant Editor as use-editor-props
123
+ participant Registry as FlowRendererRegistry
124
+ participant Inject as InjectMaterial
125
+ participant Default as Default Component
126
+ participant Custom as Custom Component
127
+
128
+ Note over App,Custom: Component Registration Phase
129
+ App->>Editor: Call use-editor-props()
130
+ Editor->>Editor: Configure materials.components
131
+ Editor->>Registry: Register component to FlowRendererRegistry
132
+ Registry->>Registry: Store mapping relationship
133
+ Registry-->>App: Registration complete
134
+
135
+ Note over App,Custom: Component Rendering Phase
136
+ App->>Inject: Render InjectMaterial component
137
+ Inject->>Registry: Query renderer (getRendererComponent)
138
+
139
+ alt Custom renderer exists
140
+ Registry-->>Inject: Return custom React component
141
+ Inject->>Custom: Render with custom component
142
+ Custom-->>App: Render custom UI
143
+ else No custom renderer
144
+ Registry-->>Inject: Return null or type mismatch
145
+ Inject->>Default: Render with default component
146
+ Default-->>App: Render default UI
147
+ end
148
+ ```
149
+
150
+ ## Render Key Priority
151
+
152
+ Component render key determination follows this priority order:
153
+
154
+ 1. `params.renderKey` (second parameter of createInjectMaterial)
155
+ 2. `Component.renderKey` (component's own renderKey property)
156
+ 3. `Component.name` (component's display name)
157
+ 4. Empty string (final fallback)
158
+
159
+ ## Type Definition
160
+
161
+ ```typescript
162
+ interface CreateInjectMaterialOptions {
163
+ renderKey?: string;
164
+ }
165
+
166
+ function createInjectMaterial<Props>(
167
+ Component: React.FC<Props> & { renderKey?: string },
168
+ params?: CreateInjectMaterialOptions
169
+ ): React.FC<Props>
170
+ ```
@@ -0,0 +1,174 @@
1
+ # InjectMaterial 组件
2
+
3
+ 一个支持依赖注入的 Material 组件包装器,用于实现动态组件替换机制。
4
+
5
+ ## 为什么需要依赖注入
6
+
7
+ ### ❌ 紧耦合:传统依赖问题
8
+
9
+ ```mermaid
10
+ graph TD
11
+ A[Material A] --> B[Material B]
12
+ B --> D[Material D]
13
+ C[Material C] --> D
14
+
15
+ style D fill:#ff4757
16
+ style A fill:#ffa502
17
+ style B fill:#ffa502
18
+ style C fill:#ffa502
19
+
20
+ note["💥 问题:D变更导致A、B、C全部需要修改"]
21
+ ```
22
+
23
+ **问题:** 连锁反应、高维护成本
24
+
25
+ ### ✅ 解耦:依赖注入方案
26
+
27
+ ```mermaid
28
+ graph TD
29
+ A[Material A] --> RenderKey[Material D RenderKey]
30
+ B[Material B] --> RenderKey
31
+ C[Material C] --> RenderKey
32
+
33
+ RenderKey -.-> BaseD[Origin D]
34
+ CustomD[Custom D] -.-> RenderKey
35
+
36
+ style RenderKey fill:#5f27cd
37
+ style BaseD fill:#2ed573
38
+ style CustomD fill:#26d0ce
39
+ style A fill:#a55eea
40
+ style B fill:#a55eea
41
+ style C fill:#a55eea
42
+
43
+ note2["✅ A、B、C依赖抽象接口,与D实现解耦"]
44
+ ```
45
+
46
+ **优势:** 热插拔、并行开发、版本兼容
47
+
48
+ ## 特性
49
+
50
+ - 🔧 **依赖注入**:通过 FlowRendererRegistry 支持动态组件替换
51
+ - 🔄 **智能回退**:当没有注册自定义组件时自动使用默认组件
52
+ - 🎯 **类型安全**:完整的 TypeScript 类型推断支持
53
+ - 📦 **零配置**:开箱即用,无需额外设置
54
+
55
+ ## 安装
56
+
57
+ 该组件是 `@flowgram.ai/form-materials` 包的一部分,无需单独安装。
58
+
59
+ ## 使用
60
+
61
+ ### 1. 创建可注入的 Material 组件件
62
+
63
+ ```tsx
64
+ import { createInjectMaterial } from '@flowgram.ai/form-materials';
65
+ import { VariableSelector } from './VariableSelector';
66
+
67
+ // 创建可注入的Material包装组件
68
+ const InjectVariableSelector = createInjectMaterial(VariableSelector);
69
+
70
+ // 现在你可以像使用普通组件一样使用它
71
+ function MyComponent() {
72
+ return <InjectVariableSelector value={value} onChange={handleChange} />;
73
+ }
74
+ ```
75
+
76
+ ### 2. 注册自定义组件
77
+
78
+ 在 `use-editor-props.tsx` 中配置自定义渲染器:
79
+
80
+ ```tsx
81
+ import { useEditorProps } from '@flowgram.ai/editor';
82
+ import { YourCustomVariableSelector } from './YourCustomVariableSelector';
83
+ import { VariableSelector } from '@flowgram.ai/form-materials';
84
+
85
+ function useCustomEditorProps() {
86
+ const editorProps = useEditorProps({
87
+ materials: {
88
+ components: {
89
+ // 使用组件的 renderKey 或组件名称作为键
90
+ [VariableSelector.renderKey]: YourCustomVariableSelector,
91
+ [TypeSelector.renderKey]: YourCustomTypeSelector,
92
+ }
93
+ }
94
+ });
95
+
96
+ return editorProps;
97
+ }
98
+ ```
99
+
100
+ ### 3. 使用自定义 renderKey
101
+
102
+ 如果你的组件需要特定的 renderKey:
103
+
104
+ ```tsx
105
+ const InjectCustomComponent = createInjectMaterial(MyComponent, {
106
+ renderKey: 'my-custom-key'
107
+ });
108
+
109
+ // 注册时
110
+ {
111
+ materials: {
112
+ components: {
113
+ 'my-custom-key': MyCustomRenderer
114
+ }
115
+ }
116
+ }
117
+ ```
118
+
119
+ ## 时序图
120
+
121
+ 完整的组件注册和渲染时序图:
122
+
123
+ ```mermaid
124
+ sequenceDiagram
125
+ participant App as 应用程序
126
+ participant Editor as use-editor-props
127
+ participant Registry as FlowRendererRegistry
128
+ participant Inject as InjectMaterial
129
+ participant Default as 默认组件
130
+ participant Custom as 自定义组件
131
+
132
+ Note over App,Custom: 组件注册阶段
133
+ App->>Editor: 调用 use-editor-props()
134
+ Editor->>Editor: 配置 materials.components
135
+ Editor->>Registry: 向 FlowRendererRegistry 注册组件
136
+ Registry->>Registry: 存储映射关系
137
+ Registry-->>App: 注册完成
138
+
139
+ Note over App,Custom: 组件渲染阶段
140
+ App->>Inject: 渲染 InjectMaterial 组件
141
+ Inject->>Registry: 查询渲染器 (getRendererComponent)
142
+
143
+ alt 存在自定义渲染器
144
+ Registry-->>Inject: 返回自定义 React 组件
145
+ Inject->>Custom: 使用自定义组件渲染
146
+ Custom-->>App: 渲染自定义 UI
147
+ else 无自定义渲染器
148
+ Registry-->>Inject: 返回 null 或类型不匹配
149
+ Inject->>Default: 使用默认组件渲染
150
+ Default-->>App: 渲染默认 UI
151
+ end
152
+ ```
153
+
154
+ ## 渲染键优先级
155
+
156
+ 组件渲染键的确定遵循以下优先级顺序:
157
+
158
+ 1. `params.renderKey` (createInjectMaterial 的第二个参数)
159
+ 2. `Component.renderKey` (组件自身的 renderKey 属性)
160
+ 3. `Component.name` (组件的显示名称)
161
+ 4. 空字符串 (最终回退)
162
+
163
+ ## 类型定义
164
+
165
+ ```typescript
166
+ interface CreateInjectMaterialOptions {
167
+ renderKey?: string;
168
+ }
169
+
170
+ function createInjectMaterial<Props>(
171
+ Component: React.FC<Props> & { renderKey?: string },
172
+ params?: CreateInjectMaterialOptions
173
+ ): React.FC<Props>
174
+ ```
@@ -0,0 +1,87 @@
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 {
9
+ FlowRendererComponentType,
10
+ FlowRendererRegistry,
11
+ usePlaygroundContainer,
12
+ } from '@flowgram.ai/editor';
13
+
14
+ /**
15
+ * Creates a material component wrapper with dependency injection support
16
+ *
17
+ * This Higher-Order Component (HOC) implements a dynamic component replacement mechanism
18
+ * for material components. It automatically checks if a custom renderer is registered
19
+ * in the editor context, using the injected component if available, otherwise
20
+ * falling back to the default component.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * // 1.Create an injectable material component
25
+ * const InjectVariableSelector = createInjectMaterial(VariableSelector)
26
+ *
27
+ * // 2. Register custom components in editor
28
+ * // Configure in use-editor-props.tsx:
29
+ * const editorProps = {
30
+ * materials: {
31
+ * components: {
32
+ * [VariableSelector.renderKey]: YourCustomVariableSelector
33
+ * }
34
+ * }
35
+ * }
36
+ * ```
37
+ *
38
+ * @description
39
+ * Data flow explanation:
40
+ * - Register components to FlowRendererRegistry in use-editor-props
41
+ * - InjectMaterial reads renderers from FlowRendererRegistry
42
+ * - If registered renderer exists and type is REACT, use injected component
43
+ * - If not exists or type mismatch, fallback to default component
44
+ *
45
+ * @param Component - Default React component
46
+ * @param params - Optional parameters
47
+ * @param params.renderKey - Custom render key name, highest priority
48
+ * @returns Wrapper component with dependency injection support
49
+ */
50
+ export function createInjectMaterial<Props>(
51
+ Component: React.FC<Props> & { renderKey?: string },
52
+ params?: {
53
+ renderKey?: string;
54
+ }
55
+ ): React.FC<Props> {
56
+ const InjectComponent: React.FC<Props> = (props) => {
57
+ const container = usePlaygroundContainer();
58
+
59
+ // Check if renderer registry is bound in container
60
+ if (!container?.isBound(FlowRendererRegistry)) {
61
+ // If no registry, use default component directly
62
+ return React.createElement(Component as (props?: any) => any, { ...props });
63
+ }
64
+
65
+ // Get renderer registry instance
66
+ const rendererRegistry = container.get(FlowRendererRegistry);
67
+
68
+ // Determine render key: prioritize param specified, then component renderKey, finally component name
69
+ const renderKey = params?.renderKey || Component.renderKey || Component.name || '';
70
+
71
+ // Get corresponding renderer from registry
72
+ const renderer = rendererRegistry.tryToGetRendererComponent(renderKey);
73
+
74
+ // Check if renderer exists and type is React component
75
+ if (renderer?.type !== FlowRendererComponentType.REACT) {
76
+ // If no suitable renderer found, fallback to default component
77
+ return React.createElement(Component as (props?: any) => any, { ...props });
78
+ }
79
+
80
+ // Render using injected React component
81
+ return React.createElement(renderer.renderer, {
82
+ ...props,
83
+ });
84
+ };
85
+
86
+ return InjectComponent;
87
+ }
@@ -1,11 +0,0 @@
1
- {
2
- "name": "assign-row",
3
- "depMaterials": [
4
- "flow-value",
5
- "dynamic-value-input",
6
- "variable-selector"
7
- ],
8
- "depPackages": [
9
- "@douyinfe/semi-ui"
10
- ]
11
- }
@@ -1,11 +0,0 @@
1
- {
2
- "name": "assign-rows",
3
- "depMaterials": [
4
- "flow-value",
5
- "dynamic-value-input",
6
- "variable-selector"
7
- ],
8
- "depPackages": [
9
- "@douyinfe/semi-ui"
10
- ]
11
- }
@@ -1,13 +0,0 @@
1
- {
2
- "name": "batch-outputs",
3
- "depMaterials": [
4
- "flow-value",
5
- "variable-selector",
6
- "use-object-list"
7
- ],
8
- "depPackages": [
9
- "@douyinfe/semi-ui",
10
- "@douyinfe/semi-icons",
11
- "styled-components"
12
- ]
13
- }
@@ -1,9 +0,0 @@
1
- {
2
- "name": "batch-variable-selector",
3
- "depMaterials": [
4
- "variable-selector"
5
- ],
6
- "depPackages": [
7
- "@flowgram.ai/json-schema"
8
- ]
9
- }
@@ -1,10 +0,0 @@
1
- {
2
- "name": "code-editor",
3
- "depMaterials": [],
4
- "depPackages": [
5
- "@coze-editor/editor@0.1.0-alpha.879fbb",
6
- "@codemirror/view",
7
- "@codemirror/state",
8
- "typescript"
9
- ]
10
- }
@@ -1,7 +0,0 @@
1
- {
2
- "name": "code-editor-mini",
3
- "depMaterials": [
4
- "code-editor"
5
- ],
6
- "depPackages": []
7
- }