@flowgram.ai/form-materials 0.1.0-alpha.11 → 0.1.0-alpha.13
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/bin/index.ts +14 -22
- package/bin/materials.ts +41 -90
- package/bin/project.ts +4 -0
- package/bin/utils/import.ts +127 -0
- package/bin/utils/traverse-file.ts +60 -0
- package/dist/esm/index.js +2073 -1601
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +392 -131
- package/dist/index.d.ts +392 -131
- package/dist/index.js +2175 -1710
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
- package/src/components/assign-row/components/blur-input.tsx +27 -0
- package/src/components/assign-row/index.tsx +84 -0
- package/src/components/assign-row/types.ts +25 -0
- package/src/components/assign-rows/index.tsx +59 -0
- package/src/components/batch-outputs/index.tsx +7 -14
- package/src/components/batch-outputs/types.ts +1 -1
- package/src/components/batch-variable-selector/index.tsx +2 -2
- package/src/components/code-editor/index.tsx +7 -0
- package/src/components/code-editor/language-features.ts +22 -1
- package/src/components/code-editor/theme/light.ts +1 -1
- package/src/components/code-editor-mini/index.tsx +31 -0
- package/src/components/condition-row/constants.ts +8 -10
- package/src/components/condition-row/hooks/useOp.tsx +15 -9
- package/src/components/condition-row/hooks/useRule.ts +9 -5
- package/src/components/condition-row/index.tsx +28 -10
- package/src/components/condition-row/types.ts +5 -5
- package/src/components/constant-input/index.tsx +20 -61
- package/src/components/constant-input/types.ts +6 -9
- package/src/components/display-flow-value/index.tsx +59 -0
- package/src/components/display-inputs-values/index.tsx +28 -0
- package/src/components/display-inputs-values/styles.ts +12 -0
- package/src/components/display-outputs/index.tsx +65 -0
- package/src/components/display-outputs/styles.ts +12 -0
- package/src/components/display-schema-tag/index.tsx +45 -0
- package/src/components/display-schema-tag/styles.ts +28 -0
- package/src/components/display-schema-tree/index.tsx +75 -0
- package/src/components/display-schema-tree/styles.tsx +90 -0
- package/src/components/dynamic-value-input/hooks.ts +53 -0
- package/src/components/dynamic-value-input/index.tsx +74 -19
- package/src/components/dynamic-value-input/styles.tsx +28 -2
- package/src/components/index.ts +9 -0
- package/src/components/inputs-values/components/blur-input.tsx +27 -0
- package/src/components/inputs-values/index.tsx +75 -0
- package/src/components/inputs-values/styles.tsx +19 -0
- package/src/components/inputs-values/types.ts +22 -0
- package/src/components/json-editor-with-variables/extensions/variable-tree.tsx +1 -1
- package/src/components/json-editor-with-variables/index.tsx +2 -1
- package/src/components/json-schema-editor/default-value.tsx +12 -106
- package/src/components/json-schema-editor/hooks.tsx +53 -94
- package/src/components/json-schema-editor/index.tsx +32 -13
- package/src/components/json-schema-editor/styles.tsx +0 -29
- package/src/components/json-schema-editor/types.ts +1 -1
- package/src/components/prompt-editor/types.tsx +1 -1
- package/src/components/prompt-editor-with-inputs/extensions/inputs-tree.tsx +2 -1
- package/src/components/prompt-editor-with-inputs/index.tsx +3 -2
- package/src/components/prompt-editor-with-inputs/inputs-picker.tsx +2 -2
- package/src/components/prompt-editor-with-variables/extensions/variable-tag.tsx +6 -3
- package/src/components/prompt-editor-with-variables/extensions/variable-tree.tsx +1 -1
- package/src/components/prompt-editor-with-variables/index.tsx +2 -1
- package/src/components/type-selector/index.tsx +58 -13
- package/src/components/variable-selector/index.tsx +42 -17
- package/src/components/variable-selector/styles.tsx +18 -8
- package/src/components/variable-selector/use-variable-tree.tsx +19 -22
- package/src/effects/auto-rename-ref/index.ts +1 -1
- package/src/effects/index.ts +3 -1
- package/src/effects/listen-ref-schema-change/index.ts +56 -0
- package/src/effects/listen-ref-value-change/index.ts +53 -0
- package/src/effects/provide-batch-input/index.ts +1 -1
- package/src/effects/provide-json-schema-outputs/index.ts +1 -3
- package/src/effects/sync-variable-title/index.ts +1 -0
- package/src/effects/validate-when-variable-sync/index.ts +35 -0
- package/src/form-plugins/batch-outputs-plugin/index.ts +1 -1
- package/src/form-plugins/index.ts +3 -1
- package/src/form-plugins/infer-assign-plugin/index.ts +90 -0
- package/src/form-plugins/infer-inputs-plugin/index.ts +108 -0
- package/src/hooks/index.tsx +6 -0
- package/src/hooks/use-object-list/index.tsx +136 -0
- package/src/index.ts +3 -1
- package/src/{utils/format-legacy-refs → plugins/disable-declaration-plugin}/config.json +1 -1
- package/src/plugins/disable-declaration-plugin/create-disable-declaration-plugin.ts +31 -0
- package/src/plugins/disable-declaration-plugin/index.tsx +6 -0
- package/src/plugins/index.ts +7 -0
- package/src/plugins/json-schema-preset/config.json +9 -0
- package/src/plugins/json-schema-preset/create-type-preset-plugin.tsx +28 -0
- package/src/plugins/json-schema-preset/index.tsx +41 -0
- package/src/plugins/json-schema-preset/manager.ts +18 -0
- package/src/plugins/json-schema-preset/type-definition/array.tsx +26 -0
- package/src/plugins/json-schema-preset/type-definition/boolean.tsx +33 -0
- package/src/plugins/json-schema-preset/type-definition/index.tsx +24 -0
- package/src/plugins/json-schema-preset/type-definition/integer.tsx +25 -0
- package/src/plugins/json-schema-preset/type-definition/number.tsx +25 -0
- package/src/plugins/json-schema-preset/type-definition/object.tsx +26 -0
- package/src/plugins/json-schema-preset/type-definition/string.tsx +24 -0
- package/src/{utils → shared}/index.ts +1 -1
- package/src/shared/inject-material/README.md +170 -0
- package/src/shared/inject-material/README.zh.md +174 -0
- package/src/shared/inject-material/index.tsx +87 -0
- package/src/typings/flow-value/index.ts +11 -0
- package/src/typings/index.ts +0 -1
- package/src/validate/index.tsx +6 -0
- package/src/validate/validate-flow-value/index.tsx +73 -0
- package/src/components/batch-outputs/config.json +0 -12
- package/src/components/batch-outputs/use-list.ts +0 -86
- package/src/components/batch-variable-selector/config.json +0 -5
- package/src/components/code-editor/config.json +0 -10
- package/src/components/condition-row/config.json +0 -5
- package/src/components/constant-input/config.json +0 -6
- package/src/components/dynamic-value-input/config.json +0 -5
- package/src/components/json-editor-with-variables/config.json +0 -13
- package/src/components/json-schema-editor/config.json +0 -13
- package/src/components/json-schema-editor/utils.ts +0 -29
- package/src/components/prompt-editor/config.json +0 -9
- package/src/components/prompt-editor-with-inputs/config.json +0 -13
- package/src/components/prompt-editor-with-variables/config.json +0 -13
- package/src/components/type-selector/config.json +0 -5
- package/src/components/type-selector/constants.tsx +0 -364
- package/src/components/variable-selector/config.json +0 -5
- package/src/effects/auto-rename-ref/config.json +0 -5
- package/src/effects/provide-batch-input/config.json +0 -5
- package/src/effects/provide-batch-outputs/config.json +0 -5
- package/src/effects/provide-batch-outputs/index.ts +0 -38
- package/src/effects/provide-json-schema-outputs/config.json +0 -8
- package/src/effects/sync-variable-title/config.json +0 -5
- package/src/form-plugins/batch-outputs-plugin/config.json +0 -7
- package/src/typings/flow-value/config.json +0 -5
- package/src/typings/json-schema/config.json +0 -5
- package/src/typings/json-schema/index.ts +0 -36
- package/src/utils/json-schema/config.json +0 -5
- package/src/utils/json-schema/index.ts +0 -180
- /package/src/{utils → shared}/format-legacy-refs/index.ts +0 -0
- /package/src/{utils → shared}/format-legacy-refs/readme.md +0 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { useEffect, useState } from 'react';
|
|
7
|
+
|
|
8
|
+
import { nanoid } from 'nanoid';
|
|
9
|
+
import { difference, get, isObject, set } from 'lodash';
|
|
10
|
+
|
|
11
|
+
function genId() {
|
|
12
|
+
return nanoid();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface ListItem<ValueType> {
|
|
16
|
+
id: string;
|
|
17
|
+
key?: string;
|
|
18
|
+
value?: ValueType;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type ObjectType<ValueType> = Record<string, ValueType | undefined>;
|
|
22
|
+
|
|
23
|
+
export function useObjectList<ValueType>({
|
|
24
|
+
value,
|
|
25
|
+
onChange,
|
|
26
|
+
sortIndexKey,
|
|
27
|
+
}: {
|
|
28
|
+
value?: ObjectType<ValueType>;
|
|
29
|
+
onChange: (value?: ObjectType<ValueType>) => void;
|
|
30
|
+
sortIndexKey?: string;
|
|
31
|
+
}) {
|
|
32
|
+
const [list, setList] = useState<ListItem<ValueType>[]>([]);
|
|
33
|
+
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
setList((_prevList) => {
|
|
36
|
+
const newKeys = Object.entries(value || {})
|
|
37
|
+
.sort((a, b) => get(a[1], sortIndexKey || 0) - get(b[1], sortIndexKey || 0))
|
|
38
|
+
.map(([key]) => key);
|
|
39
|
+
|
|
40
|
+
const oldKeys = _prevList.map((item) => item.key).filter(Boolean) as string[];
|
|
41
|
+
const addKeys = difference(newKeys, oldKeys);
|
|
42
|
+
|
|
43
|
+
return _prevList
|
|
44
|
+
.filter((item) => !item.key || newKeys.includes(item.key))
|
|
45
|
+
.map((item) => ({
|
|
46
|
+
id: item.id,
|
|
47
|
+
key: item.key,
|
|
48
|
+
value: item.key ? value?.[item.key!] : item.value,
|
|
49
|
+
}))
|
|
50
|
+
.concat(
|
|
51
|
+
addKeys.map((_key) => ({
|
|
52
|
+
id: genId(),
|
|
53
|
+
key: _key,
|
|
54
|
+
value: value?.[_key],
|
|
55
|
+
}))
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
}, [value]);
|
|
59
|
+
|
|
60
|
+
const add = () => {
|
|
61
|
+
setList((prevList) => [
|
|
62
|
+
...prevList,
|
|
63
|
+
{
|
|
64
|
+
id: genId(),
|
|
65
|
+
},
|
|
66
|
+
]);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const updateValue = (itemId: string, value: ValueType) => {
|
|
70
|
+
setList((prevList) => {
|
|
71
|
+
const nextList = prevList.map((_item) => {
|
|
72
|
+
if (_item.id === itemId) {
|
|
73
|
+
return {
|
|
74
|
+
..._item,
|
|
75
|
+
value,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return _item;
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
onChange(
|
|
82
|
+
Object.fromEntries(
|
|
83
|
+
nextList
|
|
84
|
+
.filter((item) => item.key)
|
|
85
|
+
.map((item) => [item.key!, item.value])
|
|
86
|
+
.map((_res, idx) => {
|
|
87
|
+
if (isObject(_res[1]) && sortIndexKey) {
|
|
88
|
+
set(_res[1], sortIndexKey, idx);
|
|
89
|
+
}
|
|
90
|
+
return _res;
|
|
91
|
+
})
|
|
92
|
+
)
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
return nextList;
|
|
96
|
+
});
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const updateKey = (itemId: string, key: string) => {
|
|
100
|
+
setList((prevList) => {
|
|
101
|
+
const nextList = prevList.map((_item) => {
|
|
102
|
+
if (_item.id === itemId) {
|
|
103
|
+
return {
|
|
104
|
+
..._item,
|
|
105
|
+
key,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return _item;
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
onChange(
|
|
112
|
+
Object.fromEntries(
|
|
113
|
+
nextList.filter((item) => item.key).map((item) => [item.key!, item.value])
|
|
114
|
+
)
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
return nextList;
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const remove = (itemId: string) => {
|
|
122
|
+
setList((prevList) => {
|
|
123
|
+
const nextList = prevList.filter((_item) => _item.id !== itemId);
|
|
124
|
+
|
|
125
|
+
onChange(
|
|
126
|
+
Object.fromEntries(
|
|
127
|
+
nextList.filter((item) => item.key).map((item) => [item.key!, item.value])
|
|
128
|
+
)
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
return nextList;
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
return { list, add, updateKey, updateValue, remove };
|
|
136
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
ASTMatch,
|
|
8
|
+
definePluginCreator,
|
|
9
|
+
type GlobalEventActionType,
|
|
10
|
+
VariableEngine,
|
|
11
|
+
} from '@flowgram.ai/editor';
|
|
12
|
+
|
|
13
|
+
export const createDisableDeclarationPlugin = definePluginCreator<void>({
|
|
14
|
+
onInit(ctx) {
|
|
15
|
+
const variableEngine = ctx.get(VariableEngine);
|
|
16
|
+
|
|
17
|
+
const handleEvent = (action: GlobalEventActionType) => {
|
|
18
|
+
if (ASTMatch.isVariableDeclaration(action.ast)) {
|
|
19
|
+
if (!action.ast.meta?.disabled) {
|
|
20
|
+
action.ast.updateMeta({
|
|
21
|
+
...(action.ast.meta || {}),
|
|
22
|
+
disabled: true,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
variableEngine.onGlobalEvent('NewAST', handleEvent);
|
|
29
|
+
variableEngine.onGlobalEvent('UpdateAST', handleEvent);
|
|
30
|
+
},
|
|
31
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
BaseTypeManager,
|
|
8
|
+
jsonSchemaContainerModule,
|
|
9
|
+
JsonSchemaTypeManager,
|
|
10
|
+
} from '@flowgram.ai/json-schema';
|
|
11
|
+
import { definePluginCreator } from '@flowgram.ai/editor';
|
|
12
|
+
|
|
13
|
+
import { jsonSchemaTypePreset } from './type-definition';
|
|
14
|
+
import { JsonSchemaTypeRegistry } from './manager';
|
|
15
|
+
|
|
16
|
+
export const createTypePresetPlugin = definePluginCreator<{
|
|
17
|
+
types?: Partial<JsonSchemaTypeRegistry> & Pick<JsonSchemaTypeRegistry, 'type'>[];
|
|
18
|
+
unregisterTypes?: string[];
|
|
19
|
+
}>({
|
|
20
|
+
onInit(ctx, opts) {
|
|
21
|
+
const typeManager = ctx.get(BaseTypeManager) as JsonSchemaTypeManager;
|
|
22
|
+
jsonSchemaTypePreset.forEach((_type) => typeManager.register(_type));
|
|
23
|
+
|
|
24
|
+
opts.types?.forEach((_type) => typeManager.register(_type));
|
|
25
|
+
opts.unregisterTypes?.forEach((_type) => typeManager.unregister(_type));
|
|
26
|
+
},
|
|
27
|
+
containerModules: [jsonSchemaContainerModule],
|
|
28
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
type IJsonSchema,
|
|
9
|
+
JsonSchemaUtils,
|
|
10
|
+
useTypeManager as useOriginTypeManager,
|
|
11
|
+
TypePresetProvider as OriginTypePresetProvider,
|
|
12
|
+
JsonSchemaTypeManager,
|
|
13
|
+
type JsonSchemaBasicType,
|
|
14
|
+
} from '@flowgram.ai/json-schema';
|
|
15
|
+
|
|
16
|
+
import { jsonSchemaTypePreset } from './type-definition';
|
|
17
|
+
import { type JsonSchemaTypeRegistry, type ConstantRendererProps } from './manager';
|
|
18
|
+
import { createTypePresetPlugin } from './create-type-preset-plugin';
|
|
19
|
+
|
|
20
|
+
const useTypeManager = () =>
|
|
21
|
+
useOriginTypeManager() as JsonSchemaTypeManager<IJsonSchema, JsonSchemaTypeRegistry>;
|
|
22
|
+
|
|
23
|
+
const JsonSchemaTypePresetProvider = ({
|
|
24
|
+
types = [],
|
|
25
|
+
children,
|
|
26
|
+
}: React.PropsWithChildren<{ types: JsonSchemaTypeRegistry[] }>) => (
|
|
27
|
+
<OriginTypePresetProvider types={[...jsonSchemaTypePreset, ...types]}>
|
|
28
|
+
{children}
|
|
29
|
+
</OriginTypePresetProvider>
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
export {
|
|
33
|
+
createTypePresetPlugin,
|
|
34
|
+
useTypeManager,
|
|
35
|
+
JsonSchemaTypePresetProvider,
|
|
36
|
+
IJsonSchema,
|
|
37
|
+
JsonSchemaUtils,
|
|
38
|
+
JsonSchemaTypeRegistry,
|
|
39
|
+
ConstantRendererProps,
|
|
40
|
+
JsonSchemaBasicType,
|
|
41
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { JsonSchemaTypeRegistry as OriginJsonSchemaTypeRegistry } from '@flowgram.ai/json-schema';
|
|
7
|
+
|
|
8
|
+
export interface ConstantRendererProps<Value = any> {
|
|
9
|
+
value?: Value;
|
|
10
|
+
onChange?: (value: Value) => void;
|
|
11
|
+
readonly?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface JsonSchemaTypeRegistry<Value = any> extends OriginJsonSchemaTypeRegistry {
|
|
14
|
+
/**
|
|
15
|
+
* Render Constant Input
|
|
16
|
+
*/
|
|
17
|
+
ConstantRenderer: React.FC<ConstantRendererProps<Value>>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* eslint-disable react/prop-types */
|
|
7
|
+
import React from 'react';
|
|
8
|
+
|
|
9
|
+
import { I18n } from '@flowgram.ai/editor';
|
|
10
|
+
|
|
11
|
+
import { CodeEditorMini } from '@/components/code-editor-mini';
|
|
12
|
+
|
|
13
|
+
import { type JsonSchemaTypeRegistry } from '../manager';
|
|
14
|
+
|
|
15
|
+
export const arrayRegistry: Partial<JsonSchemaTypeRegistry> = {
|
|
16
|
+
type: 'array',
|
|
17
|
+
ConstantRenderer: (props) => (
|
|
18
|
+
<CodeEditorMini
|
|
19
|
+
value={props.value}
|
|
20
|
+
languageId="json"
|
|
21
|
+
onChange={(v) => props.onChange?.(v)}
|
|
22
|
+
placeholder={I18n.t('Please Input Array')}
|
|
23
|
+
readonly={props.readonly}
|
|
24
|
+
/>
|
|
25
|
+
),
|
|
26
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* eslint-disable react/prop-types */
|
|
7
|
+
import React from 'react';
|
|
8
|
+
|
|
9
|
+
import { I18n } from '@flowgram.ai/editor';
|
|
10
|
+
import { Select } from '@douyinfe/semi-ui';
|
|
11
|
+
|
|
12
|
+
import { type JsonSchemaTypeRegistry } from '../manager';
|
|
13
|
+
|
|
14
|
+
export const booleanRegistry: Partial<JsonSchemaTypeRegistry> = {
|
|
15
|
+
type: 'boolean',
|
|
16
|
+
ConstantRenderer: (props) => {
|
|
17
|
+
const { value, onChange, ...rest } = props;
|
|
18
|
+
return (
|
|
19
|
+
<Select
|
|
20
|
+
placeholder={I18n.t('Please Select Boolean')}
|
|
21
|
+
size="small"
|
|
22
|
+
disabled={props.readonly}
|
|
23
|
+
optionList={[
|
|
24
|
+
{ label: I18n.t('True'), value: 1 },
|
|
25
|
+
{ label: I18n.t('False'), value: 0 },
|
|
26
|
+
]}
|
|
27
|
+
value={value ? 1 : 0}
|
|
28
|
+
onChange={(value) => onChange?.(!!value)}
|
|
29
|
+
{...rest}
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
},
|
|
33
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { jsonSchemaTypeManager } from '@flowgram.ai/json-schema';
|
|
7
|
+
|
|
8
|
+
import { stringRegistry } from './string';
|
|
9
|
+
import { objectRegistry } from './object';
|
|
10
|
+
import { numberRegistry } from './number';
|
|
11
|
+
import { integerRegistry } from './integer';
|
|
12
|
+
import { booleanRegistry } from './boolean';
|
|
13
|
+
import { arrayRegistry } from './array';
|
|
14
|
+
|
|
15
|
+
export const jsonSchemaTypePreset = [
|
|
16
|
+
stringRegistry,
|
|
17
|
+
objectRegistry,
|
|
18
|
+
numberRegistry,
|
|
19
|
+
integerRegistry,
|
|
20
|
+
booleanRegistry,
|
|
21
|
+
arrayRegistry,
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
jsonSchemaTypePreset.forEach((_type) => jsonSchemaTypeManager.register(_type));
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* eslint-disable react/prop-types */
|
|
7
|
+
import React from 'react';
|
|
8
|
+
|
|
9
|
+
import { I18n } from '@flowgram.ai/editor';
|
|
10
|
+
import { InputNumber } from '@douyinfe/semi-ui';
|
|
11
|
+
|
|
12
|
+
import { type JsonSchemaTypeRegistry } from '../manager';
|
|
13
|
+
|
|
14
|
+
export const integerRegistry: Partial<JsonSchemaTypeRegistry> = {
|
|
15
|
+
type: 'integer',
|
|
16
|
+
ConstantRenderer: (props) => (
|
|
17
|
+
<InputNumber
|
|
18
|
+
placeholder={I18n.t('Please Input Integer')}
|
|
19
|
+
size="small"
|
|
20
|
+
disabled={props.readonly}
|
|
21
|
+
precision={0}
|
|
22
|
+
{...props}
|
|
23
|
+
/>
|
|
24
|
+
),
|
|
25
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* eslint-disable react/prop-types */
|
|
7
|
+
import React from 'react';
|
|
8
|
+
|
|
9
|
+
import { I18n } from '@flowgram.ai/editor';
|
|
10
|
+
import { InputNumber } from '@douyinfe/semi-ui';
|
|
11
|
+
|
|
12
|
+
import { type JsonSchemaTypeRegistry } from '../manager';
|
|
13
|
+
|
|
14
|
+
export const numberRegistry: Partial<JsonSchemaTypeRegistry> = {
|
|
15
|
+
type: 'number',
|
|
16
|
+
ConstantRenderer: (props) => (
|
|
17
|
+
<InputNumber
|
|
18
|
+
placeholder={I18n.t('Please Input Number')}
|
|
19
|
+
size="small"
|
|
20
|
+
disabled={props.readonly}
|
|
21
|
+
hideButtons
|
|
22
|
+
{...props}
|
|
23
|
+
/>
|
|
24
|
+
),
|
|
25
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* eslint-disable react/prop-types */
|
|
7
|
+
import React from 'react';
|
|
8
|
+
|
|
9
|
+
import { I18n } from '@flowgram.ai/editor';
|
|
10
|
+
|
|
11
|
+
import { CodeEditorMini } from '@/components/code-editor-mini';
|
|
12
|
+
|
|
13
|
+
import { type JsonSchemaTypeRegistry } from '../manager';
|
|
14
|
+
|
|
15
|
+
export const objectRegistry: Partial<JsonSchemaTypeRegistry> = {
|
|
16
|
+
type: 'object',
|
|
17
|
+
ConstantRenderer: (props) => (
|
|
18
|
+
<CodeEditorMini
|
|
19
|
+
value={props.value}
|
|
20
|
+
onChange={(v) => props.onChange?.(v)}
|
|
21
|
+
languageId="json"
|
|
22
|
+
placeholder={I18n.t('Please Input Object')}
|
|
23
|
+
readonly={props.readonly}
|
|
24
|
+
/>
|
|
25
|
+
),
|
|
26
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/* eslint-disable react/prop-types */
|
|
7
|
+
import React from 'react';
|
|
8
|
+
|
|
9
|
+
import { I18n } from '@flowgram.ai/editor';
|
|
10
|
+
import { Input } from '@douyinfe/semi-ui';
|
|
11
|
+
|
|
12
|
+
import { type JsonSchemaTypeRegistry } from '../manager';
|
|
13
|
+
|
|
14
|
+
export const stringRegistry: Partial<JsonSchemaTypeRegistry> = {
|
|
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
|
+
),
|
|
24
|
+
};
|
|
@@ -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
|
+
```
|