@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.
@@ -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
- export declare const createTypePresetPlugin: import("@flowgram.ai/core").PluginCreator<{
7
- types?: Partial<JsonSchemaTypeRegistry> & Pick<JsonSchemaTypeRegistry, "type">[];
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.5.7",
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/json-schema": "0.5.7",
71
- "@flowgram.ai/editor": "0.5.7",
72
- "@flowgram.ai/coze-editor": "0.5.7"
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.5.7",
90
- "@flowgram.ai/ts-config": "0.5.7"
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
- export const createTypePresetPlugin = definePluginCreator<{
19
- types?: Partial<JsonSchemaTypeRegistry> & Pick<JsonSchemaTypeRegistry, 'type'>[];
18
+ type TypePresetRegistry = Partial<JsonSchemaTypeRegistry> & Pick<JsonSchemaTypeRegistry, 'type'>;
19
+
20
+ interface TypePresetPluginOptions {
21
+ types?: TypePresetRegistry[];
20
22
  unregisterTypes?: string[];
21
- }>({
22
- onInit(ctx, opts) {
23
- const typeManager = ctx.get(BaseTypeManager) as JsonSchemaTypeManager;
24
- jsonSchemaTypePreset.forEach((_type) => typeManager.register(_type));
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
- opts.types?.forEach((_type) => typeManager.register(_type));
27
- opts.unregisterTypes?.forEach((_type) => typeManager.unregister(_type));
28
- },
29
- containerModules: [jsonSchemaContainerModule],
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
- ```