configureyaml is not working with @monaco-editor/react
Closed this issue · 12 comments
Is there a different approach for @monaco-editor/react
can you please share an example of how can we do configuration with @monaco-editor/react
this is my code
useEffect(() => {
window.MonacoEnvironment = {
getWorker(moduleId, label) {
switch (label) {
case "editorWorkerService":
return new Worker(
new URL("monaco-editor/esm/vs/editor/editor.worker", import.meta.url)
);
case "yaml":
return new Worker(new URL("monaco-yaml/yaml.worker", import.meta.url));
default:
throw new Error(Unknown label ${label}
);
}
},
};
// Configure Monaco YAML
const defaultSchema = {
uri: 'https://github.com/remcohaszing/monaco-yaml/blob/HEAD/examples/demo/src/schema.json',
schema,
fileMatch: ['monaco-yaml.yaml']
}
if (window.monaco) {
const monacoYaml = configureMonacoYaml(window.monaco, {
enableSchemaRequest: true,
schemas: [defaultSchema],
});
}
}, [window.monaco]);
Please format your code and provide a full runnable example, such as a repository that reproduces the problem.
My personal recommendation is to not use @monaco-editor/react
, but use monaco-editor
directly.
Thank you sir for replying I am attaching my editorcomponent file, please look into that.
Great work sir
import Editor from '@monaco-editor/react';
import React, { useEffect } from 'react';
import './index.css';
import { configureMonacoYaml } from "monaco-yaml";
import schema from "./schema.json";
const MonacoEditorComponent = () => {
useEffect(() => {
// Configure Monaco Editor
window.MonacoEnvironment = {
getWorker(moduleId, label) {
switch (label) {
case "yaml":
return new Worker(new URL("monaco-yaml/yaml.worker", import.meta.url));
default:
throw new Error(`Unknown label ${label}`);
}
},
};
}, []);
const value = `
# Property descriptions are displayed when hovering over properties using your cursor
property: This property has a JSON schema description
# Titles work too!
titledProperty: Titles work too!
# Even markdown descriptions work
markdown: hover me to get a markdown based description 😮
# Enums can be autocompleted by placing the cursor after the colon and pressing Ctrl+Space
enum:
# Unused anchors will be reported
unused anchor: &unused anchor
# Of course numbers are supported!
number: 12
# As well as booleans!
boolean: true
# And strings
string: I am a string
# This property is using the JSON schema recursively
reference:
boolean: Not a boolean
# Also works in arrays
array:
- string: 12
enum: Mewtwo
reference:
reference:
boolean: true
# JSON referenses can be clicked for navigation
pointer:
$ref: '#/array'
# This anchor can be referenced
anchorRef: &anchor can be clicked as well
# Press control while hovering over the anchor
anchorPointer: *anchor
formatting: Formatting is supported too! Under the hood this is powered by Prettier. Just press Ctrl+Shift+I or right click and press Format to format this document.
`.replace(/:$/m, ": ");
return (
<div id="editor" style={{ height: "100vh", textAlign: "left" }} >
<Editor
defaultLanguage='yaml'
value={value}
onMount={(editor, monaco) => {
const defaultSchema = {
uri: "file://./src/schema.json",
schema,
fileMatch: ["monaco-yaml.yaml"],
};
const monacoYaml = configureMonacoYaml(monaco, {
enableSchemaRequest: true,
schemas: [defaultSchema],
});
}}
/>
</div>
)
};
export default MonacoEditorComponent;
Sir Can you please help me with this given code
I use it with react-monaco-editor
but it should be roughly the same...
Add this to your file:
import * as monacoEditor from 'monaco-editor/esm/vs/editor/editor.api';
const monacoYaml = configureMonacoYaml(monacoEditor);
And on mount use monacoYaml.update
instead of configureMonacoYaml
:
monacoYaml.update({
enableSchemaRequest: true,
schemas: [defaultSchema],
});
Surprisingly running into the same issue where I get no errors but schema and auto completion is not working
Surprisingly running into the same issue where I get no errors but schema and auto completion is not working
Are you able to find any solution for this?
@Rajgupta7080 Well, I've realized that what appears to be happening is the yamlWorker
is never started on my end. Not sure why.
@Rajgupta7080 I have it working. Switch from onMount
to beforeMount
@TerminalFi If you don't mind can you please share example of that working code, I tried before mount also it is not working for me.
@TerminalFi If you don't mind can you please share example of that working code, I tried before mount also it is not working for me.
This is what my page Editor looks like
"use client";
import PageSpinner from "@/components/PageSpinner";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
import { Database } from "@/lib/db/database";
import Editor, { BeforeMount, OnMount, type Monaco } from "@monaco-editor/react";
import { AlertTriangle } from "lucide-react";
import { editor } from "monaco-editor";
import { configureMonacoYaml } from 'monaco-yaml';
import { useTheme } from "next-themes";
import { useEffect, useRef, useState } from "react";
import toast from "react-hot-toast";
import SaveButton from "./SaveButton";
import { updateMetadata } from "./actions";
type Repository = Database["public"]["Tables"]["repositories"]["Row"];
interface MetadataEditorProps {
repository: Repository | null;
}
window.MonacoEnvironment = {
getWorker(_, label) {
switch (label) {
case 'yaml':
return new Worker(new URL('monaco-yaml/yaml.worker', import.meta.url))
default:
return new Worker(new URL('monaco-editor/esm/vs/editor/editor.worker', import.meta.url))
}
}
}
export default function MetadataEditor({ repository }: MetadataEditorProps) {
const monacoRef = useRef<editor.IStandaloneCodeEditor | null>(null);
const { theme, setTheme } = useTheme();
const [isValid, setIsValid] = useState(true);
const [errors, setErrors] = useState<string[]>([]);
const [metadata, setMetadata] = useState(repository!.metadata || "");
// If the parent repository metadata changes, update the editor value
// this should only really happen if the user tries to save an empty string as the metadata
useEffect(() => {
setMetadata(repository!.metadata || "");
}, [repository]);
var monacoOptions = {
readOnly: false,
minimap: { enabled: false },
formatOnType: true,
formatOnPaste: true,
quickSuggestions: {
other: true,
comments: false,
strings: true,
},
};
const handleEditorWillMount: BeforeMount = (monaco: Monaco) => {
configureMonacoYaml(monaco, {
enableSchemaRequest: true,
hover: true,
completion: true,
validate: true,
format: true,
schemas: [
{
uri: '/schema.json',
fileMatch: ['*'],
},
],
})
};
const handleEditorDidMount: OnMount = (editor, monaco: Monaco) => {
monacoRef.current = editor;
};
function validateEvent(validationErrors: any) {
setIsValid(validationErrors.length === 0);
if (validationErrors.length > 0) {
setErrors(validationErrors.map((error: any) => error.message));
}
}
async function saveMetadata(formData: FormData) {
if (isValid) {
let yamlMetadata = monacoRef.current!.getValue();
let result = await updateMetadata(repository!.uuid, yamlMetadata);
if (result?.error) {
toast.error(result.error);
return;
}
toast.success("Metadata Changes Saved");
monacoRef!.current!.getAction("editor.action.formatDocument")!.run();
} else {
toast.error("Metadata is invalid. Please fix the errors and try again.");
}
}
let editorTheme = theme === "light" ? "light" : "vs-dark";
return (
<div>
<Editor
className="rounded-lg border"
height="40vh"
theme={editorTheme}
onValidate={validateEvent}
beforeMount={handleEditorWillMount}
onMount={handleEditorDidMount}
value={metadata.toString()}
loading={<PageSpinner />}
options={monacoOptions}
defaultLanguage="yaml"
language="yaml"
/>
{isValid ? (
null
) : (
<Alert className="mt-5 bg-yellow-100 dark:bg-yellow-800">
<AlertTriangle className="h-4 w-4" />
<AlertTitle>Invalid YAML</AlertTitle>
<AlertDescription>
{errors.map((error, index) => {
return <p key={index}>{error}</p>
}
)}
</AlertDescription>
</Alert>
)}
<form action={saveMetadata}>
<SaveButton />
</form>
</div>
);
}
@TerminalFi Sir, Thank you so much for sharing this code, Now my code started working.