@coding-script/script-engine 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +23 -0
- package/dist/autocomplete/completion-source.d.ts +11 -0
- package/dist/autocomplete/completion-source.js +267 -0
- package/dist/autocomplete/index.d.ts +2 -0
- package/dist/autocomplete/index.js +2 -0
- package/dist/autocomplete/resolve.d.ts +15 -0
- package/dist/autocomplete/resolve.js +29 -0
- package/dist/components/data-types-section.d.ts +10 -0
- package/dist/components/data-types-section.js +25 -0
- package/dist/components/drag-handle.d.ts +10 -0
- package/dist/components/drag-handle.js +39 -0
- package/dist/components/expand-sidebar-button.d.ts +8 -0
- package/dist/components/expand-sidebar-button.js +27 -0
- package/dist/components/field-row.d.ts +8 -0
- package/dist/components/field-row.js +46 -0
- package/dist/components/function-row.d.ts +8 -0
- package/dist/components/function-row.js +47 -0
- package/dist/components/index.d.ts +28 -0
- package/dist/components/index.js +14 -0
- package/dist/components/main-function-section.d.ts +8 -0
- package/dist/components/main-function-section.js +40 -0
- package/dist/components/panel-header.d.ts +7 -0
- package/dist/components/panel-header.js +33 -0
- package/dist/components/section-header.d.ts +7 -0
- package/dist/components/section-header.js +12 -0
- package/dist/components/theme-colors.d.ts +46 -0
- package/dist/components/theme-colors.js +47 -0
- package/dist/components/toolbar-button.d.ts +11 -0
- package/dist/components/toolbar-button.js +26 -0
- package/dist/components/toolbar.d.ts +8 -0
- package/dist/components/toolbar.js +85 -0
- package/dist/components/type-section.d.ts +10 -0
- package/dist/components/type-section.js +58 -0
- package/dist/components/variable-row.d.ts +9 -0
- package/dist/components/variable-row.js +38 -0
- package/dist/components/variables-section.d.ts +9 -0
- package/dist/components/variables-section.js +23 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/script-code.d.ts +3 -0
- package/dist/script-code.js +307 -0
- package/dist/type-panel/index.d.ts +2 -0
- package/dist/type-panel/index.js +1 -0
- package/dist/type-panel/type-panel.d.ts +12 -0
- package/dist/type-panel/type-panel.js +129 -0
- package/dist/types/index.d.ts +77 -0
- package/dist/types/index.js +0 -0
- package/package.json +48 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import react from "react";
|
|
2
|
+
import { SectionHeader } from "./section-header.js";
|
|
3
|
+
import { VariableRow } from "./variable-row.js";
|
|
4
|
+
const VariablesSection = ({ sortedBinds, sortedRequests, colors })=>{
|
|
5
|
+
if (0 === sortedBinds.length && 0 === sortedRequests.length) return null;
|
|
6
|
+
return /*#__PURE__*/ react.createElement("div", null, /*#__PURE__*/ react.createElement(SectionHeader, {
|
|
7
|
+
colors: colors,
|
|
8
|
+
label: "变量"
|
|
9
|
+
}), sortedBinds.map((bind)=>/*#__PURE__*/ react.createElement(VariableRow, {
|
|
10
|
+
key: bind.name,
|
|
11
|
+
name: bind.name,
|
|
12
|
+
dataType: bind.dataType,
|
|
13
|
+
description: bind.description,
|
|
14
|
+
colors: colors
|
|
15
|
+
})), sortedRequests.map((req)=>/*#__PURE__*/ react.createElement(VariableRow, {
|
|
16
|
+
key: req.name,
|
|
17
|
+
name: req.name,
|
|
18
|
+
dataType: req.dataType,
|
|
19
|
+
description: req.description,
|
|
20
|
+
colors: colors
|
|
21
|
+
})));
|
|
22
|
+
};
|
|
23
|
+
export { VariablesSection };
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import react, { useEffect, useRef, useState } from "react";
|
|
2
|
+
import { Compartment, EditorState } from "@codemirror/state";
|
|
3
|
+
import { EditorView, crosshairCursor, drawSelection, dropCursor, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, keymap, lineNumbers, placeholder as view_placeholder, rectangularSelection } from "@codemirror/view";
|
|
4
|
+
import { defaultKeymap, history as commands_history, historyKeymap, indentWithTab } from "@codemirror/commands";
|
|
5
|
+
import { HighlightStyle, bracketMatching, defaultHighlightStyle, foldGutter, foldKeymap, indentOnInput, syntaxHighlighting } from "@codemirror/language";
|
|
6
|
+
import { java } from "@codemirror/lang-java";
|
|
7
|
+
import { oneDark } from "@codemirror/theme-one-dark";
|
|
8
|
+
import { tags } from "@lezer/highlight";
|
|
9
|
+
import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
|
|
10
|
+
import { createGroovyCompletionSource, createGroovyKeywordSource } from "./autocomplete/index.js";
|
|
11
|
+
import { TypePanel } from "./type-panel/index.js";
|
|
12
|
+
import { Toolbar } from "./components/toolbar.js";
|
|
13
|
+
import { ExpandSidebarButton } from "./components/expand-sidebar-button.js";
|
|
14
|
+
const darkHighlightStyle = HighlightStyle.define([
|
|
15
|
+
{
|
|
16
|
+
tag: tags.keyword,
|
|
17
|
+
color: '#c678dd'
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
tag: tags.operator,
|
|
21
|
+
color: '#56b6c2'
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
tag: tags.variableName,
|
|
25
|
+
color: '#e5c07b'
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
tag: tags.string,
|
|
29
|
+
color: '#98c379'
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
tag: tags.comment,
|
|
33
|
+
color: '#5c6370',
|
|
34
|
+
fontStyle: 'italic'
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
tag: tags.number,
|
|
38
|
+
color: '#d19a66'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
tag: tags.bool,
|
|
42
|
+
color: '#d19a66'
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
tag: tags["null"],
|
|
46
|
+
color: '#d19a66'
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
tag: tags.propertyName,
|
|
50
|
+
color: '#e06c75'
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
tag: tags["function"](tags.variableName),
|
|
54
|
+
color: '#61afef'
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
tag: tags.definition(tags.variableName),
|
|
58
|
+
color: '#e5c07b'
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
tag: tags.typeName,
|
|
62
|
+
color: '#e5c07b'
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
tag: tags.className,
|
|
66
|
+
color: '#e5c07b'
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
tag: tags.annotation,
|
|
70
|
+
color: '#d19a66'
|
|
71
|
+
}
|
|
72
|
+
]);
|
|
73
|
+
function buildThemeExtensions(theme) {
|
|
74
|
+
const isDark = 'dark' === theme;
|
|
75
|
+
const exts = [];
|
|
76
|
+
if (isDark) {
|
|
77
|
+
exts.push(oneDark);
|
|
78
|
+
exts.push(syntaxHighlighting(darkHighlightStyle));
|
|
79
|
+
} else exts.push(syntaxHighlighting(defaultHighlightStyle));
|
|
80
|
+
exts.push(EditorView.theme({
|
|
81
|
+
'.cm-tooltip.cm-tooltip-autocomplete': {
|
|
82
|
+
backgroundColor: isDark ? '#21252b' : '#ffffff',
|
|
83
|
+
borderColor: isDark ? '#434343' : '#d9d9d9',
|
|
84
|
+
borderRadius: '4px',
|
|
85
|
+
boxShadow: '0 2px 8px rgba(0,0,0,0.15)',
|
|
86
|
+
overflow: 'hidden'
|
|
87
|
+
},
|
|
88
|
+
'.cm-tooltip-autocomplete > ul > li': {
|
|
89
|
+
padding: '4px 8px',
|
|
90
|
+
color: isDark ? '#abb2bf' : '#333'
|
|
91
|
+
},
|
|
92
|
+
'.cm-tooltip-autocomplete > ul > li[aria-selected]': {
|
|
93
|
+
backgroundColor: isDark ? '#2c313a' : '#e6f4ff',
|
|
94
|
+
color: isDark ? '#fff' : '#000'
|
|
95
|
+
},
|
|
96
|
+
'.cm-completionLabel': {
|
|
97
|
+
fontFamily: 'monospace'
|
|
98
|
+
},
|
|
99
|
+
'.cm-completionDetail': {
|
|
100
|
+
color: isDark ? '#7f848e' : '#888',
|
|
101
|
+
fontStyle: 'normal',
|
|
102
|
+
marginLeft: '8px'
|
|
103
|
+
},
|
|
104
|
+
'.cm-completionInfo': {
|
|
105
|
+
backgroundColor: isDark ? '#282c34' : '#fafafa',
|
|
106
|
+
borderColor: isDark ? '#434343' : '#d9d9d9',
|
|
107
|
+
color: isDark ? '#abb2bf' : '#333',
|
|
108
|
+
padding: '6px 8px'
|
|
109
|
+
},
|
|
110
|
+
'.cm-completionIcon': {
|
|
111
|
+
width: '1.2em',
|
|
112
|
+
fontSize: '0.9em',
|
|
113
|
+
paddingRight: '4px'
|
|
114
|
+
},
|
|
115
|
+
'.cm-completionIcon-property::after': {
|
|
116
|
+
content: '"F"',
|
|
117
|
+
color: '#61afef'
|
|
118
|
+
},
|
|
119
|
+
'.cm-completionIcon-function::after': {
|
|
120
|
+
content: '"M"',
|
|
121
|
+
color: '#c678dd'
|
|
122
|
+
},
|
|
123
|
+
'.cm-completionIcon-variable::after': {
|
|
124
|
+
content: '"V"',
|
|
125
|
+
color: '#e5c07b'
|
|
126
|
+
},
|
|
127
|
+
'.cm-completionIcon-keyword::after': {
|
|
128
|
+
content: '"K"',
|
|
129
|
+
color: '#56b6c2'
|
|
130
|
+
}
|
|
131
|
+
}));
|
|
132
|
+
return exts;
|
|
133
|
+
}
|
|
134
|
+
function buildAutocompleteExt(metadata) {
|
|
135
|
+
return metadata ? autocompletion({
|
|
136
|
+
override: [
|
|
137
|
+
createGroovyCompletionSource(metadata)
|
|
138
|
+
],
|
|
139
|
+
activateOnTyping: true,
|
|
140
|
+
icons: true
|
|
141
|
+
}) : autocompletion({
|
|
142
|
+
override: [
|
|
143
|
+
createGroovyKeywordSource()
|
|
144
|
+
],
|
|
145
|
+
activateOnTyping: true,
|
|
146
|
+
icons: true
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
const ScriptCodeEditor = (props)=>{
|
|
150
|
+
const { value, readonly = false, onChange, onCompile, onThemeChange, placeholder = '请输入 Groovy 脚本...', theme = 'dark', title, metadata, defaultSidebarOpen, options = {} } = props;
|
|
151
|
+
const { fontSize = 14, minHeight = 300, maxHeight = 300 } = options;
|
|
152
|
+
const editorContainerRef = useRef(null);
|
|
153
|
+
const viewRef = useRef(null);
|
|
154
|
+
const themeCompartmentRef = useRef(new Compartment());
|
|
155
|
+
const autocompleteCompartmentRef = useRef(new Compartment());
|
|
156
|
+
const onChangeRef = useRef(onChange);
|
|
157
|
+
onChangeRef.current = onChange;
|
|
158
|
+
const metadataRef = useRef(metadata);
|
|
159
|
+
metadataRef.current = metadata;
|
|
160
|
+
const [sidebarOpen, setSidebarOpen] = useState(defaultSidebarOpen ?? null != metadata);
|
|
161
|
+
const [panelWidth, setPanelWidth] = useState(300);
|
|
162
|
+
useEffect(()=>{
|
|
163
|
+
if (!editorContainerRef.current) return;
|
|
164
|
+
const themeCompartment = themeCompartmentRef.current;
|
|
165
|
+
const acCompartment = autocompleteCompartmentRef.current;
|
|
166
|
+
const extensions = [
|
|
167
|
+
lineNumbers(),
|
|
168
|
+
highlightActiveLineGutter(),
|
|
169
|
+
highlightSpecialChars(),
|
|
170
|
+
commands_history(),
|
|
171
|
+
foldGutter(),
|
|
172
|
+
drawSelection(),
|
|
173
|
+
dropCursor(),
|
|
174
|
+
EditorState.allowMultipleSelections.of(true),
|
|
175
|
+
indentOnInput(),
|
|
176
|
+
bracketMatching(),
|
|
177
|
+
rectangularSelection(),
|
|
178
|
+
crosshairCursor(),
|
|
179
|
+
highlightActiveLine(),
|
|
180
|
+
keymap.of([
|
|
181
|
+
...defaultKeymap,
|
|
182
|
+
...historyKeymap,
|
|
183
|
+
...foldKeymap,
|
|
184
|
+
...completionKeymap,
|
|
185
|
+
indentWithTab
|
|
186
|
+
]),
|
|
187
|
+
java(),
|
|
188
|
+
view_placeholder(placeholder),
|
|
189
|
+
EditorView.updateListener.of((update)=>{
|
|
190
|
+
if (update.docChanged && onChangeRef.current) onChangeRef.current(update.state.doc.toString());
|
|
191
|
+
}),
|
|
192
|
+
EditorView.theme({
|
|
193
|
+
'&': {
|
|
194
|
+
fontSize: `${fontSize}px`
|
|
195
|
+
},
|
|
196
|
+
'.cm-scroller': {
|
|
197
|
+
overflow: 'auto',
|
|
198
|
+
minHeight: `${minHeight}px`,
|
|
199
|
+
maxHeight: `${maxHeight}px`
|
|
200
|
+
},
|
|
201
|
+
'.cm-content': {
|
|
202
|
+
fontFamily: 'monospace',
|
|
203
|
+
minHeight: `${minHeight}px`
|
|
204
|
+
},
|
|
205
|
+
'.cm-gutters': {
|
|
206
|
+
minHeight: `${minHeight}px`
|
|
207
|
+
}
|
|
208
|
+
}),
|
|
209
|
+
themeCompartment.of(buildThemeExtensions(theme)),
|
|
210
|
+
acCompartment.of(buildAutocompleteExt(metadataRef.current))
|
|
211
|
+
];
|
|
212
|
+
if (readonly) extensions.push(EditorState.readOnly.of(true));
|
|
213
|
+
const state = EditorState.create({
|
|
214
|
+
doc: value,
|
|
215
|
+
extensions
|
|
216
|
+
});
|
|
217
|
+
const view = new EditorView({
|
|
218
|
+
state,
|
|
219
|
+
parent: editorContainerRef.current
|
|
220
|
+
});
|
|
221
|
+
viewRef.current = view;
|
|
222
|
+
return ()=>{
|
|
223
|
+
view.destroy();
|
|
224
|
+
};
|
|
225
|
+
}, [
|
|
226
|
+
fontSize,
|
|
227
|
+
minHeight,
|
|
228
|
+
maxHeight,
|
|
229
|
+
placeholder,
|
|
230
|
+
readonly
|
|
231
|
+
]);
|
|
232
|
+
useEffect(()=>{
|
|
233
|
+
if (viewRef.current && value !== viewRef.current.state.doc.toString()) viewRef.current.dispatch({
|
|
234
|
+
changes: {
|
|
235
|
+
from: 0,
|
|
236
|
+
to: viewRef.current.state.doc.length,
|
|
237
|
+
insert: value
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
}, [
|
|
241
|
+
value
|
|
242
|
+
]);
|
|
243
|
+
useEffect(()=>{
|
|
244
|
+
if (!viewRef.current) return;
|
|
245
|
+
viewRef.current.dispatch({
|
|
246
|
+
effects: themeCompartmentRef.current.reconfigure(buildThemeExtensions(theme))
|
|
247
|
+
});
|
|
248
|
+
}, [
|
|
249
|
+
theme
|
|
250
|
+
]);
|
|
251
|
+
useEffect(()=>{
|
|
252
|
+
if (!viewRef.current) return;
|
|
253
|
+
viewRef.current.dispatch({
|
|
254
|
+
effects: autocompleteCompartmentRef.current.reconfigure(buildAutocompleteExt(metadata))
|
|
255
|
+
});
|
|
256
|
+
}, [
|
|
257
|
+
metadata
|
|
258
|
+
]);
|
|
259
|
+
const isDark = 'dark' === theme;
|
|
260
|
+
const borderColor = isDark ? '#434343' : '#d9d9d9';
|
|
261
|
+
const expandBtnBg = isDark ? '#2c313a' : '#f0f0f0';
|
|
262
|
+
const expandBtnColor = isDark ? '#abb2bf' : '#666';
|
|
263
|
+
const handleCompile = ()=>{
|
|
264
|
+
if (onCompile && viewRef.current) onCompile(viewRef.current.state.doc.toString());
|
|
265
|
+
};
|
|
266
|
+
return /*#__PURE__*/ react.createElement("div", {
|
|
267
|
+
style: {
|
|
268
|
+
display: 'flex',
|
|
269
|
+
flexDirection: 'column'
|
|
270
|
+
}
|
|
271
|
+
}, /*#__PURE__*/ react.createElement(Toolbar, {
|
|
272
|
+
title: title,
|
|
273
|
+
theme: theme,
|
|
274
|
+
onThemeChange: onThemeChange,
|
|
275
|
+
onCompile: onCompile ? handleCompile : void 0
|
|
276
|
+
}), /*#__PURE__*/ react.createElement("div", {
|
|
277
|
+
style: {
|
|
278
|
+
display: 'flex',
|
|
279
|
+
border: `1px solid ${borderColor}`,
|
|
280
|
+
borderTop: 'none',
|
|
281
|
+
borderRadius: '0 0 6px 6px',
|
|
282
|
+
overflow: 'hidden'
|
|
283
|
+
}
|
|
284
|
+
}, /*#__PURE__*/ react.createElement("div", {
|
|
285
|
+
style: {
|
|
286
|
+
flex: 1,
|
|
287
|
+
minWidth: 0,
|
|
288
|
+
position: 'relative'
|
|
289
|
+
}
|
|
290
|
+
}, metadata && !sidebarOpen && /*#__PURE__*/ react.createElement(ExpandSidebarButton, {
|
|
291
|
+
borderColor: borderColor,
|
|
292
|
+
expandBtnColor: expandBtnColor,
|
|
293
|
+
expandBtnBg: expandBtnBg,
|
|
294
|
+
onClick: ()=>setSidebarOpen(true)
|
|
295
|
+
}), /*#__PURE__*/ react.createElement("div", {
|
|
296
|
+
ref: editorContainerRef
|
|
297
|
+
})), metadata && sidebarOpen && /*#__PURE__*/ react.createElement(TypePanel, {
|
|
298
|
+
metadata: metadata,
|
|
299
|
+
theme: theme,
|
|
300
|
+
minHeight: minHeight,
|
|
301
|
+
maxHeight: maxHeight,
|
|
302
|
+
width: panelWidth,
|
|
303
|
+
onWidthChange: setPanelWidth,
|
|
304
|
+
onCollapse: ()=>setSidebarOpen(false)
|
|
305
|
+
})));
|
|
306
|
+
};
|
|
307
|
+
export { ScriptCodeEditor };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { TypePanel } from "./type-panel.js";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ScriptMetadata } from '../types';
|
|
3
|
+
export interface TypePanelProps {
|
|
4
|
+
metadata: ScriptMetadata;
|
|
5
|
+
theme: 'dark' | 'light';
|
|
6
|
+
minHeight: number;
|
|
7
|
+
maxHeight: number;
|
|
8
|
+
width: number;
|
|
9
|
+
onWidthChange: (width: number) => void;
|
|
10
|
+
onCollapse: () => void;
|
|
11
|
+
}
|
|
12
|
+
export declare const TypePanel: React.FC<TypePanelProps>;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import react, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { SCROLL_CLASS, ensureScrollbarStyle, themes } from "../components/theme-colors.js";
|
|
3
|
+
import { DragHandle } from "../components/drag-handle.js";
|
|
4
|
+
import { PanelHeader } from "../components/panel-header.js";
|
|
5
|
+
import { MainFunctionSection } from "../components/main-function-section.js";
|
|
6
|
+
import { VariablesSection } from "../components/variables-section.js";
|
|
7
|
+
import { DataTypesSection } from "../components/data-types-section.js";
|
|
8
|
+
const DEFAULT_WIDTH = 300;
|
|
9
|
+
const MIN_WIDTH = 180;
|
|
10
|
+
const MAX_WIDTH = 600;
|
|
11
|
+
const TypePanel = ({ metadata, theme, minHeight, maxHeight, width, onWidthChange, onCollapse })=>{
|
|
12
|
+
const colors = themes[theme];
|
|
13
|
+
const [expanded, setExpanded] = useState(()=>new Set());
|
|
14
|
+
const panelRef = useRef(null);
|
|
15
|
+
const [dragging, setDragging] = useState(false);
|
|
16
|
+
const [handleHovered, setHandleHovered] = useState(false);
|
|
17
|
+
const dragStartXRef = useRef(0);
|
|
18
|
+
const dragStartWidthRef = useRef(DEFAULT_WIDTH);
|
|
19
|
+
useEffect(()=>{
|
|
20
|
+
ensureScrollbarStyle();
|
|
21
|
+
}, []);
|
|
22
|
+
useEffect(()=>{
|
|
23
|
+
if (!dragging) return;
|
|
24
|
+
const onMouseMove = (e)=>{
|
|
25
|
+
const delta = dragStartXRef.current - e.clientX;
|
|
26
|
+
const next = Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, dragStartWidthRef.current + delta));
|
|
27
|
+
onWidthChange(next);
|
|
28
|
+
};
|
|
29
|
+
const onMouseUp = ()=>{
|
|
30
|
+
setDragging(false);
|
|
31
|
+
document.body.classList.remove('se-panel-resizing');
|
|
32
|
+
};
|
|
33
|
+
window.addEventListener('mousemove', onMouseMove);
|
|
34
|
+
window.addEventListener('mouseup', onMouseUp);
|
|
35
|
+
return ()=>{
|
|
36
|
+
window.removeEventListener('mousemove', onMouseMove);
|
|
37
|
+
window.removeEventListener('mouseup', onMouseUp);
|
|
38
|
+
};
|
|
39
|
+
}, [
|
|
40
|
+
dragging,
|
|
41
|
+
onWidthChange
|
|
42
|
+
]);
|
|
43
|
+
const onHandleMouseDown = useCallback((e)=>{
|
|
44
|
+
e.preventDefault();
|
|
45
|
+
dragStartXRef.current = e.clientX;
|
|
46
|
+
dragStartWidthRef.current = width;
|
|
47
|
+
setDragging(true);
|
|
48
|
+
document.body.classList.add('se-panel-resizing');
|
|
49
|
+
}, [
|
|
50
|
+
width
|
|
51
|
+
]);
|
|
52
|
+
const toggle = useCallback((typeName)=>{
|
|
53
|
+
setExpanded((prev)=>{
|
|
54
|
+
const next = new Set(prev);
|
|
55
|
+
if (next.has(typeName)) next.delete(typeName);
|
|
56
|
+
else next.add(typeName);
|
|
57
|
+
return next;
|
|
58
|
+
});
|
|
59
|
+
}, []);
|
|
60
|
+
const allTypes = useMemo(()=>Object.values(metadata.types).sort((a, b)=>a.dataType.localeCompare(b.dataType)), [
|
|
61
|
+
metadata.types
|
|
62
|
+
]);
|
|
63
|
+
const sortedBinds = useMemo(()=>[
|
|
64
|
+
...metadata.binds
|
|
65
|
+
].sort((a, b)=>a.name.localeCompare(b.name)), [
|
|
66
|
+
metadata.binds
|
|
67
|
+
]);
|
|
68
|
+
const sortedRequests = useMemo(()=>[
|
|
69
|
+
...metadata.requests
|
|
70
|
+
].sort((a, b)=>a.name.localeCompare(b.name)), [
|
|
71
|
+
metadata.requests
|
|
72
|
+
]);
|
|
73
|
+
return /*#__PURE__*/ react.createElement("div", {
|
|
74
|
+
ref: panelRef,
|
|
75
|
+
style: {
|
|
76
|
+
width,
|
|
77
|
+
flexShrink: 0,
|
|
78
|
+
display: 'flex',
|
|
79
|
+
flexDirection: 'row',
|
|
80
|
+
overflow: 'hidden',
|
|
81
|
+
minHeight: `${minHeight}px`,
|
|
82
|
+
maxHeight: `${maxHeight}px`,
|
|
83
|
+
position: 'relative'
|
|
84
|
+
}
|
|
85
|
+
}, /*#__PURE__*/ react.createElement(DragHandle, {
|
|
86
|
+
colors: colors,
|
|
87
|
+
dragging: dragging,
|
|
88
|
+
handleHovered: handleHovered,
|
|
89
|
+
onMouseDown: onHandleMouseDown,
|
|
90
|
+
onHoverChange: setHandleHovered
|
|
91
|
+
}), /*#__PURE__*/ react.createElement("div", {
|
|
92
|
+
style: {
|
|
93
|
+
flex: 1,
|
|
94
|
+
minWidth: 0,
|
|
95
|
+
borderLeft: `1px solid ${colors.border}`,
|
|
96
|
+
display: 'flex',
|
|
97
|
+
flexDirection: 'column',
|
|
98
|
+
overflow: 'hidden',
|
|
99
|
+
backgroundColor: colors.bg,
|
|
100
|
+
color: colors.text,
|
|
101
|
+
fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
|
|
102
|
+
fontSize: 13
|
|
103
|
+
}
|
|
104
|
+
}, /*#__PURE__*/ react.createElement(PanelHeader, {
|
|
105
|
+
colors: colors,
|
|
106
|
+
onCollapse: onCollapse
|
|
107
|
+
}), /*#__PURE__*/ react.createElement("div", {
|
|
108
|
+
className: SCROLL_CLASS,
|
|
109
|
+
style: {
|
|
110
|
+
flex: 1,
|
|
111
|
+
overflowY: 'auto',
|
|
112
|
+
overflowX: 'hidden',
|
|
113
|
+
minHeight: 0
|
|
114
|
+
}
|
|
115
|
+
}, /*#__PURE__*/ react.createElement(MainFunctionSection, {
|
|
116
|
+
metadata: metadata,
|
|
117
|
+
colors: colors
|
|
118
|
+
}), /*#__PURE__*/ react.createElement(VariablesSection, {
|
|
119
|
+
sortedBinds: sortedBinds,
|
|
120
|
+
sortedRequests: sortedRequests,
|
|
121
|
+
colors: colors
|
|
122
|
+
}), /*#__PURE__*/ react.createElement(DataTypesSection, {
|
|
123
|
+
allTypes: allTypes,
|
|
124
|
+
expanded: expanded,
|
|
125
|
+
onToggle: toggle,
|
|
126
|
+
colors: colors
|
|
127
|
+
}))));
|
|
128
|
+
};
|
|
129
|
+
export { TypePanel };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/** 函数参数信息 */
|
|
2
|
+
export interface ScriptParameterInfo {
|
|
3
|
+
dataType: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
name: string;
|
|
6
|
+
}
|
|
7
|
+
/** 函数/方法信息 */
|
|
8
|
+
export interface ScriptFunctionInfo {
|
|
9
|
+
description?: string;
|
|
10
|
+
name: string;
|
|
11
|
+
parameters: ScriptParameterInfo[];
|
|
12
|
+
returnType?: string;
|
|
13
|
+
}
|
|
14
|
+
/** 字段/属性信息 */
|
|
15
|
+
export interface ScriptFieldInfo {
|
|
16
|
+
dataType: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
name: string;
|
|
19
|
+
}
|
|
20
|
+
/** 类型定义 */
|
|
21
|
+
export interface ScriptTypeInfo {
|
|
22
|
+
dataType: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
fields: ScriptFieldInfo[];
|
|
25
|
+
functions: ScriptFunctionInfo[];
|
|
26
|
+
}
|
|
27
|
+
/** 绑定变量信息(如 $request) */
|
|
28
|
+
export interface ScriptBindInfo {
|
|
29
|
+
dataType: string;
|
|
30
|
+
name: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
}
|
|
33
|
+
/** 请求参数信息(如 request) */
|
|
34
|
+
export interface ScriptRequestInfo {
|
|
35
|
+
dataType: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
name: string;
|
|
38
|
+
}
|
|
39
|
+
/** 脚本元数据顶层结构 */
|
|
40
|
+
export interface ScriptMetadata {
|
|
41
|
+
binds: ScriptBindInfo[];
|
|
42
|
+
requests: ScriptRequestInfo[];
|
|
43
|
+
mainMethod: string;
|
|
44
|
+
returnType?: string;
|
|
45
|
+
types: Record<string, ScriptTypeInfo>;
|
|
46
|
+
}
|
|
47
|
+
export interface ScriptCodeEditorProps {
|
|
48
|
+
/** 代码内容 */
|
|
49
|
+
value?: string;
|
|
50
|
+
/** 是否只读 */
|
|
51
|
+
readonly?: boolean;
|
|
52
|
+
/** 代码变化回调 */
|
|
53
|
+
onChange?: (value: string) => void;
|
|
54
|
+
/** 编译/测试脚本回调(后续接入 API) */
|
|
55
|
+
onCompile?: (code: string) => void;
|
|
56
|
+
/** 主题切换回调 */
|
|
57
|
+
onThemeChange?: (theme: 'dark' | 'light') => void;
|
|
58
|
+
/** 占位符 */
|
|
59
|
+
placeholder?: string;
|
|
60
|
+
/** 主题 */
|
|
61
|
+
theme?: 'dark' | 'light';
|
|
62
|
+
/** 标题(可选) */
|
|
63
|
+
title?: string;
|
|
64
|
+
/** 脚本元数据 — 提供后启用类型面板和自动补全 */
|
|
65
|
+
metadata?: ScriptMetadata;
|
|
66
|
+
/** 类型面板侧边栏默认是否展开(默认:提供 metadata 时为 true) */
|
|
67
|
+
defaultSidebarOpen?: boolean;
|
|
68
|
+
/** 其他选项 */
|
|
69
|
+
options?: {
|
|
70
|
+
/** 字体大小 */
|
|
71
|
+
fontSize?: number;
|
|
72
|
+
/** 最小高度 */
|
|
73
|
+
minHeight?: number;
|
|
74
|
+
/** 最大高度 */
|
|
75
|
+
maxHeight?: number;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
File without changes
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@coding-script/script-engine",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "script-engine components",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"coding-script",
|
|
7
|
+
"script-engine"
|
|
8
|
+
],
|
|
9
|
+
"homepage": "https://github.com/codingapi/script-engine",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/codingapi/script-engine/issues"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/codingapi/script-engine.git"
|
|
16
|
+
},
|
|
17
|
+
"license": "Apache-2.0",
|
|
18
|
+
"author": "1024lorne@gmail.com",
|
|
19
|
+
"type": "module",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"import": "./dist/index.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"files": [
|
|
28
|
+
"dist"
|
|
29
|
+
],
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@codemirror/autocomplete": "^6.18.0",
|
|
32
|
+
"@codemirror/commands": "^6.10.2",
|
|
33
|
+
"@codemirror/lang-java": "^6.0.2",
|
|
34
|
+
"@codemirror/language": "^6.12.2",
|
|
35
|
+
"@codemirror/state": "^6.5.4",
|
|
36
|
+
"@codemirror/theme-one-dark": "^6.1.3",
|
|
37
|
+
"@codemirror/view": "^6.39.16"
|
|
38
|
+
},
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"react": ">=18",
|
|
41
|
+
"react-dom": ">=18"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "rslib build",
|
|
45
|
+
"dev": "rslib build --watch",
|
|
46
|
+
"push": "pnpm run build && pnpm publish --access public"
|
|
47
|
+
}
|
|
48
|
+
}
|