@flowgram.ai/form-materials 0.2.16 → 0.2.18

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 (64) hide show
  1. package/bin/materials.ts +6 -1
  2. package/bin/project.ts +5 -0
  3. package/dist/esm/index.js +462 -14
  4. package/dist/esm/index.js.map +1 -1
  5. package/dist/index.d.mts +177 -6
  6. package/dist/index.d.ts +177 -6
  7. package/dist/index.js +482 -43
  8. package/dist/index.js.map +1 -1
  9. package/package.json +6 -4
  10. package/src/components/batch-outputs/config.json +12 -0
  11. package/src/components/batch-outputs/index.tsx +61 -0
  12. package/src/components/batch-outputs/styles.tsx +19 -0
  13. package/src/components/batch-outputs/types.ts +22 -0
  14. package/src/components/batch-outputs/use-list.ts +86 -0
  15. package/src/components/batch-variable-selector/index.tsx +5 -0
  16. package/src/components/condition-row/constants.ts +5 -0
  17. package/src/components/condition-row/hooks/useOp.tsx +5 -0
  18. package/src/components/condition-row/hooks/useRule.ts +5 -0
  19. package/src/components/condition-row/index.tsx +5 -0
  20. package/src/components/condition-row/styles.tsx +5 -0
  21. package/src/components/condition-row/types.ts +5 -0
  22. package/src/components/constant-input/index.tsx +5 -0
  23. package/src/components/constant-input/types.ts +5 -0
  24. package/src/components/dynamic-value-input/index.tsx +7 -0
  25. package/src/components/dynamic-value-input/styles.tsx +7 -0
  26. package/src/components/index.ts +8 -0
  27. package/src/components/json-schema-editor/components/blur-input.tsx +5 -0
  28. package/src/components/json-schema-editor/default-value.tsx +5 -0
  29. package/src/components/json-schema-editor/hooks.tsx +5 -0
  30. package/src/components/json-schema-editor/index.tsx +5 -0
  31. package/src/components/json-schema-editor/styles.tsx +5 -0
  32. package/src/components/json-schema-editor/types.ts +5 -0
  33. package/src/components/json-schema-editor/utils.ts +5 -0
  34. package/src/components/prompt-editor/config.json +9 -0
  35. package/src/components/prompt-editor/extensions/jinja.tsx +58 -0
  36. package/src/components/prompt-editor/extensions/language-support.tsx +19 -0
  37. package/src/components/prompt-editor/extensions/markdown.tsx +75 -0
  38. package/src/components/prompt-editor/index.tsx +43 -0
  39. package/src/components/prompt-editor/styles.tsx +18 -0
  40. package/src/components/prompt-editor/types.tsx +16 -0
  41. package/src/components/prompt-editor-with-variables/config.json +10 -0
  42. package/src/components/prompt-editor-with-variables/extensions/variable.tsx +85 -0
  43. package/src/components/prompt-editor-with-variables/index.tsx +17 -0
  44. package/src/components/type-selector/constants.tsx +5 -0
  45. package/src/components/type-selector/index.tsx +5 -0
  46. package/src/components/variable-selector/index.tsx +9 -2
  47. package/src/components/variable-selector/styles.tsx +17 -1
  48. package/src/components/variable-selector/use-variable-tree.tsx +8 -3
  49. package/src/effects/auto-rename-ref/index.ts +5 -0
  50. package/src/effects/index.ts +5 -0
  51. package/src/effects/provide-batch-input/index.ts +5 -0
  52. package/src/effects/provide-batch-outputs/index.ts +5 -1
  53. package/src/effects/provide-json-schema-outputs/index.ts +5 -0
  54. package/src/effects/sync-variable-title/index.ts +5 -0
  55. package/src/form-plugins/batch-outputs-plugin/config.json +7 -0
  56. package/src/form-plugins/batch-outputs-plugin/index.ts +104 -0
  57. package/src/form-plugins/index.ts +6 -0
  58. package/src/index.ts +6 -0
  59. package/src/typings/flow-value/index.ts +5 -0
  60. package/src/typings/index.ts +5 -0
  61. package/src/typings/json-schema/index.ts +5 -0
  62. package/src/utils/format-legacy-refs/index.ts +5 -0
  63. package/src/utils/index.ts +5 -0
  64. package/src/utils/json-schema/index.ts +21 -2
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import styled, { css } from 'styled-components';
7
+
8
+ export const UIContainer = styled.div<{ $hasError?: boolean }>`
9
+ background-color: var(--semi-color-fill-0);
10
+ padding-left: 10px;
11
+ padding-right: 6px;
12
+
13
+ ${({ $hasError }) =>
14
+ $hasError &&
15
+ css`
16
+ border: 1px solid var(--semi-color-danger-6);
17
+ `}
18
+ `;
@@ -0,0 +1,16 @@
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 { IFlowTemplateValue } from '../../typings';
9
+
10
+ export type PropsType = React.PropsWithChildren<{
11
+ value?: IFlowTemplateValue;
12
+ onChange: (value?: IFlowTemplateValue) => void;
13
+ readonly?: boolean;
14
+ hasError?: boolean;
15
+ style?: React.CSSProperties;
16
+ }>;
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "prompt-editor",
3
+ "depMaterials": [],
4
+ "depPackages": [
5
+ "@coze-editor/editor@0.1.0-alpha.8d7a30",
6
+ "@codemirror/view",
7
+ "styled-components",
8
+ "@douyinfe/semi-ui"
9
+ ]
10
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import React, { useEffect, useState } from 'react';
7
+
8
+ import { Popover, Tree } from '@douyinfe/semi-ui';
9
+ import {
10
+ Mention,
11
+ MentionOpenChangeEvent,
12
+ getCurrentMentionReplaceRange,
13
+ useEditor,
14
+ PositionMirror,
15
+ } from '@coze-editor/editor/react';
16
+ import { EditorAPI } from '@coze-editor/editor/preset-prompt';
17
+
18
+ import { useVariableTree } from '../../variable-selector';
19
+
20
+ function Variable() {
21
+ const [posKey, setPosKey] = useState('');
22
+ const [visible, setVisible] = useState(false);
23
+ const [position, setPosition] = useState(-1);
24
+ const editor = useEditor<EditorAPI>();
25
+
26
+ function insert(variablePath: string) {
27
+ const range = getCurrentMentionReplaceRange(editor.$view.state);
28
+
29
+ if (!range) {
30
+ return;
31
+ }
32
+
33
+ editor.replaceText({
34
+ ...range,
35
+ text: '{{' + variablePath + '}}',
36
+ });
37
+
38
+ setVisible(false);
39
+ }
40
+
41
+ function handleOpenChange(e: MentionOpenChangeEvent) {
42
+ setPosition(e.state.selection.main.head);
43
+ setVisible(e.value);
44
+ }
45
+
46
+ useEffect(() => {
47
+ if (!editor) {
48
+ return;
49
+ }
50
+ }, [editor, visible]);
51
+
52
+ const treeData = useVariableTree({});
53
+
54
+ return (
55
+ <>
56
+ <Mention triggerCharacters={['{', '{}']} onOpenChange={handleOpenChange} />
57
+
58
+ <Popover
59
+ visible={visible}
60
+ trigger="custom"
61
+ position="topLeft"
62
+ rePosKey={posKey}
63
+ content={
64
+ <div style={{ width: 300 }}>
65
+ <Tree
66
+ treeData={treeData}
67
+ onSelect={(v) => {
68
+ insert(v);
69
+ }}
70
+ />
71
+ </div>
72
+ }
73
+ >
74
+ {/* PositionMirror allows the Popover to appear at the specified cursor position */}
75
+ <PositionMirror
76
+ position={position}
77
+ // When Doc scroll, update position
78
+ onChange={() => setPosKey(String(Math.random()))}
79
+ />
80
+ </Popover>
81
+ </>
82
+ );
83
+ }
84
+
85
+ export default Variable;
@@ -0,0 +1,17 @@
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 Variable from './extensions/variable';
9
+ import { PromptEditor, PromptEditorPropsType } from '../prompt-editor';
10
+
11
+ export function PromptEditorWithVariables(props: PromptEditorPropsType) {
12
+ return (
13
+ <PromptEditor {...props}>
14
+ <Variable />
15
+ </PromptEditor>
16
+ );
17
+ }
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  import React from 'react';
2
7
 
3
8
  import { CascaderData } from '@douyinfe/semi-ui/lib/es/cascader';
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  import React, { useMemo } from 'react';
2
7
 
3
8
  import { Button, Cascader } from '@douyinfe/semi-ui';
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  import React, { useMemo } from 'react';
2
7
 
3
8
  import { TriggerRenderProps } from '@douyinfe/semi-ui/lib/es/treeSelect';
@@ -6,7 +11,7 @@ import { IconChevronDownStroked, IconIssueStroked } from '@douyinfe/semi-icons';
6
11
 
7
12
  import { IJsonSchema } from '../../typings/json-schema';
8
13
  import { useVariableTree } from './use-variable-tree';
9
- import { UIRootTitle, UITag, UITreeSelect } from './styles';
14
+ import { UIRootTitle, UITag, UITreeSelect, UIVarName } from './styles';
10
15
 
11
16
  interface PropTypes {
12
17
  value?: string[];
@@ -25,6 +30,8 @@ interface PropTypes {
25
30
 
26
31
  export type VariableSelectorProps = PropTypes;
27
32
 
33
+ export { useVariableTree };
34
+
28
35
  export const VariableSelector = ({
29
36
  value,
30
37
  config = {},
@@ -95,7 +102,7 @@ export const VariableSelector = ({
95
102
  <UIRootTitle>
96
103
  {_option.rootMeta?.title ? `${_option.rootMeta?.title} -` : null}
97
104
  </UIRootTitle>
98
- {_option.label}
105
+ <UIVarName>{_option.label}</UIVarName>
99
106
  </UITag>
100
107
  );
101
108
  }}
@@ -1,11 +1,27 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  import styled from 'styled-components';
2
7
  import { Tag, TreeSelect } from '@douyinfe/semi-ui';
3
8
 
4
- export const UIRootTitle = styled.span`
9
+ export const UIRootTitle = styled.div`
5
10
  margin-right: 4px;
11
+ min-width: 20px;
12
+ overflow: hidden;
13
+ text-overflow: ellipsis;
14
+ white-space: nowrap;
6
15
  color: var(--semi-color-text-2);
7
16
  `;
8
17
 
18
+ export const UIVarName = styled.div`
19
+ overflow: hidden;
20
+ text-overflow: ellipsis;
21
+ white-space: nowrap;
22
+ min-width: 50%;
23
+ `;
24
+
9
25
  export const UITag = styled(Tag)`
10
26
  width: 100%;
11
27
  display: flex;
@@ -1,6 +1,11 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  import React, { useCallback } from 'react';
2
7
 
3
- import { useScopeAvailable, ASTMatch, BaseVariableField } from '@flowgram.ai/editor';
8
+ import { ASTMatch, BaseVariableField, useAvailableVariables } from '@flowgram.ai/editor';
4
9
  import { TreeNodeData } from '@douyinfe/semi-ui/lib/es/tree';
5
10
  import { Icon } from '@douyinfe/semi-ui';
6
11
 
@@ -16,7 +21,7 @@ export function useVariableTree(params: {
16
21
  }): TreeNodeData[] {
17
22
  const { includeSchema, excludeSchema } = params;
18
23
 
19
- const available = useScopeAvailable();
24
+ const variables = useAvailableVariables();
20
25
 
21
26
  const getVariableTypeIcon = useCallback((variable: VariableField) => {
22
27
  if (variable.meta?.icon) {
@@ -92,7 +97,7 @@ export function useVariableTree(params: {
92
97
  };
93
98
  };
94
99
 
95
- return [...available.variables.slice(0).reverse()]
100
+ return [...variables.slice(0).reverse()]
96
101
  .map((_variable) => renderVariable(_variable as VariableField))
97
102
  .filter(Boolean) as TreeNodeData[];
98
103
  }
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  import { isArray, isObject } from 'lodash';
2
7
  import {
3
8
  DataEvent,
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  export * from './provide-batch-input';
2
7
  export * from './provide-batch-outputs';
3
8
  export * from './auto-rename-ref';
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  import {
2
7
  ASTFactory,
3
8
  EffectOptions,
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  import {
2
7
  ASTFactory,
3
8
  EffectOptions,
@@ -9,7 +14,6 @@ import {
9
14
  import { IFlowRefValue } from '../../typings';
10
15
 
11
16
  export const provideBatchOutputsEffect: EffectOptions[] = createEffectFromVariableProvider({
12
- private: true,
13
17
  parse: (value: Record<string, IFlowRefValue>, ctx) => [
14
18
  ASTFactory.createVariableDeclaration({
15
19
  key: `${ctx.node.id}`,
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  import {
2
7
  ASTFactory,
3
8
  EffectOptions,
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  import {
2
7
  DataEvent,
3
8
  Effect,
@@ -0,0 +1,7 @@
1
+ {
2
+ "name": "batch-outputs-plugin",
3
+ "depMaterials": [
4
+ "flow-value"
5
+ ],
6
+ "depPackages": []
7
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ import {
7
+ ASTFactory,
8
+ createEffectFromVariableProvider,
9
+ defineFormPluginCreator,
10
+ FlowNodeRegistry,
11
+ getNodeForm,
12
+ getNodePrivateScope,
13
+ getNodeScope,
14
+ ScopeChainTransformService,
15
+ type EffectOptions,
16
+ type FormPluginCreator,
17
+ FlowNodeScopeType,
18
+ } from '@flowgram.ai/editor';
19
+
20
+ import { IFlowRefValue } from '../../typings';
21
+
22
+ export const provideBatchOutputsEffect: EffectOptions[] = createEffectFromVariableProvider({
23
+ parse: (value: Record<string, IFlowRefValue>, ctx) => [
24
+ ASTFactory.createVariableDeclaration({
25
+ key: `${ctx.node.id}`,
26
+ meta: {
27
+ title: getNodeForm(ctx.node)?.getValueIn('title'),
28
+ icon: ctx.node.getNodeRegistry<FlowNodeRegistry>().info?.icon,
29
+ },
30
+ type: ASTFactory.createObject({
31
+ properties: Object.entries(value).map(([_key, value]) =>
32
+ ASTFactory.createProperty({
33
+ key: _key,
34
+ initializer: ASTFactory.createWrapArrayExpression({
35
+ wrapFor: ASTFactory.createKeyPathExpression({
36
+ keyPath: value?.content || [],
37
+ }),
38
+ }),
39
+ })
40
+ ),
41
+ }),
42
+ }),
43
+ ],
44
+ });
45
+
46
+ /**
47
+ * Free Layout only right now
48
+ */
49
+ export const createBatchOutputsFormPlugin: FormPluginCreator<{ outputKey: string }> =
50
+ defineFormPluginCreator({
51
+ name: 'batch-outputs-plugin',
52
+ onSetupFormMeta({ mergeEffect }, { outputKey }) {
53
+ mergeEffect({
54
+ [outputKey]: provideBatchOutputsEffect,
55
+ });
56
+ },
57
+ onInit(ctx, { outputKey }) {
58
+ const chainTransformService = ctx.node.getService(ScopeChainTransformService);
59
+
60
+ const batchNodeType = ctx.node.flowNodeType;
61
+
62
+ const transformerId = `${batchNodeType}-outputs`;
63
+
64
+ if (chainTransformService.hasTransformer(transformerId)) {
65
+ return;
66
+ }
67
+
68
+ chainTransformService.registerTransformer(transformerId, {
69
+ transformCovers: (covers, ctx) => {
70
+ const node = ctx.scope.meta?.node;
71
+
72
+ // Child Node's variable can cover parent
73
+ if (node?.parent?.flowNodeType === batchNodeType) {
74
+ return [...covers, getNodeScope(node.parent)];
75
+ }
76
+
77
+ return covers;
78
+ },
79
+ transformDeps(scopes, ctx) {
80
+ const scopeMeta = ctx.scope.meta;
81
+
82
+ if (scopeMeta?.type === FlowNodeScopeType.private) {
83
+ return scopes;
84
+ }
85
+
86
+ const node = scopeMeta?.node;
87
+
88
+ // Public of Loop Node depends on child Node
89
+ if (node?.flowNodeType === batchNodeType) {
90
+ // Get all child blocks
91
+ const childBlocks = node.blocks;
92
+
93
+ // public scope of all child blocks
94
+ return [
95
+ getNodePrivateScope(node),
96
+ ...childBlocks.map((_childBlock) => getNodeScope(_childBlock)),
97
+ ];
98
+ }
99
+
100
+ return scopes;
101
+ },
102
+ });
103
+ },
104
+ });
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
6
+ export { createBatchOutputsFormPlugin } from './batch-outputs-plugin';
package/src/index.ts CHANGED
@@ -1,4 +1,10 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  export * from './components';
2
7
  export * from './effects';
3
8
  export * from './utils';
4
9
  export * from './typings';
10
+ export * from './form-plugins';
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  export interface IFlowConstantValue {
2
7
  type: 'constant';
3
8
  content?: string | number | boolean;
@@ -1,2 +1,7 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  export * from './flow-value';
2
7
  export * from './json-schema';
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  export type JsonSchemaBasicType =
2
7
  | 'boolean'
3
8
  | 'string'
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  import { isObject } from 'lodash';
2
7
 
3
8
  interface LegacyFlowRefValueSchema {
@@ -1,2 +1,7 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  export * from './format-legacy-refs';
2
7
  export * from './json-schema';
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
3
+ * SPDX-License-Identifier: MIT
4
+ */
5
+
1
6
  import { get } from 'lodash';
2
7
  import { ASTFactory, ASTKind, ASTMatch, ASTNode, ASTNodeJSON, BaseType } from '@flowgram.ai/editor';
3
8
 
@@ -37,7 +42,10 @@ export namespace JsonSchemaUtils {
37
42
  .map(([key, _property]) => ({
38
43
  key,
39
44
  type: schemaToAST(_property),
40
- meta: { description: _property.description },
45
+ meta: {
46
+ title: _property.title,
47
+ description: _property.description,
48
+ },
41
49
  })),
42
50
  });
43
51
  case 'array':
@@ -109,7 +117,18 @@ export namespace JsonSchemaUtils {
109
117
  type: 'object',
110
118
  properties: drilldown
111
119
  ? Object.fromEntries(
112
- Object.entries(typeAST.properties).map(([key, value]) => [key, astToSchema(value)!])
120
+ typeAST.properties.map((property) => {
121
+ const schema = astToSchema(property.type);
122
+
123
+ if (property.meta?.title && schema) {
124
+ schema.title = property.meta.title;
125
+ }
126
+ if (property.meta?.description && schema) {
127
+ schema.description = property.meta.description;
128
+ }
129
+
130
+ return [property.key, schema!];
131
+ })
113
132
  )
114
133
  : {},
115
134
  };