@stonecrop/code-editor 0.13.2 → 0.13.4
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/dist/assets/editor.worker-Be8ye1pW.js.map +1 -0
- package/dist/assets/json.worker-DKiEKt88.js +59 -0
- package/dist/assets/json.worker-DKiEKt88.js.map +1 -0
- package/dist/code-editor.css +1 -1
- package/dist/code-editor.js +177 -134
- package/dist/code-editor.js.map +1 -1
- package/dist/editor.worker-DwCTOaYH.js +24 -0
- package/dist/editor.worker-DwCTOaYH.js.map +1 -0
- package/dist/graphql-DWkL3f8U.js +152 -0
- package/dist/graphql-DWkL3f8U.js.map +1 -0
- package/dist/graphqlMode-0MXNK8Fk.js +6758 -0
- package/dist/graphqlMode-0MXNK8Fk.js.map +1 -0
- package/dist/index-DH1yIu_w.js +124799 -0
- package/dist/index-DH1yIu_w.js.map +1 -0
- package/dist/jsonMode-DycJAYy-.js +2066 -0
- package/dist/jsonMode-DycJAYy-.js.map +1 -0
- package/dist/src/utils/graphql.d.ts +44 -0
- package/dist/src/utils/graphql.d.ts.map +1 -0
- package/dist/src/utils/graphql.js +38 -0
- package/dist/src/utils/language.d.ts +11 -0
- package/dist/src/utils/language.d.ts.map +1 -0
- package/dist/src/utils/language.js +16 -0
- package/dist/src/utils/serialization.d.ts +9 -0
- package/dist/src/utils/serialization.d.ts.map +1 -0
- package/dist/src/utils/serialization.js +14 -0
- package/package.json +9 -6
- package/src/components/ACodeEditor.vue +66 -20
- package/src/utils/language.ts +14 -0
- package/src/utils/serialization.ts +12 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { SchemaConfig } from 'monaco-graphql';
|
|
2
|
+
/**
|
|
3
|
+
* Initializes the GraphQL language mode for Monaco. Safe to call multiple
|
|
4
|
+
* times — initialization only runs once. Subsequent calls with a schema
|
|
5
|
+
* update the active schema.
|
|
6
|
+
*
|
|
7
|
+
* Consumers must configure `globalThis.MonacoEnvironment.getWorker` before
|
|
8
|
+
* creating a GraphQL editor so that the language service worker is available.
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
export declare function configureGraphQL(schemaConfig?: SchemaConfig): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Lazily loads and returns the Monaco instance from monaco-graphql/monaco-editor.
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export declare function getMonaco(): Promise<{
|
|
17
|
+
default: typeof import("monaco-graphql/esm/monaco-editor.js");
|
|
18
|
+
CancellationTokenSource: typeof import("monaco-editor").CancellationTokenSource;
|
|
19
|
+
Emitter: typeof import("monaco-editor").Emitter;
|
|
20
|
+
KeyCode: typeof import("monaco-editor").KeyCode;
|
|
21
|
+
KeyMod: typeof import("monaco-editor").KeyMod;
|
|
22
|
+
MarkerSeverity: typeof import("monaco-editor").MarkerSeverity;
|
|
23
|
+
MarkerTag: typeof import("monaco-editor").MarkerTag;
|
|
24
|
+
Position: typeof import("monaco-editor").Position;
|
|
25
|
+
Range: typeof import("monaco-editor").Range;
|
|
26
|
+
Selection: typeof import("monaco-editor").Selection;
|
|
27
|
+
SelectionDirection: typeof import("monaco-editor").SelectionDirection;
|
|
28
|
+
Token: typeof import("monaco-editor").Token;
|
|
29
|
+
languages: typeof import("monaco-editor").languages;
|
|
30
|
+
Uri: typeof import("monaco-editor").Uri;
|
|
31
|
+
createWebWorker: typeof import("monaco-editor").createWebWorker;
|
|
32
|
+
css: typeof import("monaco-editor").css;
|
|
33
|
+
editor: typeof import("monaco-editor").editor;
|
|
34
|
+
html: typeof import("monaco-editor").html;
|
|
35
|
+
json: typeof import("monaco-editor").json;
|
|
36
|
+
lsp: typeof import("monaco-editor").lsp;
|
|
37
|
+
typescript: typeof import("monaco-editor").typescript;
|
|
38
|
+
}>;
|
|
39
|
+
/**
|
|
40
|
+
* Lazily loads and returns the Monaco editor loader.
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
43
|
+
export declare function getLoader(): Promise<typeof import("@monaco-editor/loader").default>;
|
|
44
|
+
//# sourceMappingURL=graphql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql.d.ts","sourceRoot":"","sources":["../../../src/utils/graphql.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAIlD;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,YAAY,CAAC,EAAE,YAAY,iBAajE;AAED;;;GAGG;AACH,wBAAsB,SAAS;;;;;;;;;;;;;;;;;;;;;;GAE9B;AAED;;;GAGG;AACH,wBAAsB,SAAS,4DAG9B"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
let graphqlInitialized = false;
|
|
2
|
+
/**
|
|
3
|
+
* Initializes the GraphQL language mode for Monaco. Safe to call multiple
|
|
4
|
+
* times — initialization only runs once. Subsequent calls with a schema
|
|
5
|
+
* update the active schema.
|
|
6
|
+
*
|
|
7
|
+
* Consumers must configure `globalThis.MonacoEnvironment.getWorker` before
|
|
8
|
+
* creating a GraphQL editor so that the language service worker is available.
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
export async function configureGraphQL(schemaConfig) {
|
|
12
|
+
if (!graphqlInitialized) {
|
|
13
|
+
const { initializeMode } = await import('monaco-graphql/initializeMode');
|
|
14
|
+
initializeMode(schemaConfig ? { schemas: [schemaConfig] } : undefined);
|
|
15
|
+
graphqlInitialized = true;
|
|
16
|
+
}
|
|
17
|
+
else if (schemaConfig) {
|
|
18
|
+
const monaco = await import('monaco-graphql/monaco-editor');
|
|
19
|
+
const { languages } = monaco;
|
|
20
|
+
const api = languages.graphql;
|
|
21
|
+
api?.api?.setSchemaConfig([schemaConfig]);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Lazily loads and returns the Monaco instance from monaco-graphql/monaco-editor.
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export async function getMonaco() {
|
|
29
|
+
return import('monaco-graphql/monaco-editor');
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Lazily loads and returns the Monaco editor loader.
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export async function getLoader() {
|
|
36
|
+
const { default: loader } = await import('@monaco-editor/loader');
|
|
37
|
+
return loader;
|
|
38
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves the Monaco language identifier from a Stonecrop fieldtype and an
|
|
3
|
+
* optional explicit language override.
|
|
4
|
+
*
|
|
5
|
+
* - JSON fieldtype always maps to 'json' regardless of the explicit language.
|
|
6
|
+
* - Code fieldtype defaults to 'typescript'; the explicit language overrides it.
|
|
7
|
+
* - All other fieldtypes use the explicit language, falling back to 'plaintext'.
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export declare function detectLanguage(fieldtype?: string, explicitLanguage?: string): string;
|
|
11
|
+
//# sourceMappingURL=language.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"language.d.ts","sourceRoot":"","sources":["../../../src/utils/language.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAIpF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves the Monaco language identifier from a Stonecrop fieldtype and an
|
|
3
|
+
* optional explicit language override.
|
|
4
|
+
*
|
|
5
|
+
* - JSON fieldtype always maps to 'json' regardless of the explicit language.
|
|
6
|
+
* - Code fieldtype defaults to 'typescript'; the explicit language overrides it.
|
|
7
|
+
* - All other fieldtypes use the explicit language, falling back to 'plaintext'.
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export function detectLanguage(fieldtype, explicitLanguage) {
|
|
11
|
+
if (fieldtype === 'JSON')
|
|
12
|
+
return 'json';
|
|
13
|
+
if (fieldtype === 'Code')
|
|
14
|
+
return explicitLanguage ?? 'typescript';
|
|
15
|
+
return explicitLanguage ?? 'plaintext';
|
|
16
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coerces an unknown value to a string suitable for Monaco's initial content.
|
|
3
|
+
* Objects are JSON-stringified with 2-space indentation.
|
|
4
|
+
* Null and undefined become empty string.
|
|
5
|
+
* Strings pass through unchanged.
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export declare function toEditorString(value: unknown, _fieldtype?: string): string;
|
|
9
|
+
//# sourceMappingURL=serialization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../../../src/utils/serialization.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAI1E"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coerces an unknown value to a string suitable for Monaco's initial content.
|
|
3
|
+
* Objects are JSON-stringified with 2-space indentation.
|
|
4
|
+
* Null and undefined become empty string.
|
|
5
|
+
* Strings pass through unchanged.
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export function toEditorString(value, _fieldtype) {
|
|
9
|
+
if (value === null || value === undefined)
|
|
10
|
+
return '';
|
|
11
|
+
if (typeof value === 'string')
|
|
12
|
+
return value;
|
|
13
|
+
return JSON.stringify(value, null, 2);
|
|
14
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stonecrop/code-editor",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": {
|
|
@@ -33,9 +33,7 @@
|
|
|
33
33
|
],
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@monaco-editor/loader": "^1.7.0",
|
|
36
|
-
"monaco-editor": "^0.55.1"
|
|
37
|
-
"@stonecrop/themes": "0.13.2",
|
|
38
|
-
"@stonecrop/utilities": "0.13.2"
|
|
36
|
+
"monaco-editor": "^0.55.1"
|
|
39
37
|
},
|
|
40
38
|
"peerDependencies": {
|
|
41
39
|
"vue": "^3.5.33"
|
|
@@ -45,16 +43,18 @@
|
|
|
45
43
|
"@microsoft/api-documenter": "^7.30.5",
|
|
46
44
|
"@rushstack/heft": "^1.2.17",
|
|
47
45
|
"@vitejs/plugin-vue": "^6.0.6",
|
|
46
|
+
"@vue/test-utils": "^2.4.10",
|
|
47
|
+
"jsdom": "^29.1.1",
|
|
48
48
|
"eslint": "^10.3.0",
|
|
49
49
|
"eslint-config-prettier": "^10.1.8",
|
|
50
50
|
"eslint-plugin-vue": "^10.9.0",
|
|
51
51
|
"globals": "^17.6.0",
|
|
52
52
|
"typescript": "^6.0.3",
|
|
53
53
|
"typescript-eslint": "^8.59.1",
|
|
54
|
+
"vitest": "^4.1.5",
|
|
54
55
|
"vue": "^3.5.33",
|
|
55
56
|
"vite": "^7.3.2",
|
|
56
57
|
"vue-router": "^5.0.6",
|
|
57
|
-
"@stonecrop/atable": "0.13.2",
|
|
58
58
|
"stonecrop-rig": "0.7.0"
|
|
59
59
|
},
|
|
60
60
|
"publishConfig": {
|
|
@@ -69,6 +69,9 @@
|
|
|
69
69
|
"dev": "vite",
|
|
70
70
|
"docs": "bash ../common/scripts/run-docs.sh code_editor",
|
|
71
71
|
"lint": "eslint .",
|
|
72
|
-
"preview": "vite preview"
|
|
72
|
+
"preview": "vite preview",
|
|
73
|
+
"test": "vitest run",
|
|
74
|
+
"test:watch": "vitest",
|
|
75
|
+
"test:coverage": "vitest run --coverage"
|
|
73
76
|
}
|
|
74
77
|
}
|
|
@@ -1,42 +1,88 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div ref="aCodeEditor" class="a-code-editor" :style="{ height }" />
|
|
3
3
|
</template>
|
|
4
4
|
|
|
5
5
|
<script setup lang="ts">
|
|
6
6
|
import loader from '@monaco-editor/loader'
|
|
7
7
|
import type * as Monaco from 'monaco-editor'
|
|
8
|
-
import { editor } from 'monaco-editor'
|
|
9
|
-
import { onMounted,
|
|
8
|
+
import type { editor } from 'monaco-editor'
|
|
9
|
+
import { onMounted, onUnmounted, shallowRef, watch } from 'vue'
|
|
10
|
+
import { useTemplateRef } from 'vue'
|
|
10
11
|
|
|
11
12
|
import { theme } from '../theme/code_editor/agritheory'
|
|
13
|
+
import { detectLanguage } from '../utils/language'
|
|
14
|
+
import { toEditorString } from '../utils/serialization'
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
type EditorSchema = { fieldtype?: string; [key: string]: unknown }
|
|
17
|
+
|
|
18
|
+
const modelValue = defineModel<string>()
|
|
19
|
+
const {
|
|
20
|
+
height = '300px',
|
|
21
|
+
mode = 'edit',
|
|
22
|
+
schema = undefined,
|
|
23
|
+
language = undefined,
|
|
24
|
+
options = undefined,
|
|
25
|
+
} = defineProps<{
|
|
26
|
+
height?: string
|
|
27
|
+
mode?: 'edit' | 'read' | 'display'
|
|
28
|
+
schema?: EditorSchema
|
|
29
|
+
language?: string
|
|
30
|
+
options?: editor.IStandaloneEditorConstructionOptions
|
|
31
|
+
}>()
|
|
14
32
|
|
|
15
33
|
const editorRef = useTemplateRef<HTMLDivElement>('aCodeEditor')
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
34
|
+
const editorInstance = shallowRef<editor.IStandaloneCodeEditor | null>(null)
|
|
35
|
+
|
|
36
|
+
watch(modelValue, val => {
|
|
37
|
+
const inst = editorInstance.value
|
|
38
|
+
if (inst && val !== inst.getValue()) inst.setValue(val ?? '')
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
watch(
|
|
42
|
+
() => mode,
|
|
43
|
+
m => {
|
|
44
|
+
editorInstance.value?.updateOptions({ readOnly: m !== 'edit' })
|
|
45
|
+
}
|
|
46
|
+
)
|
|
23
47
|
|
|
24
48
|
onMounted(async () => {
|
|
25
49
|
const monacoInstance: typeof Monaco = await loader.init()
|
|
26
|
-
const
|
|
50
|
+
const lang = detectLanguage(schema?.fieldtype, language)
|
|
27
51
|
|
|
28
|
-
|
|
29
|
-
|
|
52
|
+
monacoInstance.editor.defineTheme('agritheory', theme)
|
|
53
|
+
monacoInstance.editor.setTheme('agritheory')
|
|
30
54
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
55
|
+
const inst = monacoInstance.editor.create(editorRef.value!, {
|
|
56
|
+
automaticLayout: true,
|
|
57
|
+
colorDecorators: true,
|
|
58
|
+
lineHeight: 24,
|
|
59
|
+
scrollBeyondLastLine: false,
|
|
60
|
+
...options,
|
|
61
|
+
value: toEditorString(modelValue.value, schema?.fieldtype),
|
|
62
|
+
language: lang,
|
|
63
|
+
readOnly: mode !== 'edit',
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
inst.onDidChangeModelContent(() => {
|
|
67
|
+
modelValue.value = inst.getValue()
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
editorInstance.value = inst
|
|
71
|
+
|
|
72
|
+
// Sync any modelValue change that arrived during the async CDN load
|
|
73
|
+
const current = modelValue.value ?? ''
|
|
74
|
+
if (current !== inst.getValue()) inst.setValue(current)
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
onUnmounted(() => {
|
|
78
|
+
editorInstance.value?.dispose()
|
|
79
|
+
editorInstance.value = null
|
|
34
80
|
})
|
|
35
81
|
</script>
|
|
36
82
|
|
|
37
|
-
<style>
|
|
38
|
-
|
|
83
|
+
<style scoped>
|
|
84
|
+
.a-code-editor {
|
|
39
85
|
width: 100%;
|
|
40
|
-
|
|
86
|
+
overflow: hidden;
|
|
41
87
|
}
|
|
42
88
|
</style>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves the Monaco language identifier from a Stonecrop fieldtype and an
|
|
3
|
+
* optional explicit language override.
|
|
4
|
+
*
|
|
5
|
+
* - JSON fieldtype always maps to 'json' regardless of the explicit language.
|
|
6
|
+
* - Code fieldtype defaults to 'typescript'; the explicit language overrides it.
|
|
7
|
+
* - All other fieldtypes use the explicit language, falling back to 'plaintext'.
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export function detectLanguage(fieldtype?: string, explicitLanguage?: string): string {
|
|
11
|
+
if (fieldtype === 'JSON') return 'json'
|
|
12
|
+
if (fieldtype === 'Code') return explicitLanguage ?? 'typescript'
|
|
13
|
+
return explicitLanguage ?? 'plaintext'
|
|
14
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coerces an unknown value to a string suitable for Monaco's initial content.
|
|
3
|
+
* Objects are JSON-stringified with 2-space indentation.
|
|
4
|
+
* Null and undefined become empty string.
|
|
5
|
+
* Strings pass through unchanged.
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export function toEditorString(value: unknown, _fieldtype?: string): string {
|
|
9
|
+
if (value === null || value === undefined) return ''
|
|
10
|
+
if (typeof value === 'string') return value
|
|
11
|
+
return JSON.stringify(value, null, 2)
|
|
12
|
+
}
|