@flowgram.ai/form-materials 0.5.7 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/components/condition-context/hooks/use-condition.js +4 -0
- package/dist/esm/components/condition-context/hooks/use-condition.mjs +4 -0
- package/dist/types/plugins/json-schema-preset/create-type-preset-plugin.d.ts +7 -3
- package/package.json +6 -6
- package/src/components/condition-context/hooks/use-condition.tsx +4 -0
- package/src/plugins/json-schema-preset/create-type-preset-plugin.tsx +17 -12
- package/src/shared/inject-material/README.md +0 -170
- package/src/shared/inject-material/README.zh.md +0 -174
|
@@ -87,6 +87,10 @@ function useCondition({ leftSchema, operator, onClearOp, onClearRight, ruleConfi
|
|
|
87
87
|
]);
|
|
88
88
|
const prevTargetSchemaRef = (0, external_react_namespaceObject.useRef)(void 0);
|
|
89
89
|
(0, external_react_namespaceObject.useEffect)(()=>{
|
|
90
|
+
if (!prevTargetSchemaRef.current) {
|
|
91
|
+
prevTargetSchemaRef.current = targetSchema;
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
90
94
|
if (prevTargetSchemaRef.current?.type !== targetSchema?.type) onClearRight?.();
|
|
91
95
|
prevTargetSchemaRef.current = targetSchema;
|
|
92
96
|
}, [
|
|
@@ -59,6 +59,10 @@ function useCondition({ leftSchema, operator, onClearOp, onClearRight, ruleConfi
|
|
|
59
59
|
]);
|
|
60
60
|
const prevTargetSchemaRef = useRef(void 0);
|
|
61
61
|
useEffect(()=>{
|
|
62
|
+
if (!prevTargetSchemaRef.current) {
|
|
63
|
+
prevTargetSchemaRef.current = targetSchema;
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
62
66
|
if (prevTargetSchemaRef.current?.type !== targetSchema?.type) onClearRight?.();
|
|
63
67
|
prevTargetSchemaRef.current = targetSchema;
|
|
64
68
|
}, [
|
|
@@ -2,8 +2,12 @@
|
|
|
2
2
|
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
3
|
* SPDX-License-Identifier: MIT
|
|
4
4
|
*/
|
|
5
|
+
import { type PluginCreator } from '@flowgram.ai/editor';
|
|
5
6
|
import { JsonSchemaTypeRegistry } from './types';
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
type TypePresetRegistry = Partial<JsonSchemaTypeRegistry> & Pick<JsonSchemaTypeRegistry, 'type'>;
|
|
8
|
+
interface TypePresetPluginOptions {
|
|
9
|
+
types?: TypePresetRegistry[];
|
|
8
10
|
unregisterTypes?: string[];
|
|
9
|
-
}
|
|
11
|
+
}
|
|
12
|
+
export declare const createTypePresetPlugin: PluginCreator<TypePresetPluginOptions>;
|
|
13
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowgram.ai/form-materials",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"homepage": "https://flowgram.ai/",
|
|
5
5
|
"repository": "https://github.com/bytedance/flowgram.ai",
|
|
6
6
|
"license": "MIT",
|
|
@@ -67,9 +67,9 @@
|
|
|
67
67
|
"@codemirror/view": "~6.38.0",
|
|
68
68
|
"@codemirror/state": "~6.5.2",
|
|
69
69
|
"zod": "^3.24.4",
|
|
70
|
-
"@flowgram.ai/
|
|
71
|
-
"@flowgram.ai/
|
|
72
|
-
"@flowgram.ai/coze-editor": "0.
|
|
70
|
+
"@flowgram.ai/editor": "1.0.1",
|
|
71
|
+
"@flowgram.ai/json-schema": "1.0.1",
|
|
72
|
+
"@flowgram.ai/coze-editor": "1.0.1"
|
|
73
73
|
},
|
|
74
74
|
"devDependencies": {
|
|
75
75
|
"@types/lodash-es": "^4.17.12",
|
|
@@ -86,8 +86,8 @@
|
|
|
86
86
|
"cross-env": "~7.0.3",
|
|
87
87
|
"@rsbuild/plugin-react": "^1.1.1",
|
|
88
88
|
"date-fns": "~4.1.0",
|
|
89
|
-
"@flowgram.ai/eslint-config": "0.
|
|
90
|
-
"@flowgram.ai/ts-config": "0.
|
|
89
|
+
"@flowgram.ai/eslint-config": "1.0.1",
|
|
90
|
+
"@flowgram.ai/ts-config": "1.0.1"
|
|
91
91
|
},
|
|
92
92
|
"peerDependencies": {
|
|
93
93
|
"react": ">=16.8",
|
|
@@ -125,6 +125,10 @@ export function useCondition({
|
|
|
125
125
|
|
|
126
126
|
// When type of target schema updated, clear it
|
|
127
127
|
useEffect(() => {
|
|
128
|
+
if (!prevTargetSchemaRef.current) {
|
|
129
|
+
prevTargetSchemaRef.current = targetSchema;
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
128
132
|
if (prevTargetSchemaRef.current?.type !== targetSchema?.type) {
|
|
129
133
|
onClearRight?.();
|
|
130
134
|
}
|
|
@@ -8,23 +8,28 @@ import {
|
|
|
8
8
|
jsonSchemaContainerModule,
|
|
9
9
|
JsonSchemaTypeManager,
|
|
10
10
|
} from '@flowgram.ai/json-schema';
|
|
11
|
-
import { definePluginCreator } from '@flowgram.ai/editor';
|
|
11
|
+
import { definePluginCreator, type PluginCreator } from '@flowgram.ai/editor';
|
|
12
12
|
|
|
13
13
|
import { JsonSchemaTypeRegistry } from './types';
|
|
14
14
|
import { initRegistries, jsonSchemaTypePreset } from './type-definition';
|
|
15
15
|
|
|
16
16
|
initRegistries();
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
type TypePresetRegistry = Partial<JsonSchemaTypeRegistry> & Pick<JsonSchemaTypeRegistry, 'type'>;
|
|
19
|
+
|
|
20
|
+
interface TypePresetPluginOptions {
|
|
21
|
+
types?: TypePresetRegistry[];
|
|
20
22
|
unregisterTypes?: string[];
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const createTypePresetPlugin: PluginCreator<TypePresetPluginOptions> =
|
|
26
|
+
definePluginCreator<TypePresetPluginOptions>({
|
|
27
|
+
onInit(ctx, opts) {
|
|
28
|
+
const typeManager = ctx.get(BaseTypeManager) as JsonSchemaTypeManager;
|
|
29
|
+
jsonSchemaTypePreset.forEach((_type) => typeManager.register(_type));
|
|
25
30
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
});
|
|
31
|
+
opts.types?.forEach((_type) => typeManager.register(_type));
|
|
32
|
+
opts.unregisterTypes?.forEach((_type) => typeManager.unregister(_type));
|
|
33
|
+
},
|
|
34
|
+
containerModules: [jsonSchemaContainerModule],
|
|
35
|
+
});
|
|
@@ -1,170 +0,0 @@
|
|
|
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
|
-
```
|
|
@@ -1,174 +0,0 @@
|
|
|
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
|
-
```
|