@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.
Files changed (97) hide show
  1. package/bin/index.ts +0 -11
  2. package/bin/materials.ts +29 -2
  3. package/dist/esm/chunk-727SU246.js +13 -0
  4. package/dist/esm/chunk-727SU246.js.map +1 -0
  5. package/dist/esm/chunk-DEZUEMUM.js +284 -0
  6. package/dist/esm/chunk-DEZUEMUM.js.map +1 -0
  7. package/dist/esm/chunk-DUOXDOUE.js +477 -0
  8. package/dist/esm/chunk-DUOXDOUE.js.map +1 -0
  9. package/dist/esm/editor-6UMULJYB.js +180 -0
  10. package/dist/esm/editor-6UMULJYB.js.map +1 -0
  11. package/dist/esm/editor-EYOQTGMT.js +282 -0
  12. package/dist/esm/editor-EYOQTGMT.js.map +1 -0
  13. package/dist/esm/editor-OXPGKPF5.js +167 -0
  14. package/dist/esm/editor-OXPGKPF5.js.map +1 -0
  15. package/dist/esm/editor-VO6YAXRC.js +249 -0
  16. package/dist/esm/editor-VO6YAXRC.js.map +1 -0
  17. package/dist/esm/editor-XYLKTB6L.js +365 -0
  18. package/dist/esm/editor-XYLKTB6L.js.map +1 -0
  19. package/dist/esm/index.js +1110 -2306
  20. package/dist/esm/index.js.map +1 -1
  21. package/dist/index.d.mts +298 -59
  22. package/dist/index.d.ts +298 -59
  23. package/dist/index.js +3932 -2681
  24. package/dist/index.js.map +1 -1
  25. package/package.json +9 -8
  26. package/src/components/batch-outputs/index.tsx +3 -2
  27. package/src/components/code-editor/editor.tsx +89 -0
  28. package/src/components/code-editor/index.tsx +5 -89
  29. package/src/components/code-editor/language-features.ts +18 -18
  30. package/src/components/code-editor/theme/dark.ts +49 -30
  31. package/src/components/code-editor/theme/light.ts +56 -32
  32. package/src/components/code-editor-mini/index.tsx +2 -2
  33. package/src/components/condition-row/constants.ts +8 -0
  34. package/src/components/condition-row/index.tsx +4 -0
  35. package/src/components/db-condition-row/hooks/use-left.tsx +66 -0
  36. package/src/components/db-condition-row/hooks/use-op.tsx +59 -0
  37. package/src/components/db-condition-row/index.tsx +93 -0
  38. package/src/components/db-condition-row/styles.tsx +43 -0
  39. package/src/components/db-condition-row/types.ts +34 -0
  40. package/src/components/display-flow-value/index.tsx +2 -12
  41. package/src/components/display-inputs-values/index.tsx +44 -6
  42. package/src/components/dynamic-value-input/hooks.ts +25 -4
  43. package/src/components/dynamic-value-input/index.tsx +21 -12
  44. package/src/components/dynamic-value-input/styles.tsx +14 -4
  45. package/src/components/index.ts +3 -0
  46. package/src/components/inputs-values/index.tsx +14 -3
  47. package/src/components/inputs-values/styles.tsx +1 -1
  48. package/src/components/inputs-values-tree/hooks/use-child-list.tsx +76 -0
  49. package/src/components/inputs-values-tree/index.tsx +62 -0
  50. package/src/components/inputs-values-tree/row.tsx +177 -0
  51. package/src/components/inputs-values-tree/styles.tsx +128 -0
  52. package/src/components/inputs-values-tree/types.ts +21 -0
  53. package/src/components/json-editor-with-variables/editor.tsx +69 -0
  54. package/src/components/json-editor-with-variables/extensions/variable-tag.tsx +6 -5
  55. package/src/components/json-editor-with-variables/index.tsx +5 -59
  56. package/src/components/json-schema-editor/default-value.tsx +1 -3
  57. package/src/components/json-schema-editor/hooks.tsx +14 -3
  58. package/src/components/json-schema-editor/index.tsx +18 -58
  59. package/src/components/json-schema-editor/styles.tsx +12 -55
  60. package/src/components/json-schema-editor/types.ts +0 -1
  61. package/src/components/prompt-editor/editor.tsx +81 -0
  62. package/src/components/prompt-editor/index.tsx +5 -62
  63. package/src/components/prompt-editor-with-inputs/editor.tsx +25 -0
  64. package/src/components/prompt-editor-with-inputs/extensions/inputs-tree.tsx +11 -0
  65. package/src/components/prompt-editor-with-inputs/index.tsx +5 -16
  66. package/src/components/prompt-editor-with-inputs/inputs-picker.tsx +34 -17
  67. package/src/components/prompt-editor-with-variables/editor.tsx +22 -0
  68. package/src/components/prompt-editor-with-variables/extensions/variable-tag.tsx +12 -20
  69. package/src/components/prompt-editor-with-variables/extensions/variable-tree.tsx +13 -1
  70. package/src/components/prompt-editor-with-variables/index.tsx +5 -13
  71. package/src/components/type-selector/index.tsx +12 -2
  72. package/src/components/variable-selector/context.tsx +28 -0
  73. package/src/components/variable-selector/index.tsx +10 -1
  74. package/src/components/variable-selector/use-variable-tree.tsx +3 -3
  75. package/src/effects/auto-rename-ref/index.ts +7 -54
  76. package/src/effects/validate-when-variable-sync/index.ts +1 -1
  77. package/src/form-plugins/infer-assign-plugin/index.ts +1 -1
  78. package/src/form-plugins/infer-inputs-plugin/index.ts +4 -76
  79. package/src/hooks/use-object-list/index.tsx +35 -7
  80. package/src/index.ts +1 -0
  81. package/src/plugins/json-schema-preset/manager.ts +1 -0
  82. package/src/plugins/json-schema-preset/type-definition/date-time.tsx +25 -0
  83. package/src/plugins/json-schema-preset/type-definition/index.tsx +2 -0
  84. package/src/plugins/json-schema-preset/type-definition/string.tsx +18 -9
  85. package/src/shared/flow-value/index.ts +6 -0
  86. package/src/shared/flow-value/schema.ts +38 -0
  87. package/src/shared/flow-value/utils.ts +201 -0
  88. package/src/shared/format-legacy-refs/index.ts +1 -1
  89. package/src/shared/index.ts +3 -0
  90. package/src/shared/lazy-suspense/index.tsx +28 -0
  91. package/src/shared/polyfill-create-root/index.tsx +33 -0
  92. package/src/typings/flow-value/index.ts +3 -1
  93. package/src/validate/validate-flow-value/index.tsx +4 -16
  94. package/src/components/json-schema-editor/components/blur-input.tsx +0 -27
  95. package/src/plugins/disable-declaration-plugin/config.json +0 -5
  96. package/src/plugins/json-schema-preset/config.json +0 -9
  97. /package/src/components/{inputs-values/components/blur-input.tsx → blur-input/index.tsx} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/prompt-editor-with-inputs/editor.tsx","../../src/components/prompt-editor-with-inputs/extensions/inputs-tree.tsx","../../src/components/prompt-editor-with-inputs/inputs-picker.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React from 'react';\n\nimport { PromptEditor, PromptEditorPropsType } from '@/components/prompt-editor';\n\nimport { InputsTree } from './extensions/inputs-tree';\n\nexport interface PromptEditorWithInputsProps extends PromptEditorPropsType {\n inputsValues: any;\n}\n\nexport function PromptEditorWithInputs({\n inputsValues,\n ...restProps\n}: PromptEditorWithInputsProps) {\n return (\n <PromptEditor {...restProps}>\n <InputsTree inputsValues={inputsValues} />\n </PromptEditor>\n );\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React, { useEffect, useState } from 'react';\n\nimport { Popover } from '@douyinfe/semi-ui';\nimport {\n Mention,\n MentionOpenChangeEvent,\n getCurrentMentionReplaceRange,\n useEditor,\n PositionMirror,\n} from '@coze-editor/editor/react';\nimport { EditorAPI } from '@coze-editor/editor/preset-prompt';\n\nimport { IFlowValue } from '@/typings';\n\nimport { InputsPicker } from '../inputs-picker';\n\nexport function InputsTree({ inputsValues }: { inputsValues: Record<string, IFlowValue> }) {\n const [posKey, setPosKey] = useState('');\n const [visible, setVisible] = useState(false);\n const [position, setPosition] = useState(-1);\n const editor = useEditor<EditorAPI>();\n\n function insert(variablePath: string) {\n const range = getCurrentMentionReplaceRange(editor.$view.state);\n\n if (!range) {\n return;\n }\n\n /**\n * When user input {{xxxx}}, {{{xxx}}}(more brackets if possible), replace all brackets with {{xxxx}}\n */\n let { from, to } = range;\n while (editor.$view.state.doc.sliceString(from - 1, from) === '{') {\n from--;\n }\n while (editor.$view.state.doc.sliceString(to, to + 1) === '}') {\n to++;\n }\n\n editor.replaceText({\n ...range,\n text: '{{' + variablePath + '}}',\n });\n\n setVisible(false);\n }\n\n function handleOpenChange(e: MentionOpenChangeEvent) {\n setPosition(e.state.selection.main.head);\n setVisible(e.value);\n }\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n }, [editor, visible]);\n\n return (\n <>\n <Mention triggerCharacters={['{', '{}', '@']} onOpenChange={handleOpenChange} />\n\n <Popover\n visible={visible}\n trigger=\"custom\"\n position=\"topLeft\"\n rePosKey={posKey}\n content={\n <div style={{ width: 300 }}>\n <InputsPicker\n inputsValues={inputsValues}\n onSelect={(v) => {\n insert(v);\n }}\n />\n </div>\n }\n >\n {/* PositionMirror allows the Popover to appear at the specified cursor position */}\n <PositionMirror\n position={position}\n // When Doc scroll, update position\n onChange={() => setPosKey(String(Math.random()))}\n />\n </Popover>\n </>\n );\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React, { useMemo } from 'react';\n\nimport { isPlainObject, last } from 'lodash-es';\nimport {\n type ArrayType,\n ASTMatch,\n type BaseType,\n type BaseVariableField,\n useScopeAvailable,\n} from '@flowgram.ai/editor';\nimport { TreeNodeData } from '@douyinfe/semi-ui/lib/es/tree';\nimport { Tree } from '@douyinfe/semi-ui';\n\nimport { FlowValueUtils } from '@/shared';\n\ntype VariableField = BaseVariableField<{ icon?: string | JSX.Element; title?: string }>;\n\nexport function InputsPicker({\n inputsValues,\n onSelect,\n}: {\n inputsValues: any;\n onSelect: (v: string) => void;\n}) {\n const available = useScopeAvailable();\n\n const getArrayDrilldown = (type: ArrayType, depth = 1): { type: BaseType; depth: number } => {\n if (ASTMatch.isArray(type.items)) {\n return getArrayDrilldown(type.items, depth + 1);\n }\n\n return { type: type.items, depth: depth };\n };\n\n const renderVariable = (variable: VariableField, keyPath: string[]): TreeNodeData => {\n let type = variable?.type;\n\n let children: TreeNodeData[] | undefined;\n\n if (ASTMatch.isObject(type)) {\n children = (type.properties || [])\n .map((_property) => renderVariable(_property as VariableField, [...keyPath, _property.key]))\n .filter(Boolean) as TreeNodeData[];\n }\n\n if (ASTMatch.isArray(type)) {\n const drilldown = getArrayDrilldown(type);\n\n if (ASTMatch.isObject(drilldown.type)) {\n children = (drilldown.type.properties || [])\n .map((_property) =>\n renderVariable(_property as VariableField, [\n ...keyPath,\n ...new Array(drilldown.depth).fill('[0]'),\n _property.key,\n ])\n )\n .filter(Boolean) as TreeNodeData[];\n }\n }\n\n const key = keyPath\n .map((_key, idx) => (_key === '[0]' || idx === 0 ? _key : `.${_key}`))\n .join('');\n\n return {\n key: key,\n label: last(keyPath),\n value: key,\n children,\n };\n };\n\n const getTreeData = (value: any, keyPath: string[]): TreeNodeData | undefined => {\n const currKey = keyPath.join('.');\n\n if (FlowValueUtils.isFlowValue(value)) {\n if (FlowValueUtils.isRef(value)) {\n const variable = available.getByKeyPath(value.content || []);\n if (variable) {\n return renderVariable(variable, keyPath);\n }\n }\n return {\n key: currKey,\n value: currKey,\n label: last(keyPath),\n };\n }\n\n if (isPlainObject(value)) {\n return {\n key: currKey,\n value: currKey,\n label: last(keyPath),\n children: Object.entries(value)\n .map(([key, value]) => getTreeData(value, [...keyPath, key])!)\n .filter(Boolean),\n };\n }\n };\n\n const treeData: TreeNodeData[] = useMemo(\n () =>\n Object.entries(inputsValues)\n .map(([key, value]) => getTreeData(value, [key])!)\n .filter(Boolean),\n []\n );\n\n return <Tree treeData={treeData} onSelect={(v) => onSelect(v)} />;\n}\n"],"mappings":"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","names":["React","React","value","React","React"]}
@@ -0,0 +1,249 @@
1
+ import {
2
+ PromptEditor
3
+ } from "./chunk-727SU246.js";
4
+ import {
5
+ useVariableTree
6
+ } from "./chunk-DUOXDOUE.js";
7
+ import {
8
+ polyfillCreateRoot
9
+ } from "./chunk-DEZUEMUM.js";
10
+
11
+ // src/components/prompt-editor-with-variables/editor.tsx
12
+ import React3 from "react";
13
+
14
+ // src/components/prompt-editor-with-variables/extensions/variable-tree.tsx
15
+ import React, { useEffect, useState } from "react";
16
+ import { Popover, Tree } from "@douyinfe/semi-ui";
17
+ import {
18
+ Mention,
19
+ getCurrentMentionReplaceRange,
20
+ useEditor,
21
+ PositionMirror
22
+ } from "@coze-editor/editor/react";
23
+ function VariableTree() {
24
+ const [posKey, setPosKey] = useState("");
25
+ const [visible, setVisible] = useState(false);
26
+ const [position, setPosition] = useState(-1);
27
+ const editor = useEditor();
28
+ function insert(variablePath) {
29
+ const range = getCurrentMentionReplaceRange(editor.$view.state);
30
+ if (!range) {
31
+ return;
32
+ }
33
+ let { from, to } = range;
34
+ while (editor.$view.state.doc.sliceString(from - 1, from) === "{") {
35
+ from--;
36
+ }
37
+ while (editor.$view.state.doc.sliceString(to, to + 1) === "}") {
38
+ to++;
39
+ }
40
+ editor.replaceText({
41
+ from,
42
+ to,
43
+ text: "{{" + variablePath + "}}"
44
+ });
45
+ setVisible(false);
46
+ }
47
+ function handleOpenChange(e) {
48
+ setPosition(e.state.selection.main.head);
49
+ setVisible(e.value);
50
+ }
51
+ useEffect(() => {
52
+ if (!editor) {
53
+ return;
54
+ }
55
+ }, [editor, visible]);
56
+ const treeData = useVariableTree({});
57
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Mention, { triggerCharacters: ["{", "{}", "@"], onOpenChange: handleOpenChange }), /* @__PURE__ */ React.createElement(
58
+ Popover,
59
+ {
60
+ visible,
61
+ trigger: "custom",
62
+ position: "topLeft",
63
+ rePosKey: posKey,
64
+ content: /* @__PURE__ */ React.createElement("div", { style: { width: 300 } }, /* @__PURE__ */ React.createElement(
65
+ Tree,
66
+ {
67
+ treeData,
68
+ onSelect: (v) => {
69
+ insert(v);
70
+ }
71
+ }
72
+ ))
73
+ },
74
+ /* @__PURE__ */ React.createElement(
75
+ PositionMirror,
76
+ {
77
+ position,
78
+ onChange: () => setPosKey(String(Math.random()))
79
+ }
80
+ )
81
+ ));
82
+ }
83
+
84
+ // src/components/prompt-editor-with-variables/extensions/variable-tag.tsx
85
+ import React2, { useLayoutEffect } from "react";
86
+ import { isEqual, last } from "lodash-es";
87
+ import {
88
+ Disposable,
89
+ DisposableCollection,
90
+ useCurrentScope
91
+ } from "@flowgram.ai/editor";
92
+ import { Popover as Popover2 } from "@douyinfe/semi-ui";
93
+ import { IconIssueStroked } from "@douyinfe/semi-icons";
94
+ import { useInjector } from "@coze-editor/editor/react";
95
+ import {
96
+ Decoration,
97
+ EditorView,
98
+ MatchDecorator,
99
+ ViewPlugin,
100
+ WidgetType
101
+ } from "@codemirror/view";
102
+
103
+ // src/components/prompt-editor-with-variables/styles.tsx
104
+ import styled from "styled-components";
105
+ import { Tag } from "@douyinfe/semi-ui";
106
+ var UIRootTitle = styled.div`
107
+ margin-right: 4px;
108
+ min-width: 20px;
109
+ overflow: hidden;
110
+ text-overflow: ellipsis;
111
+ white-space: nowrap;
112
+ color: var(--semi-color-text-2);
113
+ `;
114
+ var UIVarName = styled.div`
115
+ overflow: hidden;
116
+ text-overflow: ellipsis;
117
+ white-space: nowrap;
118
+ `;
119
+ var UITag = styled(Tag)`
120
+ display: inline-flex;
121
+ align-items: center;
122
+ justify-content: flex-start;
123
+ max-width: 300px;
124
+
125
+ & .semi-tag-content-center {
126
+ justify-content: flex-start;
127
+ }
128
+
129
+ &.semi-tag {
130
+ margin: 0 5px;
131
+ }
132
+ `;
133
+ var UIPopoverContent = styled.div`
134
+ padding: 10px;
135
+ display: inline-flex;
136
+ align-items: center;
137
+ justify-content: flex-start;
138
+ `;
139
+
140
+ // src/components/prompt-editor-with-variables/extensions/variable-tag.tsx
141
+ var VariableTagWidget = class extends WidgetType {
142
+ constructor({ keyPath, scope }) {
143
+ super();
144
+ this.toDispose = new DisposableCollection();
145
+ this.renderIcon = (icon) => {
146
+ if (typeof icon === "string") {
147
+ return /* @__PURE__ */ React2.createElement("img", { style: { marginRight: 8 }, width: 12, height: 12, src: icon });
148
+ }
149
+ return icon;
150
+ };
151
+ this.keyPath = keyPath;
152
+ this.scope = scope;
153
+ }
154
+ renderVariable(v) {
155
+ if (!v) {
156
+ this.root.render(
157
+ /* @__PURE__ */ React2.createElement(UITag, { prefixIcon: /* @__PURE__ */ React2.createElement(IconIssueStroked, null), color: "amber" }, "Unknown")
158
+ );
159
+ return;
160
+ }
161
+ const rootField = last(v.parentFields);
162
+ const rootTitle = /* @__PURE__ */ React2.createElement(UIRootTitle, null, rootField?.meta.title ? `${rootField.meta.title} -` : "");
163
+ const rootIcon = this.renderIcon(rootField?.meta.icon);
164
+ this.root.render(
165
+ /* @__PURE__ */ React2.createElement(
166
+ Popover2,
167
+ {
168
+ content: /* @__PURE__ */ React2.createElement(UIPopoverContent, null, rootIcon, rootTitle, /* @__PURE__ */ React2.createElement(UIVarName, null, v?.keyPath.slice(1).join(".")))
169
+ },
170
+ /* @__PURE__ */ React2.createElement(UITag, { prefixIcon: rootIcon }, rootTitle, /* @__PURE__ */ React2.createElement(UIVarName, null, v?.key))
171
+ )
172
+ );
173
+ }
174
+ toDOM(view) {
175
+ const dom = document.createElement("span");
176
+ this.root = polyfillCreateRoot(dom);
177
+ this.toDispose.push(
178
+ Disposable.create(() => {
179
+ this.root.unmount();
180
+ })
181
+ );
182
+ this.toDispose.push(
183
+ this.scope.available.trackByKeyPath(
184
+ this.keyPath,
185
+ (v) => {
186
+ this.renderVariable(v);
187
+ },
188
+ { triggerOnInit: false }
189
+ )
190
+ );
191
+ this.renderVariable(this.scope.available.getByKeyPath(this.keyPath));
192
+ return dom;
193
+ }
194
+ eq(other) {
195
+ return isEqual(this.keyPath, other.keyPath);
196
+ }
197
+ ignoreEvent() {
198
+ return false;
199
+ }
200
+ destroy(dom) {
201
+ this.toDispose.dispose();
202
+ }
203
+ };
204
+ function VariableTagInject() {
205
+ const injector = useInjector();
206
+ const scope = useCurrentScope();
207
+ useLayoutEffect(() => {
208
+ const atMatcher = new MatchDecorator({
209
+ regexp: /\{\{([^\}\{]+)\}\}/g,
210
+ decoration: (match) => Decoration.replace({
211
+ widget: new VariableTagWidget({
212
+ keyPath: match[1]?.split(".") ?? [],
213
+ scope
214
+ })
215
+ })
216
+ });
217
+ return injector.inject([
218
+ ViewPlugin.fromClass(
219
+ class {
220
+ constructor(view) {
221
+ this.view = view;
222
+ this.decorations = atMatcher.createDeco(view);
223
+ }
224
+ update() {
225
+ this.decorations = atMatcher.createDeco(this.view);
226
+ }
227
+ },
228
+ {
229
+ decorations: (p) => p.decorations,
230
+ provide(p) {
231
+ return EditorView.atomicRanges.of(
232
+ (view) => view.plugin(p)?.decorations ?? Decoration.none
233
+ );
234
+ }
235
+ }
236
+ )
237
+ ]);
238
+ }, [injector]);
239
+ return null;
240
+ }
241
+
242
+ // src/components/prompt-editor-with-variables/editor.tsx
243
+ function PromptEditorWithVariables(props) {
244
+ return /* @__PURE__ */ React3.createElement(PromptEditor, { ...props }, /* @__PURE__ */ React3.createElement(VariableTree, null), /* @__PURE__ */ React3.createElement(VariableTagInject, null));
245
+ }
246
+ export {
247
+ PromptEditorWithVariables
248
+ };
249
+ //# sourceMappingURL=editor-VO6YAXRC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/components/prompt-editor-with-variables/editor.tsx","../../src/components/prompt-editor-with-variables/extensions/variable-tree.tsx","../../src/components/prompt-editor-with-variables/extensions/variable-tag.tsx","../../src/components/prompt-editor-with-variables/styles.tsx"],"sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React from 'react';\n\nimport { PromptEditor, PromptEditorPropsType } from '@/components/prompt-editor';\n\nimport { VariableTree } from './extensions/variable-tree';\nimport { VariableTagInject } from './extensions/variable-tag';\n\nexport interface PromptEditorWithVariablesProps extends PromptEditorPropsType {}\n\nexport function PromptEditorWithVariables(props: PromptEditorWithVariablesProps) {\n return (\n <PromptEditor {...props}>\n <VariableTree />\n <VariableTagInject />\n </PromptEditor>\n );\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React, { useEffect, useState } from 'react';\n\nimport { Popover, Tree } from '@douyinfe/semi-ui';\nimport {\n Mention,\n MentionOpenChangeEvent,\n getCurrentMentionReplaceRange,\n useEditor,\n PositionMirror,\n} from '@coze-editor/editor/react';\nimport { EditorAPI } from '@coze-editor/editor/preset-prompt';\n\nimport { useVariableTree } from '@/components/variable-selector';\n\nexport function VariableTree() {\n const [posKey, setPosKey] = useState('');\n const [visible, setVisible] = useState(false);\n const [position, setPosition] = useState(-1);\n const editor = useEditor<EditorAPI>();\n\n function insert(variablePath: string) {\n const range = getCurrentMentionReplaceRange(editor.$view.state);\n\n if (!range) {\n return;\n }\n\n /**\n * When user input {{xxxx}}, {{{xxx}}}(more brackets if possible), replace all brackets with {{xxxx}}\n */\n let { from, to } = range;\n while (editor.$view.state.doc.sliceString(from - 1, from) === '{') {\n from--;\n }\n while (editor.$view.state.doc.sliceString(to, to + 1) === '}') {\n to++;\n }\n\n editor.replaceText({\n from,\n to,\n text: '{{' + variablePath + '}}',\n });\n\n setVisible(false);\n }\n\n function handleOpenChange(e: MentionOpenChangeEvent) {\n setPosition(e.state.selection.main.head);\n setVisible(e.value);\n }\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n }, [editor, visible]);\n\n const treeData = useVariableTree({});\n\n return (\n <>\n <Mention triggerCharacters={['{', '{}', '@']} onOpenChange={handleOpenChange} />\n\n <Popover\n visible={visible}\n trigger=\"custom\"\n position=\"topLeft\"\n rePosKey={posKey}\n content={\n <div style={{ width: 300 }}>\n <Tree\n treeData={treeData}\n onSelect={(v) => {\n insert(v);\n }}\n />\n </div>\n }\n >\n {/* PositionMirror allows the Popover to appear at the specified cursor position */}\n <PositionMirror\n position={position}\n // When Doc scroll, update position\n onChange={() => setPosKey(String(Math.random()))}\n />\n </Popover>\n </>\n );\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport React, { useLayoutEffect } from 'react';\n\nimport { isEqual, last } from 'lodash-es';\nimport {\n BaseVariableField,\n Disposable,\n DisposableCollection,\n Scope,\n useCurrentScope,\n} from '@flowgram.ai/editor';\nimport { Popover } from '@douyinfe/semi-ui';\nimport { IconIssueStroked } from '@douyinfe/semi-icons';\nimport { useInjector } from '@coze-editor/editor/react';\nimport {\n Decoration,\n DecorationSet,\n EditorView,\n MatchDecorator,\n ViewPlugin,\n WidgetType,\n} from '@codemirror/view';\n\nimport { IPolyfillRoot, polyfillCreateRoot } from '@/shared';\n\nimport { UIPopoverContent, UIRootTitle, UITag, UIVarName } from '../styles';\n\nclass VariableTagWidget extends WidgetType {\n keyPath?: string[];\n\n toDispose = new DisposableCollection();\n\n scope: Scope;\n\n root: IPolyfillRoot;\n\n constructor({ keyPath, scope }: { keyPath?: string[]; scope: Scope }) {\n super();\n\n this.keyPath = keyPath;\n this.scope = scope;\n }\n\n renderIcon = (icon: string | JSX.Element) => {\n if (typeof icon === 'string') {\n return <img style={{ marginRight: 8 }} width={12} height={12} src={icon} />;\n }\n\n return icon;\n };\n\n renderVariable(v?: BaseVariableField) {\n if (!v) {\n this.root.render(\n <UITag prefixIcon={<IconIssueStroked />} color=\"amber\">\n Unknown\n </UITag>\n );\n return;\n }\n\n const rootField = last(v.parentFields);\n\n const rootTitle = (\n <UIRootTitle>{rootField?.meta.title ? `${rootField.meta.title} -` : ''}</UIRootTitle>\n );\n const rootIcon = this.renderIcon(rootField?.meta.icon);\n\n this.root.render(\n <Popover\n content={\n <UIPopoverContent>\n {rootIcon}\n {rootTitle}\n <UIVarName>{v?.keyPath.slice(1).join('.')}</UIVarName>\n </UIPopoverContent>\n }\n >\n <UITag prefixIcon={rootIcon}>\n {rootTitle}\n <UIVarName>{v?.key}</UIVarName>\n </UITag>\n </Popover>\n );\n }\n\n toDOM(view: EditorView): HTMLElement {\n const dom = document.createElement('span');\n\n this.root = polyfillCreateRoot(dom);\n\n this.toDispose.push(\n Disposable.create(() => {\n this.root.unmount();\n })\n );\n\n this.toDispose.push(\n this.scope.available.trackByKeyPath(\n this.keyPath,\n (v) => {\n this.renderVariable(v);\n },\n { triggerOnInit: false }\n )\n );\n\n this.renderVariable(this.scope.available.getByKeyPath(this.keyPath));\n\n return dom;\n }\n\n eq(other: VariableTagWidget) {\n return isEqual(this.keyPath, other.keyPath);\n }\n\n ignoreEvent(): boolean {\n return false;\n }\n\n destroy(dom: HTMLElement): void {\n this.toDispose.dispose();\n }\n}\n\nexport function VariableTagInject() {\n const injector = useInjector();\n\n const scope = useCurrentScope();\n\n // 基于 {{var}} 的正则进行匹配,匹配后进行自定义渲染\n useLayoutEffect(() => {\n const atMatcher = new MatchDecorator({\n regexp: /\\{\\{([^\\}\\{]+)\\}\\}/g,\n decoration: (match) =>\n Decoration.replace({\n widget: new VariableTagWidget({\n keyPath: match[1]?.split('.') ?? [],\n scope,\n }),\n }),\n });\n\n return injector.inject([\n ViewPlugin.fromClass(\n class {\n decorations: DecorationSet;\n\n constructor(private view: EditorView) {\n this.decorations = atMatcher.createDeco(view);\n }\n\n update() {\n this.decorations = atMatcher.createDeco(this.view);\n }\n },\n {\n decorations: (p) => p.decorations,\n provide(p) {\n return EditorView.atomicRanges.of(\n (view) => view.plugin(p)?.decorations ?? Decoration.none\n );\n },\n }\n ),\n ]);\n }, [injector]);\n\n return null;\n}\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport styled from 'styled-components';\nimport { Tag } from '@douyinfe/semi-ui';\n\nexport const UIRootTitle = styled.div`\n margin-right: 4px;\n min-width: 20px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--semi-color-text-2);\n`;\n\nexport const UIVarName = styled.div`\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n`;\n\nexport const UITag = styled(Tag)`\n display: inline-flex;\n align-items: center;\n justify-content: flex-start;\n max-width: 300px;\n\n & .semi-tag-content-center {\n justify-content: flex-start;\n }\n\n &.semi-tag {\n margin: 0 5px;\n }\n`;\n\nexport const UIPopoverContent = styled.div`\n padding: 10px;\n display: inline-flex;\n align-items: center;\n justify-content: flex-start;\n`;\n"],"mappings":";;;;;;;;;;;AAKA,OAAOA,YAAW;;;ACAlB,OAAO,SAAS,WAAW,gBAAgB;AAE3C,SAAS,SAAS,YAAY;AAC9B;AAAA,EACE;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAKA,SAAS,eAAe;AAC7B,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,EAAE;AACvC,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,EAAE;AAC3C,QAAM,SAAS,UAAqB;AAEpC,WAAS,OAAO,cAAsB;AACpC,UAAM,QAAQ,8BAA8B,OAAO,MAAM,KAAK;AAE9D,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AAKA,QAAI,EAAE,MAAM,GAAG,IAAI;AACnB,WAAO,OAAO,MAAM,MAAM,IAAI,YAAY,OAAO,GAAG,IAAI,MAAM,KAAK;AACjE;AAAA,IACF;AACA,WAAO,OAAO,MAAM,MAAM,IAAI,YAAY,IAAI,KAAK,CAAC,MAAM,KAAK;AAC7D;AAAA,IACF;AAEA,WAAO,YAAY;AAAA,MACjB;AAAA,MACA;AAAA,MACA,MAAM,OAAO,eAAe;AAAA,IAC9B,CAAC;AAED,eAAW,KAAK;AAAA,EAClB;AAEA,WAAS,iBAAiB,GAA2B;AACnD,gBAAY,EAAE,MAAM,UAAU,KAAK,IAAI;AACvC,eAAW,EAAE,KAAK;AAAA,EACpB;AAEA,YAAU,MAAM;AACd,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAAA,EACF,GAAG,CAAC,QAAQ,OAAO,CAAC;AAEpB,QAAM,WAAW,gBAAgB,CAAC,CAAC;AAEnC,SACE,0DACE,oCAAC,WAAQ,mBAAmB,CAAC,KAAK,MAAM,GAAG,GAAG,cAAc,kBAAkB,GAE9E;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,SAAQ;AAAA,MACR,UAAS;AAAA,MACT,UAAU;AAAA,MACV,SACE,oCAAC,SAAI,OAAO,EAAE,OAAO,IAAI,KACvB;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,UAAU,CAAC,MAAM;AACf,mBAAO,CAAC;AAAA,UACV;AAAA;AAAA,MACF,CACF;AAAA;AAAA,IAIF;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QAEA,UAAU,MAAM,UAAU,OAAO,KAAK,OAAO,CAAC,CAAC;AAAA;AAAA,IACjD;AAAA,EACF,CACF;AAEJ;;;ACzFA,OAAOC,UAAS,uBAAuB;AAEvC,SAAS,SAAS,YAAY;AAC9B;AAAA,EAEE;AAAA,EACA;AAAA,EAEA;AAAA,OACK;AACP,SAAS,WAAAC,gBAAe;AACxB,SAAS,wBAAwB;AACjC,SAAS,mBAAmB;AAC5B;AAAA,EACE;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACpBP,OAAO,YAAY;AACnB,SAAS,WAAW;AAEb,IAAM,cAAc,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAS3B,IAAM,YAAY,OAAO;AAAA;AAAA;AAAA;AAAA;AAMzB,IAAM,QAAQ,OAAO,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAexB,IAAM,mBAAmB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;;;ADPvC,IAAM,oBAAN,cAAgC,WAAW;AAAA,EASzC,YAAY,EAAE,SAAS,MAAM,GAAyC;AACpE,UAAM;AAPR,qBAAY,IAAI,qBAAqB;AAarC,sBAAa,CAAC,SAA+B;AAC3C,UAAI,OAAO,SAAS,UAAU;AAC5B,eAAO,gBAAAC,OAAA,cAAC,SAAI,OAAO,EAAE,aAAa,EAAE,GAAG,OAAO,IAAI,QAAQ,IAAI,KAAK,MAAM;AAAA,MAC3E;AAEA,aAAO;AAAA,IACT;AAVE,SAAK,UAAU;AACf,SAAK,QAAQ;AAAA,EACf;AAAA,EAUA,eAAe,GAAuB;AACpC,QAAI,CAAC,GAAG;AACN,WAAK,KAAK;AAAA,QACR,gBAAAA,OAAA,cAAC,SAAM,YAAY,gBAAAA,OAAA,cAAC,sBAAiB,GAAI,OAAM,WAAQ,SAEvD;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,YAAY,KAAK,EAAE,YAAY;AAErC,UAAM,YACJ,gBAAAA,OAAA,cAAC,mBAAa,WAAW,KAAK,QAAQ,GAAG,UAAU,KAAK,KAAK,OAAO,EAAG;AAEzE,UAAM,WAAW,KAAK,WAAW,WAAW,KAAK,IAAI;AAErD,SAAK,KAAK;AAAA,MACR,gBAAAA,OAAA;AAAA,QAACC;AAAA,QAAA;AAAA,UACC,SACE,gBAAAD,OAAA,cAAC,wBACE,UACA,WACD,gBAAAA,OAAA,cAAC,iBAAW,GAAG,QAAQ,MAAM,CAAC,EAAE,KAAK,GAAG,CAAE,CAC5C;AAAA;AAAA,QAGF,gBAAAA,OAAA,cAAC,SAAM,YAAY,YAChB,WACD,gBAAAA,OAAA,cAAC,iBAAW,GAAG,GAAI,CACrB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,MAA+B;AACnC,UAAM,MAAM,SAAS,cAAc,MAAM;AAEzC,SAAK,OAAO,mBAAmB,GAAG;AAElC,SAAK,UAAU;AAAA,MACb,WAAW,OAAO,MAAM;AACtB,aAAK,KAAK,QAAQ;AAAA,MACpB,CAAC;AAAA,IACH;AAEA,SAAK,UAAU;AAAA,MACb,KAAK,MAAM,UAAU;AAAA,QACnB,KAAK;AAAA,QACL,CAAC,MAAM;AACL,eAAK,eAAe,CAAC;AAAA,QACvB;AAAA,QACA,EAAE,eAAe,MAAM;AAAA,MACzB;AAAA,IACF;AAEA,SAAK,eAAe,KAAK,MAAM,UAAU,aAAa,KAAK,OAAO,CAAC;AAEnE,WAAO;AAAA,EACT;AAAA,EAEA,GAAG,OAA0B;AAC3B,WAAO,QAAQ,KAAK,SAAS,MAAM,OAAO;AAAA,EAC5C;AAAA,EAEA,cAAuB;AACrB,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,KAAwB;AAC9B,SAAK,UAAU,QAAQ;AAAA,EACzB;AACF;AAEO,SAAS,oBAAoB;AAClC,QAAM,WAAW,YAAY;AAE7B,QAAM,QAAQ,gBAAgB;AAG9B,kBAAgB,MAAM;AACpB,UAAM,YAAY,IAAI,eAAe;AAAA,MACnC,QAAQ;AAAA,MACR,YAAY,CAAC,UACX,WAAW,QAAQ;AAAA,QACjB,QAAQ,IAAI,kBAAkB;AAAA,UAC5B,SAAS,MAAM,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC;AAAA,UAClC;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACL,CAAC;AAED,WAAO,SAAS,OAAO;AAAA,MACrB,WAAW;AAAA,QACT,MAAM;AAAA,UAGJ,YAAoB,MAAkB;AAAlB;AAClB,iBAAK,cAAc,UAAU,WAAW,IAAI;AAAA,UAC9C;AAAA,UAEA,SAAS;AACP,iBAAK,cAAc,UAAU,WAAW,KAAK,IAAI;AAAA,UACnD;AAAA,QACF;AAAA,QACA;AAAA,UACE,aAAa,CAAC,MAAM,EAAE;AAAA,UACtB,QAAQ,GAAG;AACT,mBAAO,WAAW,aAAa;AAAA,cAC7B,CAAC,SAAS,KAAK,OAAO,CAAC,GAAG,eAAe,WAAW;AAAA,YACtD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,QAAQ,CAAC;AAEb,SAAO;AACT;;;AF/JO,SAAS,0BAA0B,OAAuC;AAC/E,SACE,gBAAAE,OAAA,cAAC,gBAAc,GAAG,SAChB,gBAAAA,OAAA,cAAC,kBAAa,GACd,gBAAAA,OAAA,cAAC,uBAAkB,CACrB;AAEJ;","names":["React","React","Popover","React","Popover","React"]}
@@ -0,0 +1,365 @@
1
+ // src/components/code-editor/editor.tsx
2
+ import React, { useEffect, useRef } from "react";
3
+ import {
4
+ ActiveLinePlaceholder,
5
+ createRenderer,
6
+ EditorProvider
7
+ } from "@coze-editor/editor/react";
8
+ import preset from "@coze-editor/editor/preset-code";
9
+ import { EditorView } from "@codemirror/view";
10
+
11
+ // src/components/code-editor/utils.ts
12
+ function getSuffixByLanguageId(languageId) {
13
+ if (languageId === "python") {
14
+ return ".py";
15
+ }
16
+ if (languageId === "typescript") {
17
+ return ".ts";
18
+ }
19
+ if (languageId === "shell") {
20
+ return ".sh";
21
+ }
22
+ if (languageId === "json") {
23
+ return ".json";
24
+ }
25
+ return "";
26
+ }
27
+
28
+ // src/components/code-editor/theme/index.ts
29
+ import { themes } from "@coze-editor/editor/preset-code";
30
+
31
+ // src/components/code-editor/theme/light.ts
32
+ import { createTheme, tags as t } from "@coze-editor/editor/preset-code";
33
+ var colors = {
34
+ background: "#FFFFFF",
35
+ comment: "#6B7280",
36
+ key: "#2563EB",
37
+ variable: "#DC2626",
38
+ string: "#059669",
39
+ number: "#EA580C",
40
+ boolean: "#7C3AED",
41
+ null: "#7C3AED",
42
+ separator: "#374151"
43
+ };
44
+ var lightTheme = createTheme({
45
+ variant: "light",
46
+ settings: {
47
+ background: "#FFFFFF",
48
+ foreground: "#1F2937",
49
+ caret: "#2563EB",
50
+ selection: "#E5E7EB",
51
+ gutterBackground: "#F9FAFB",
52
+ gutterForeground: "#6B7280",
53
+ gutterBorderColor: "transparent",
54
+ gutterBorderWidth: 0,
55
+ lineHighlight: "#F3F4F680",
56
+ bracketColors: ["#F59E0B", "#8B5CF6", "#06B6D4"],
57
+ tooltip: {
58
+ backgroundColor: "#FFFFFF",
59
+ color: "#1F2937",
60
+ border: "1px solid #E5E7EB",
61
+ boxShadow: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)"
62
+ },
63
+ link: {
64
+ color: "#2563EB"
65
+ },
66
+ completionItemHover: {
67
+ backgroundColor: "#F3F4F6"
68
+ },
69
+ completionItemSelected: {
70
+ backgroundColor: "#E5E7EB"
71
+ },
72
+ completionItemIcon: {
73
+ color: "#4B5563"
74
+ },
75
+ completionItemLabel: {
76
+ color: "#1F2937"
77
+ },
78
+ completionItemInfo: {
79
+ color: "#4B5563"
80
+ },
81
+ completionItemDetail: {
82
+ color: "#6B7280"
83
+ }
84
+ },
85
+ styles: [
86
+ // JSON
87
+ {
88
+ tag: t.comment,
89
+ color: colors.comment
90
+ },
91
+ {
92
+ tag: [t.propertyName],
93
+ color: colors.key
94
+ },
95
+ {
96
+ tag: [t.variableName],
97
+ color: colors.variable
98
+ },
99
+ {
100
+ tag: [t.string],
101
+ color: colors.string
102
+ },
103
+ {
104
+ tag: [t.number],
105
+ color: colors.number
106
+ },
107
+ {
108
+ tag: [t.bool],
109
+ color: colors.boolean
110
+ },
111
+ {
112
+ tag: [t.null],
113
+ color: colors.null
114
+ },
115
+ {
116
+ tag: [t.separator],
117
+ color: colors.separator
118
+ },
119
+ // markdown
120
+ {
121
+ tag: [t.heading],
122
+ color: "#2563EB"
123
+ },
124
+ {
125
+ tag: [t.processingInstruction],
126
+ color: "#2563EB"
127
+ },
128
+ // js
129
+ {
130
+ tag: [t.definitionKeyword],
131
+ color: "#9333EA"
132
+ },
133
+ {
134
+ tag: [t.modifier],
135
+ color: "#9333EA"
136
+ },
137
+ {
138
+ tag: [t.controlKeyword],
139
+ color: "#9333EA"
140
+ },
141
+ {
142
+ tag: [t.operatorKeyword],
143
+ color: "#9333EA"
144
+ },
145
+ // shell
146
+ // curl
147
+ {
148
+ tag: [t.standard(t.variableName)],
149
+ color: "#059669"
150
+ },
151
+ // -X
152
+ {
153
+ tag: [t.attributeName],
154
+ color: "#EA580C"
155
+ },
156
+ // url in string (includes quotes), e.g. "https://..."
157
+ {
158
+ tag: [t.special(t.string)],
159
+ color: "#2563EB"
160
+ }
161
+ ]
162
+ });
163
+
164
+ // src/components/code-editor/theme/dark.ts
165
+ import { createTheme as createTheme2, tags as t2 } from "@coze-editor/editor/preset-code";
166
+ var colors2 = {
167
+ background: "#0D1117",
168
+ // syntax - 现代化暗色主题配色
169
+ comment: "#8B949E",
170
+ key: "#7DD3FC",
171
+ variable: "#F472B6",
172
+ string: "#34D399",
173
+ number: "#FBBF24",
174
+ boolean: "#A78BFA",
175
+ null: "#A78BFA",
176
+ separator: "#E6EDF3"
177
+ };
178
+ var darkTheme = createTheme2({
179
+ variant: "dark",
180
+ settings: {
181
+ background: colors2.background,
182
+ foreground: "#E6EDF3",
183
+ caret: "#7DD3FC",
184
+ selection: "#264F7833",
185
+ gutterBackground: colors2.background,
186
+ gutterForeground: "#6E7681",
187
+ gutterBorderColor: "transparent",
188
+ gutterBorderWidth: 0,
189
+ lineHighlight: "#21262D",
190
+ bracketColors: ["#FBBF24", "#A78BFA", "#7DD3FC"],
191
+ tooltip: {
192
+ backgroundColor: "#21262D",
193
+ color: "#E6EDF3",
194
+ border: "1px solid #30363D"
195
+ },
196
+ link: {
197
+ color: "#58A6FF"
198
+ },
199
+ completionItemHover: {
200
+ backgroundColor: "#21262D"
201
+ },
202
+ completionItemSelected: {
203
+ backgroundColor: "#1F6EEB"
204
+ },
205
+ completionItemIcon: {
206
+ color: "#8B949E"
207
+ },
208
+ completionItemLabel: {
209
+ color: "#E6EDF3"
210
+ },
211
+ completionItemInfo: {
212
+ color: "#8B949E"
213
+ },
214
+ completionItemDetail: {
215
+ color: "#6E7681"
216
+ }
217
+ },
218
+ styles: [
219
+ // json
220
+ {
221
+ tag: t2.comment,
222
+ color: colors2.comment
223
+ },
224
+ {
225
+ tag: [t2.propertyName],
226
+ color: colors2.key
227
+ },
228
+ {
229
+ tag: [t2.string],
230
+ color: colors2.string
231
+ },
232
+ {
233
+ tag: [t2.number],
234
+ color: colors2.number
235
+ },
236
+ {
237
+ tag: [t2.bool],
238
+ color: colors2.boolean
239
+ },
240
+ {
241
+ tag: [t2.null],
242
+ color: colors2.null
243
+ },
244
+ {
245
+ tag: [t2.separator],
246
+ color: colors2.separator
247
+ },
248
+ // js
249
+ {
250
+ tag: [t2.definitionKeyword],
251
+ color: "#C084FC"
252
+ },
253
+ {
254
+ tag: [t2.modifier],
255
+ color: "#C084FC"
256
+ },
257
+ {
258
+ tag: [t2.controlKeyword],
259
+ color: "#C084FC"
260
+ },
261
+ {
262
+ tag: [t2.operatorKeyword],
263
+ color: "#C084FC"
264
+ },
265
+ // markdown
266
+ {
267
+ tag: [t2.heading],
268
+ color: "#7DD3FC"
269
+ },
270
+ {
271
+ tag: [t2.processingInstruction],
272
+ color: "#7DD3FC"
273
+ },
274
+ // shell
275
+ // curl
276
+ {
277
+ tag: [t2.standard(t2.variableName)],
278
+ color: "#34D399"
279
+ },
280
+ // -X
281
+ {
282
+ tag: [t2.attributeName],
283
+ color: "#FBBF24"
284
+ },
285
+ // url in string (includes quotes), e.g. "https://..."
286
+ {
287
+ tag: [t2.special(t2.string)],
288
+ color: "#7DD3FC"
289
+ }
290
+ ]
291
+ });
292
+
293
+ // src/components/code-editor/theme/index.ts
294
+ themes.register("dark", darkTheme);
295
+ themes.register("light", lightTheme);
296
+
297
+ // src/components/code-editor/language-features.ts
298
+ import { languages } from "@coze-editor/editor/preset-code";
299
+ import { typescript } from "@coze-editor/editor/language-typescript";
300
+ import { shell } from "@coze-editor/editor/language-shell";
301
+ import { python } from "@coze-editor/editor/language-python";
302
+ import { json } from "@coze-editor/editor/language-json";
303
+ import { mixLanguages } from "@coze-editor/editor";
304
+ languages.register("python", python);
305
+ languages.register("shell", shell);
306
+ languages.register("typescript", typescript);
307
+ languages.register("json", {
308
+ // mixLanguages is used to solve the problem that interpolation also uses parentheses, which causes incorrect highlighting
309
+ language: mixLanguages({
310
+ outerLanguage: json.language
311
+ }),
312
+ languageService: json.languageService
313
+ });
314
+
315
+ // src/components/code-editor/editor.tsx
316
+ var OriginCodeEditor = createRenderer(preset, [
317
+ EditorView.theme({
318
+ "&.cm-focused": {
319
+ outline: "none"
320
+ }
321
+ })
322
+ ]);
323
+ function CodeEditor({
324
+ value,
325
+ onChange,
326
+ languageId = "python",
327
+ theme = "light",
328
+ children,
329
+ placeholder,
330
+ activeLinePlaceholder,
331
+ options,
332
+ readonly
333
+ }) {
334
+ const editorRef = useRef(null);
335
+ useEffect(() => {
336
+ if (editorRef.current?.getValue() !== value) {
337
+ editorRef.current?.setValue(String(value || ""));
338
+ }
339
+ }, [value]);
340
+ return /* @__PURE__ */ React.createElement(EditorProvider, null, /* @__PURE__ */ React.createElement(
341
+ OriginCodeEditor,
342
+ {
343
+ defaultValue: String(value || ""),
344
+ options: {
345
+ uri: `file:///untitled${getSuffixByLanguageId(languageId)}`,
346
+ languageId,
347
+ theme,
348
+ placeholder,
349
+ readOnly: readonly,
350
+ editable: !readonly,
351
+ ...options || {}
352
+ },
353
+ didMount: (editor) => {
354
+ editorRef.current = editor;
355
+ },
356
+ onChange: (e) => onChange?.(e.value)
357
+ },
358
+ activeLinePlaceholder && /* @__PURE__ */ React.createElement(ActiveLinePlaceholder, null, activeLinePlaceholder),
359
+ children
360
+ ));
361
+ }
362
+ export {
363
+ CodeEditor
364
+ };
365
+ //# sourceMappingURL=editor-XYLKTB6L.js.map