@flowgram.ai/form-materials 0.1.0-alpha.13 → 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.
- package/bin/index.ts +0 -11
- package/bin/materials.ts +29 -2
- package/dist/esm/chunk-727SU246.js +13 -0
- package/dist/esm/chunk-727SU246.js.map +1 -0
- package/dist/esm/chunk-DEZUEMUM.js +284 -0
- package/dist/esm/chunk-DEZUEMUM.js.map +1 -0
- package/dist/esm/chunk-DUOXDOUE.js +477 -0
- package/dist/esm/chunk-DUOXDOUE.js.map +1 -0
- package/dist/esm/editor-6UMULJYB.js +180 -0
- package/dist/esm/editor-6UMULJYB.js.map +1 -0
- package/dist/esm/editor-EYOQTGMT.js +282 -0
- package/dist/esm/editor-EYOQTGMT.js.map +1 -0
- package/dist/esm/editor-OXPGKPF5.js +167 -0
- package/dist/esm/editor-OXPGKPF5.js.map +1 -0
- package/dist/esm/editor-VO6YAXRC.js +249 -0
- package/dist/esm/editor-VO6YAXRC.js.map +1 -0
- package/dist/esm/editor-XYLKTB6L.js +365 -0
- package/dist/esm/editor-XYLKTB6L.js.map +1 -0
- package/dist/esm/index.js +1110 -2306
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +298 -59
- package/dist/index.d.ts +298 -59
- package/dist/index.js +3932 -2681
- package/dist/index.js.map +1 -1
- package/package.json +9 -8
- package/src/components/batch-outputs/index.tsx +3 -2
- package/src/components/code-editor/editor.tsx +89 -0
- package/src/components/code-editor/index.tsx +5 -89
- package/src/components/code-editor/language-features.ts +18 -18
- package/src/components/code-editor/theme/dark.ts +49 -30
- package/src/components/code-editor/theme/light.ts +56 -32
- package/src/components/code-editor-mini/index.tsx +2 -2
- package/src/components/condition-row/constants.ts +8 -0
- package/src/components/condition-row/index.tsx +4 -0
- package/src/components/db-condition-row/hooks/use-left.tsx +66 -0
- package/src/components/db-condition-row/hooks/use-op.tsx +59 -0
- package/src/components/db-condition-row/index.tsx +93 -0
- package/src/components/db-condition-row/styles.tsx +43 -0
- package/src/components/db-condition-row/types.ts +34 -0
- package/src/components/display-flow-value/index.tsx +2 -12
- package/src/components/display-inputs-values/index.tsx +44 -6
- package/src/components/dynamic-value-input/hooks.ts +25 -4
- package/src/components/dynamic-value-input/index.tsx +21 -12
- package/src/components/dynamic-value-input/styles.tsx +14 -4
- package/src/components/index.ts +3 -0
- package/src/components/inputs-values/index.tsx +14 -3
- package/src/components/inputs-values/styles.tsx +1 -1
- package/src/components/inputs-values-tree/hooks/use-child-list.tsx +76 -0
- package/src/components/inputs-values-tree/index.tsx +62 -0
- package/src/components/inputs-values-tree/row.tsx +177 -0
- package/src/components/inputs-values-tree/styles.tsx +128 -0
- package/src/components/inputs-values-tree/types.ts +21 -0
- package/src/components/json-editor-with-variables/editor.tsx +69 -0
- package/src/components/json-editor-with-variables/extensions/variable-tag.tsx +6 -5
- package/src/components/json-editor-with-variables/index.tsx +5 -59
- package/src/components/json-schema-editor/default-value.tsx +1 -3
- package/src/components/json-schema-editor/hooks.tsx +14 -3
- package/src/components/json-schema-editor/index.tsx +18 -58
- package/src/components/json-schema-editor/styles.tsx +12 -55
- package/src/components/json-schema-editor/types.ts +0 -1
- package/src/components/prompt-editor/editor.tsx +81 -0
- package/src/components/prompt-editor/index.tsx +5 -62
- package/src/components/prompt-editor-with-inputs/editor.tsx +25 -0
- package/src/components/prompt-editor-with-inputs/extensions/inputs-tree.tsx +11 -0
- package/src/components/prompt-editor-with-inputs/index.tsx +5 -16
- package/src/components/prompt-editor-with-inputs/inputs-picker.tsx +34 -17
- package/src/components/prompt-editor-with-variables/editor.tsx +22 -0
- package/src/components/prompt-editor-with-variables/extensions/variable-tag.tsx +12 -20
- package/src/components/prompt-editor-with-variables/extensions/variable-tree.tsx +13 -1
- package/src/components/prompt-editor-with-variables/index.tsx +5 -13
- package/src/components/type-selector/index.tsx +12 -2
- package/src/components/variable-selector/context.tsx +28 -0
- package/src/components/variable-selector/index.tsx +10 -1
- package/src/components/variable-selector/use-variable-tree.tsx +3 -3
- package/src/effects/auto-rename-ref/index.ts +7 -54
- package/src/effects/validate-when-variable-sync/index.ts +1 -1
- package/src/form-plugins/infer-assign-plugin/index.ts +1 -1
- package/src/form-plugins/infer-inputs-plugin/index.ts +4 -76
- package/src/hooks/use-object-list/index.tsx +35 -7
- package/src/index.ts +1 -0
- package/src/plugins/json-schema-preset/manager.ts +1 -0
- package/src/plugins/json-schema-preset/type-definition/date-time.tsx +25 -0
- package/src/plugins/json-schema-preset/type-definition/index.tsx +2 -0
- package/src/plugins/json-schema-preset/type-definition/string.tsx +18 -9
- package/src/shared/flow-value/index.ts +6 -0
- package/src/shared/flow-value/schema.ts +38 -0
- package/src/shared/flow-value/utils.ts +201 -0
- package/src/shared/format-legacy-refs/index.ts +1 -1
- package/src/shared/index.ts +3 -0
- package/src/shared/lazy-suspense/index.tsx +28 -0
- package/src/shared/polyfill-create-root/index.tsx +33 -0
- package/src/typings/flow-value/index.ts +3 -1
- package/src/validate/validate-flow-value/index.tsx +4 -16
- package/src/components/json-schema-editor/components/blur-input.tsx +0 -27
- package/src/plugins/disable-declaration-plugin/config.json +0 -5
- package/src/plugins/json-schema-preset/config.json +0 -9
- /package/src/components/{inputs-values/components/blur-input.tsx → blur-input/index.tsx} +0 -0
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
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 styled, { css } from 'styled-components';
|
|
9
|
+
import Icon from '@douyinfe/semi-icons';
|
|
10
|
+
|
|
11
|
+
export const UIContainer = styled.div``;
|
|
12
|
+
|
|
13
|
+
export const UIRow = styled.div`
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: flex-start;
|
|
16
|
+
gap: 5px;
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
export const UICollapseTrigger = styled.div`
|
|
20
|
+
cursor: pointer;
|
|
21
|
+
margin-right: 5px;
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
export const UITreeItems = styled.div<{ $shrink?: boolean }>`
|
|
25
|
+
display: grid;
|
|
26
|
+
grid-template-columns: auto 1fr;
|
|
27
|
+
|
|
28
|
+
${({ $shrink }) =>
|
|
29
|
+
$shrink &&
|
|
30
|
+
css`
|
|
31
|
+
padding-left: 3px;
|
|
32
|
+
margin-top: 10px;
|
|
33
|
+
`}
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
export const UITreeItemLeft = styled.div<{
|
|
37
|
+
$isLast?: boolean;
|
|
38
|
+
$showLine?: boolean;
|
|
39
|
+
$showCollapse?: boolean;
|
|
40
|
+
}>`
|
|
41
|
+
grid-column: 1;
|
|
42
|
+
position: relative;
|
|
43
|
+
width: 16px;
|
|
44
|
+
|
|
45
|
+
${({ $showLine, $isLast, $showCollapse }) => {
|
|
46
|
+
let height = $isLast ? '24px' : '100%';
|
|
47
|
+
let width = $showCollapse ? '12px' : '30px';
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
$showLine &&
|
|
51
|
+
css`
|
|
52
|
+
&::before {
|
|
53
|
+
/* 竖线 */
|
|
54
|
+
content: '';
|
|
55
|
+
height: ${height};
|
|
56
|
+
position: absolute;
|
|
57
|
+
left: -14px;
|
|
58
|
+
top: -16px;
|
|
59
|
+
width: 1px;
|
|
60
|
+
background: #d9d9d9;
|
|
61
|
+
display: block;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
&::after {
|
|
65
|
+
/* 横线 */
|
|
66
|
+
content: '';
|
|
67
|
+
position: absolute;
|
|
68
|
+
left: -14px; // 横线起点和竖线对齐
|
|
69
|
+
top: 8px; // 跟随你的行高调整
|
|
70
|
+
width: ${width}; // 横线长度
|
|
71
|
+
height: 1px;
|
|
72
|
+
background: #d9d9d9;
|
|
73
|
+
display: block;
|
|
74
|
+
}
|
|
75
|
+
`
|
|
76
|
+
);
|
|
77
|
+
}}
|
|
78
|
+
`;
|
|
79
|
+
|
|
80
|
+
export const UITreeItemRight = styled.div`
|
|
81
|
+
grid-column: 2;
|
|
82
|
+
margin-bottom: 10px;
|
|
83
|
+
|
|
84
|
+
&:last-child {
|
|
85
|
+
margin-bottom: 0px;
|
|
86
|
+
}
|
|
87
|
+
`;
|
|
88
|
+
|
|
89
|
+
export const UITreeItemMain = styled.div<{}>`
|
|
90
|
+
display: flex;
|
|
91
|
+
flex-direction: column;
|
|
92
|
+
gap: 10px;
|
|
93
|
+
position: relative;
|
|
94
|
+
`;
|
|
95
|
+
|
|
96
|
+
export const UICollapsible = styled.div<{ $collapse?: boolean }>`
|
|
97
|
+
display: none;
|
|
98
|
+
|
|
99
|
+
${({ $collapse }) =>
|
|
100
|
+
$collapse &&
|
|
101
|
+
css`
|
|
102
|
+
display: block;
|
|
103
|
+
`}
|
|
104
|
+
`;
|
|
105
|
+
|
|
106
|
+
export const UIActions = styled.div`
|
|
107
|
+
white-space: nowrap;
|
|
108
|
+
`;
|
|
109
|
+
|
|
110
|
+
const iconAddChildrenSvg = (
|
|
111
|
+
<svg
|
|
112
|
+
className="icon-icon icon-icon-coz_add_node "
|
|
113
|
+
width="1em"
|
|
114
|
+
height="1em"
|
|
115
|
+
viewBox="0 0 24 24"
|
|
116
|
+
fill="currentColor"
|
|
117
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
118
|
+
>
|
|
119
|
+
<path
|
|
120
|
+
fillRule="evenodd"
|
|
121
|
+
clipRule="evenodd"
|
|
122
|
+
d="M11 6.49988C11 8.64148 9.50397 10.4337 7.49995 10.8884V15.4998C7.49995 16.0521 7.94767 16.4998 8.49995 16.4998H11.208C11.0742 16.8061 11 17.1443 11 17.4998C11 17.8554 11.0742 18.1936 11.208 18.4998H8.49995C6.8431 18.4998 5.49995 17.1567 5.49995 15.4998V10.8884C3.49599 10.4336 2 8.64145 2 6.49988C2 4.0146 4.01472 1.99988 6.5 1.99988C8.98528 1.99988 11 4.0146 11 6.49988ZM6.5 8.99988C7.88071 8.99988 9 7.88059 9 6.49988C9 5.11917 7.88071 3.99988 6.5 3.99988C5.11929 3.99988 4 5.11917 4 6.49988C4 7.88059 5.11929 8.99988 6.5 8.99988Z"
|
|
123
|
+
></path>
|
|
124
|
+
<path d="M17.5 12.4999C18.0523 12.4999 18.5 12.9476 18.5 13.4999V16.4999H21.5C22.0523 16.4999 22.5 16.9476 22.5 17.4999C22.5 18.0522 22.0523 18.4999 21.5 18.4999H18.5V21.4999C18.5 22.0522 18.0523 22.4999 17.5 22.4999C16.9477 22.4999 16.5 22.0522 16.5 21.4999V18.4999H13.5C12.9477 18.4999 12.5 18.0522 12.5 17.4999C12.5 16.9476 12.9477 16.4999 13.5 16.4999H16.5V13.4999C16.5 12.9476 16.9477 12.4999 17.5 12.4999Z"></path>
|
|
125
|
+
</svg>
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
export const IconAddChildren = () => <Icon size="small" svg={iconAddChildrenSvg} />;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
|
|
3
|
+
* SPDX-License-Identifier: MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { IJsonSchema } from '@flowgram.ai/json-schema';
|
|
7
|
+
|
|
8
|
+
import { ConstantInputStrategy } from '@/components/constant-input';
|
|
9
|
+
|
|
10
|
+
export interface PropsType {
|
|
11
|
+
value?: any;
|
|
12
|
+
onChange: (value?: any) => void;
|
|
13
|
+
readonly?: boolean;
|
|
14
|
+
hasError?: boolean;
|
|
15
|
+
schema?: IJsonSchema;
|
|
16
|
+
style?: React.CSSProperties;
|
|
17
|
+
constantProps?: {
|
|
18
|
+
strategies?: ConstantInputStrategy[];
|
|
19
|
+
[key: string]: any;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
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 { transformerCreator } from '@coze-editor/editor/preset-code';
|
|
10
|
+
import { Text } from '@coze-editor/editor/language-json';
|
|
11
|
+
|
|
12
|
+
import { CodeEditor, type CodeEditorPropsType } from '@/components/code-editor';
|
|
13
|
+
|
|
14
|
+
import { VariableTree } from './extensions/variable-tree';
|
|
15
|
+
import { VariableTagInject } from './extensions/variable-tag';
|
|
16
|
+
|
|
17
|
+
type Match = { match: string; range: [number, number] };
|
|
18
|
+
function findAllMatches(inputString: string, regex: RegExp): Match[] {
|
|
19
|
+
const globalRegex = new RegExp(
|
|
20
|
+
regex,
|
|
21
|
+
regex.flags.includes('g') ? regex.flags : regex.flags + 'g'
|
|
22
|
+
);
|
|
23
|
+
let match;
|
|
24
|
+
const matches: Match[] = [];
|
|
25
|
+
|
|
26
|
+
while ((match = globalRegex.exec(inputString)) !== null) {
|
|
27
|
+
if (match.index === globalRegex.lastIndex) {
|
|
28
|
+
globalRegex.lastIndex++;
|
|
29
|
+
}
|
|
30
|
+
matches.push({
|
|
31
|
+
match: match[0],
|
|
32
|
+
range: [match.index, match.index + match[0].length],
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return matches;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const transformer = transformerCreator((text: Text) => {
|
|
40
|
+
const originalSource = text.toString();
|
|
41
|
+
const matches = findAllMatches(originalSource, /\{\{([^\}]*)\}\}/g);
|
|
42
|
+
|
|
43
|
+
if (matches.length > 0) {
|
|
44
|
+
matches.forEach(({ range }) => {
|
|
45
|
+
text.replaceRange(range[0], range[1], 'null');
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return text;
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
export interface JsonEditorWithVariablesProps extends Omit<CodeEditorPropsType, 'languageId'> {}
|
|
53
|
+
|
|
54
|
+
export function JsonEditorWithVariables(props: JsonEditorWithVariablesProps) {
|
|
55
|
+
return (
|
|
56
|
+
<CodeEditor
|
|
57
|
+
languageId="json"
|
|
58
|
+
activeLinePlaceholder={I18n.t("Press '@' to Select variable")}
|
|
59
|
+
{...props}
|
|
60
|
+
options={{
|
|
61
|
+
transformer,
|
|
62
|
+
...(props.options || {}),
|
|
63
|
+
}}
|
|
64
|
+
>
|
|
65
|
+
<VariableTree />
|
|
66
|
+
<VariableTagInject />
|
|
67
|
+
</CodeEditor>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import React, { useLayoutEffect } from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
import { isEqual, last } from 'lodash';
|
|
8
|
+
import { isEqual, last } from 'lodash-es';
|
|
10
9
|
import {
|
|
11
10
|
BaseVariableField,
|
|
12
11
|
Disposable,
|
|
@@ -26,6 +25,8 @@ import {
|
|
|
26
25
|
WidgetType,
|
|
27
26
|
} from '@codemirror/view';
|
|
28
27
|
|
|
28
|
+
import { IPolyfillRoot, polyfillCreateRoot } from '@/shared';
|
|
29
|
+
|
|
29
30
|
import { UIPopoverContent, UIRootTitle, UITag, UIVarName } from '../styles';
|
|
30
31
|
|
|
31
32
|
class VariableTagWidget extends WidgetType {
|
|
@@ -35,7 +36,7 @@ class VariableTagWidget extends WidgetType {
|
|
|
35
36
|
|
|
36
37
|
scope: Scope;
|
|
37
38
|
|
|
38
|
-
root:
|
|
39
|
+
root: IPolyfillRoot;
|
|
39
40
|
|
|
40
41
|
constructor({ keyPath, scope }: { keyPath?: string[]; scope: Scope }) {
|
|
41
42
|
super();
|
|
@@ -90,7 +91,7 @@ class VariableTagWidget extends WidgetType {
|
|
|
90
91
|
toDOM(view: EditorView): HTMLElement {
|
|
91
92
|
const dom = document.createElement('span');
|
|
92
93
|
|
|
93
|
-
this.root =
|
|
94
|
+
this.root = polyfillCreateRoot(dom);
|
|
94
95
|
|
|
95
96
|
this.toDispose.push(
|
|
96
97
|
Disposable.create(() => {
|
|
@@ -134,7 +135,7 @@ export function VariableTagInject() {
|
|
|
134
135
|
// 基于 {{var}} 的正则进行匹配,匹配后进行自定义渲染
|
|
135
136
|
useLayoutEffect(() => {
|
|
136
137
|
const atMatcher = new MatchDecorator({
|
|
137
|
-
regexp: /\{\{([^\}]+)\}\}/g,
|
|
138
|
+
regexp: /\{\{([^\}\{]+)\}\}/g,
|
|
138
139
|
decoration: (match) =>
|
|
139
140
|
Decoration.replace({
|
|
140
141
|
widget: new VariableTagWidget({
|
|
@@ -3,64 +3,10 @@
|
|
|
3
3
|
* SPDX-License-Identifier: MIT
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import { lazySuspense } from '@/shared';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
import {
|
|
8
|
+
export const JsonEditorWithVariables = lazySuspense(() =>
|
|
9
|
+
import('./editor').then((module) => ({ default: module.JsonEditorWithVariables }))
|
|
10
|
+
);
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
import { VariableTree } from './extensions/variable-tree';
|
|
14
|
-
import { VariableTagInject } from './extensions/variable-tag';
|
|
15
|
-
|
|
16
|
-
type Match = { match: string; range: [number, number] };
|
|
17
|
-
function findAllMatches(inputString: string, regex: RegExp): Match[] {
|
|
18
|
-
const globalRegex = new RegExp(
|
|
19
|
-
regex,
|
|
20
|
-
regex.flags.includes('g') ? regex.flags : regex.flags + 'g'
|
|
21
|
-
);
|
|
22
|
-
let match;
|
|
23
|
-
const matches: Match[] = [];
|
|
24
|
-
|
|
25
|
-
while ((match = globalRegex.exec(inputString)) !== null) {
|
|
26
|
-
if (match.index === globalRegex.lastIndex) {
|
|
27
|
-
globalRegex.lastIndex++;
|
|
28
|
-
}
|
|
29
|
-
matches.push({
|
|
30
|
-
match: match[0],
|
|
31
|
-
range: [match.index, match.index + match[0].length],
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return matches;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const transformer = transformerCreator((text: Text) => {
|
|
39
|
-
const originalSource = text.toString();
|
|
40
|
-
const matches = findAllMatches(originalSource, /\{\{([^\}]*)\}\}/g);
|
|
41
|
-
|
|
42
|
-
if (matches.length > 0) {
|
|
43
|
-
matches.forEach(({ range }) => {
|
|
44
|
-
text.replaceRange(range[0], range[1], 'null');
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return text;
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
export function JsonEditorWithVariables(props: Omit<CodeEditorPropsType, 'languageId'>) {
|
|
52
|
-
return (
|
|
53
|
-
<CodeEditor
|
|
54
|
-
languageId="json"
|
|
55
|
-
activeLinePlaceholder="Press '@' to Select variable"
|
|
56
|
-
{...props}
|
|
57
|
-
options={{
|
|
58
|
-
transformer,
|
|
59
|
-
...(props.options || {}),
|
|
60
|
-
}}
|
|
61
|
-
>
|
|
62
|
-
<VariableTree />
|
|
63
|
-
<VariableTagInject />
|
|
64
|
-
</CodeEditor>
|
|
65
|
-
);
|
|
66
|
-
}
|
|
12
|
+
export type { JsonEditorWithVariablesProps } from './editor';
|
|
@@ -20,10 +20,7 @@ import { ConstantInputWrapper } from './styles';
|
|
|
20
20
|
export function DefaultValue(props: {
|
|
21
21
|
value: any;
|
|
22
22
|
schema?: IJsonSchema;
|
|
23
|
-
name?: string;
|
|
24
|
-
type?: string;
|
|
25
23
|
placeholder?: string;
|
|
26
|
-
jsonFormatText?: string;
|
|
27
24
|
onChange: (value: any) => void;
|
|
28
25
|
}) {
|
|
29
26
|
const { value, schema, onChange, placeholder } = props;
|
|
@@ -35,6 +32,7 @@ export function DefaultValue(props: {
|
|
|
35
32
|
onChange={(_v) => onChange(_v)}
|
|
36
33
|
schema={schema || { type: 'string' }}
|
|
37
34
|
placeholder={placeholder ?? I18n.t('Default value if parameter is not provided')}
|
|
35
|
+
enableMultiLineStr
|
|
38
36
|
/>
|
|
39
37
|
</ConstantInputWrapper>
|
|
40
38
|
);
|