1
- import React , { useRef , useEffect } from "react" ;
2
- import Editor , {
3
- useMonaco ,
4
- Monaco ,
5
- OnMount ,
6
- OnChange ,
7
- } from "@monaco-editor/react" ;
1
+ import React , { useRef } from "react" ;
2
+ import Editor , { OnMount , OnChange } from "@monaco-editor/react" ;
8
3
import * as monaco from "monaco-editor/esm/vs/editor/editor.api" ;
9
4
import { MonacoEmptyMock } from "./monaco-mock-empty" ;
10
5
import { register } from "./monaco-utils" ;
11
6
import { __dangerous__lastFormattedValue__global } from "@code-editor/prettier-services" ;
7
+ import { debounce } from "utils/debounce" ;
8
+ import { downloadFile } from "utils/download" ;
12
9
13
10
type ICodeEditor = monaco . editor . IStandaloneCodeEditor ;
14
11
15
12
export interface MonacoEditorProps {
16
- defaultValue ?: string ;
17
- defaultLanguage ?: string ;
13
+ value ?: string ;
14
+ language ?: string ;
18
15
onChange ?: OnChange ;
19
16
width ?: number | string ;
20
17
height ?: number | string ;
@@ -23,16 +20,15 @@ export interface MonacoEditorProps {
23
20
24
21
export function MonacoEditor ( props : MonacoEditorProps ) {
25
22
const instance = useRef < { editor : ICodeEditor ; format : any } | null > ( null ) ;
26
- const activeModel = useRef < any > ( ) ;
23
+
24
+ const path = "app." + lang2ext ( props . language ) ;
27
25
28
26
const onMount : OnMount = ( editor , monaco ) => {
29
27
const format = editor . getAction ( "editor.action.formatDocument" ) ;
30
28
const rename = editor . getAction ( "editor.action.rename" ) ;
31
29
32
30
instance . current = { editor, format } ;
33
31
34
- activeModel . current = editor . getModel ( ) ;
35
-
36
32
register . initEditor ( editor , monaco ) ;
37
33
38
34
editor . addCommand ( monaco . KeyMod . CtrlCmd | monaco . KeyCode . KeyS , function ( ) {
@@ -41,6 +37,7 @@ export function MonacoEditor(props: MonacoEditorProps) {
41
37
42
38
// disabled. todo: find a way to format on new line, but also with adding new line.
43
39
// editor.addCommand(monaco.KeyCode.Enter, function () {
40
+ // // add new line via script, then run format
44
41
// format.run();
45
42
// });
46
43
@@ -50,9 +47,24 @@ export function MonacoEditor(props: MonacoEditorProps) {
50
47
rename . run ( ) ;
51
48
} ) ;
52
49
53
- editor . onDidChangeModelContent ( ( e ) => {
54
- /* add here */
50
+ editor . addAction ( {
51
+ // An unique identifier of the contributed action.
52
+ id : "export-module-as-file" ,
53
+
54
+ // A label of the action that will be presented to the user.
55
+ label : "Export as file" ,
56
+ precondition : null ,
57
+ keybindingContext : null ,
58
+ contextMenuGroupId : "navigation" ,
59
+ contextMenuOrder : 1.5 ,
60
+ run : function ( ed ) {
61
+ downloadFile ( { data : ed . getModel ( ) . getValue ( ) , filename : path } ) ;
62
+ } ,
55
63
} ) ;
64
+
65
+ editor . onDidChangeModelContent ( ( ) =>
66
+ debounce ( ( ) => editor . saveViewState ( ) , 200 )
67
+ ) ;
56
68
} ;
57
69
58
70
return (
@@ -61,11 +73,10 @@ export function MonacoEditor(props: MonacoEditorProps) {
61
73
onMount = { onMount }
62
74
width = { props . width }
63
75
height = { props . height }
64
- defaultLanguage = {
65
- pollyfill_language ( props . defaultLanguage ) ?? "typescript"
66
- }
76
+ language = { pollyfill_language ( props . language ) ?? "typescript" }
77
+ path = { path }
67
78
loading = { < MonacoEmptyMock l = { 5 } /> }
68
- defaultValue = { props . defaultValue ?? "// no content" }
79
+ value = { props . value ?? "// no content" }
69
80
theme = "vs-dark"
70
81
onChange = { ( ...v ) => {
71
82
if ( v [ 0 ] === __dangerous__lastFormattedValue__global ) {
@@ -84,6 +95,23 @@ export function MonacoEditor(props: MonacoEditorProps) {
84
95
) ;
85
96
}
86
97
98
+ const lang2ext = ( lang : string ) => {
99
+ switch ( lang ) {
100
+ case "typescript" :
101
+ return "ts" ;
102
+ case "javascript" :
103
+ return "js" ;
104
+ case "tsx" :
105
+ return "tsx" ;
106
+ case "jsx" :
107
+ return "jsx" ;
108
+ case "dart" :
109
+ return "dart" ;
110
+ default :
111
+ return lang ;
112
+ }
113
+ } ;
114
+
87
115
const pollyfill_language = ( lang : string ) => {
88
116
switch ( lang ) {
89
117
case "tsx" :
0 commit comments