Open vrabota opened 3 years ago
this can be helpful. I'll try to find some time to make a working example
It's hard to understand something in this example and how to integrate with monaco-react. Seems like all the code should be placed in public/index.html and we don't need monaco-react at all.
An update on this would be greatly appreciated
@suren-atoyan could you please provide an update on this.
@suren-atoyan Did you manage to get some time to look into it? :)
@Nivl @Chethannp @efreila guys sorry, but this package isn't compatible with this yaml-monaco implmenetation. To avoid using webpack configuration in this package we download monaco sources from CDN. The mentioned yaml-monaco implementation heavily depends on the ESM version of monaco, which requires a specific webpack configuration
@suren-atoyan Is there a workaround that let us use https://github.com/remcohaszing/monaco-yaml with https://github.com/suren-atoyan/monaco-react ?
is there any example with monaco-yaml?
this might make it possible to use monaco-yaml
with monaco-react
@suren-atoyan Cheers for the suggestion. I did manage to get it working using the webpack config from https://github.com/remcohaszing/monaco-yaml and the following component:
import React, {FC, useEffect} from 'react';
import * as monaco from "monaco-editor";
import Editor, { loader } from "@monaco-editor/react";
loader.config({ monaco });
import {setDiagnosticsOptions} from 'monaco-yaml';
// @ts-ignore
window.MonacoEnvironment = {
getWorker(moduleId: any, label: string) {
switch (label) {
case 'editorWorkerService':
// @ts-ignore
return new Worker(new URL('monaco-editor/esm/vs/editor/editor.worker', import.meta.url));
case 'css':
case 'less':
case 'scss':
// @ts-ignore
return new Worker(new URL('monaco-editor/esm/vs/language/css/css.worker', import.meta.url));
case 'handlebars':
case 'html':
case 'razor':
return new Worker(
// @ts-ignore
new URL('monaco-editor/esm/vs/language/html/html.worker', import.meta.url),
);
case 'json':
return new Worker(
// @ts-ignore
new URL('monaco-editor/esm/vs/language/json/json.worker', import.meta.url),
);
case 'javascript':
case 'typescript':
return new Worker(
// @ts-ignore
new URL('monaco-editor/esm/vs/language/typescript/ts.worker', import.meta.url),
);
case 'yaml':
// @ts-ignore
return new Worker(new URL('monaco-yaml/yaml.worker', import.meta.url));
default:
throw new Error(`Unknown label ${label}`);
}
},
};
interface CodeEditorProps {
language: string;
value: any;
disabled?: boolean;
onChange(value: string|undefined): void;
className?: string;
width?: string;
height?: string;
}
export const CodeEditor: FC<CodeEditorProps> = (props) => {
const {language, value, disabled, onChange, className, width, height} = props;
const handleOnChange = (value: string|undefined) => {
onChange(value);
}
const handleEditorValidation = (markers: any) => {
// model markers
markers.forEach((marker: any) => console.log("onValidate:", marker.message));
}
useEffect(() => {
setDiagnosticsOptions({
// Have to set an empty Diagnostics options to get syntax checking
});
}, [])
return (
<div style={{border: "1px solid #ccc"}} className={className}>
<Editor
options={{
readOnly: disabled,
lineDecorationsWidth: 5,
lineNumbersMinChars: 0,
glyphMargin: false,
folding: false,
lineNumbers: 'off',
minimap: {
enabled: false
},
fontSize: 11,
}}
width={width}
height={height}
language={language}
value={value}
onValidate={handleEditorValidation}
onChange={handleOnChange}
/>
</div>
);
}
@suren-atoyan Cheers for the suggestion. I did manage to get it working using the webpack config from https://github.com/remcohaszing/monaco-yaml and the following component:
import React, {FC, useEffect} from 'react'; import * as monaco from "monaco-editor"; import Editor, { loader } from "@monaco-editor/react"; loader.config({ monaco }); import {setDiagnosticsOptions} from 'monaco-yaml'; // @ts-ignore window.MonacoEnvironment = { getWorker(moduleId: any, label: string) { switch (label) { case 'editorWorkerService': // @ts-ignore return new Worker(new URL('monaco-editor/esm/vs/editor/editor.worker', import.meta.url)); case 'css': case 'less': case 'scss': // @ts-ignore return new Worker(new URL('monaco-editor/esm/vs/language/css/css.worker', import.meta.url)); case 'handlebars': case 'html': case 'razor': return new Worker( // @ts-ignore new URL('monaco-editor/esm/vs/language/html/html.worker', import.meta.url), ); case 'json': return new Worker( // @ts-ignore new URL('monaco-editor/esm/vs/language/json/json.worker', import.meta.url), ); case 'javascript': case 'typescript': return new Worker( // @ts-ignore new URL('monaco-editor/esm/vs/language/typescript/ts.worker', import.meta.url), ); case 'yaml': // @ts-ignore return new Worker(new URL('monaco-yaml/yaml.worker', import.meta.url)); default: throw new Error(`Unknown label ${label}`); } }, }; interface CodeEditorProps { language: string; value: any; disabled?: boolean; onChange(value: string|undefined): void; className?: string; width?: string; height?: string; } export const CodeEditor: FC<CodeEditorProps> = (props) => { const {language, value, disabled, onChange, className, width, height} = props; const handleOnChange = (value: string|undefined) => { onChange(value); } const handleEditorValidation = (markers: any) => { // model markers markers.forEach((marker: any) => console.log("onValidate:", marker.message)); } useEffect(() => { setDiagnosticsOptions({ // Have to set an empty Diagnostics options to get syntax checking }); }, []) return ( <div style={{border: "1px solid #ccc"}} className={className}> <Editor options={{ readOnly: disabled, lineDecorationsWidth: 5, lineNumbersMinChars: 0, glyphMargin: false, folding: false, lineNumbers: 'off', minimap: { enabled: false }, fontSize: 11, }} width={width} height={height} language={language} value={value} onValidate={handleEditorValidation} onChange={handleOnChange} /> </div> ); }
Throws:
Error: Target container is not a DOM element.
In a Next.js app :(
I was able to configure @monaco-editor/react to work with monaco-yaml:
1. yaml.worker.ts
import "monaco-yaml/yaml.worker.js";
2. setupMonaco.ts
import { loader } from "@monaco-editor/react";
import * as monaco from "monaco-editor";
import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
import jsonWorker from "monaco-editor/esm/vs/language/json/json.worker?worker";
import cssWorker from "monaco-editor/esm/vs/language/css/css.worker?worker";
import htmlWorker from "monaco-editor/esm/vs/language/html/html.worker?worker";
import tsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker";
import yamlWorker from "./yaml.worker.js?worker";
/** Configure Monaco editor for Vite */
self.MonacoEnvironment = {
getWorker(_, label) {
if (label === "json") {
return new jsonWorker();
}
if (label === "css" || label === "scss" || label === "less") {
return new cssWorker();
}
if (label === "html" || label === "handlebars" || label === "razor") {
return new htmlWorker();
}
if (label === "typescript" || label === "javascript") {
return new tsWorker();
}
if (label === "yaml") {
return new yamlWorker();
}
return new editorWorker();
},
};
loader.config({ monaco });
import "./setupMonaco"
to index.tsx// In the docs, it is stated that there should only be one monaco yaml instance configured at a time
let monacoYamlInstance: MonacoYaml | undefined;
export function YamlEditor({
schemaUri,
path,
...props
}: YamlEditorProps) {
useEffect(() => {
if (schemaUri) {
monacoYamlInstance?.update({
enableSchemaRequest: true,
schemas: [
{
fileMatch: [path ? `*/**${path}` : "*"],
uri: schemaUri,
},
],
});
}
}, [path, schemaUri]);
const handleEditorBeforeMount = (monaco: Monaco) => {
if (!monacoYamlInstance) {
monacoYamlInstance = configureMonacoYaml(monaco, {
hover: true,
completion: true,
validate: true,
format: true,
enableSchemaRequest: true,
schemas: schemaUri
? [
{
fileMatch: [path ? `*/**${path}` : "*"],
uri: schemaUri,
},
]
: undefined,
});
}
};
return (
<Editor
defaultLanguage="yaml"
path={path}
beforeMount={handleEditorBeforeMount}
{...props}
/>
);
}
For YAML seems like we have indentation and code highlighting, but unfortunately, we can't validate the code (indentation format or naming, duplications of the fields).
I found a library (https://github.com/pengx17/monaco-yaml) that can maybe help, but I have issues to integrate with create-react-app.
I also tried this solution (https://github.com/suren-atoyan/monaco-react/issues/68#issuecomment-770205419) but unfortunately nothing works for create-react-app application.
Maybe someone integrated YAML validations and can share some knowledge.