"monaco-editor": "^0.55.1",
"@monaco-editor/react": "^4.7.0",
"react": "^19.2.0",
"react-dom": "^19.2.0",
<MonacoEditor
key={id}
height="100%"
onMount={handleEditorDidMount}
beforeMount={handleEditorWillMount}
onValidate={onValidate}
saveViewState={true}
keepCurrentModel={true}
className={`min-h-16 min-w-16 size-full`}
wrapperProps={{}}
loading={false}
options={{...defaultEditorOptions}}
/>
export const defaultEditorOptions={
model:null,
contextmenu: true,
automaticLayout: true,
mouseWheelZoom: true,
dragAndDrop: true,
links: true,
// UX polish
smoothScrolling: true,
cursorSmoothCaretAnimation: "on",
scrollBeyondLastLine: false,
renderLineHighlight: "all",
// IntelliSense
quickSuggestions: true,
suggestOnTriggerCharacters: true,
acceptSuggestionOnEnter: "smart",
// Code navigation
folding: true,
foldingStrategy: "auto",
minimap: { enabled: true },
// Editing
formatOnPaste: true,
formatOnType: false,
wordWrap: "off",
// Performance
largeFileOptimizations: true,
fontSize: 14,
lineNumbers: 'on',
roundedSelection: false,
readOnly: false,
domReadOnly: false,
tabSize: 4,
tabFocusMode: false, // ensures Tab inserts tab, not moves focus
selectionClipboard: true,
copyWithSyntaxHighlighting: true, // cleaner plain-text pastes
emptySelectionClipboard: true,
pasteAs: {
"enabled": true,
"showPasteSelector": "afterPaste"
},
lineDecorationsWidth: 10,
lineNumbersMinChars: 3,
'bracketPairColorization.enabled': false,
scrollbar: {
verticalScrollbarSize: 10,
horizontalScrollbarSize: 10
}
} as editor.IStandaloneEditorConstructionOptions;
// i have registerd workers
export async function initMonacoLoader() {
// Ensure MonacoEnvironment is registered first
await import('./monaco-env');
const { loader } = await import("@monaco-editor/react");
const monaco = await import("monaco-editor");
loader.config({ monaco });
await loader.init();
}
//env file
// monaco-environment.ts
import type { Environment } from 'monaco-editor';
declare global {
interface Window {
MonacoEnvironment?: Environment;
}
}
globalThis.MonacoEnvironment = {
getWorker(workerId: string, label: string): Worker {
switch (label) {
case 'json':
return new Worker(
new URL(
'monaco-editor/esm/vs/language/json/json.worker',
import.meta.url
),
{ type: 'module', name: workerId }
);
case 'css':
case 'scss':
case 'less':
return new Worker(
new URL(
'monaco-editor/esm/vs/language/css/css.worker',
import.meta.url
),
{ type: 'module', name: workerId }
);
case 'html':
case 'handlebars':
case 'razor':
return new Worker(
new URL(
'monaco-editor/esm/vs/language/html/html.worker',
import.meta.url
),
{ type: 'module', name: workerId }
);
case 'typescript':
case 'javascript':
return new Worker(
new URL(
'monaco-editor/esm/vs/language/typescript/ts.worker',
import.meta.url
),
{ type: 'module', name: workerId }
);
default:
return new Worker(
new URL(
'monaco-editor/esm/vs/editor/editor.worker',
import.meta.url
),
{ type: 'module', name: workerId }
);
}
}
};
//custom paste...since monaco copy paste is not working
editor.addAction({
id: 'custom-paste',
label: 'Paste',
keybindings: [
monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyV,
],
precondition: 'editorTextFocus && !findInputFocused',
run: async (editor:any) => {
try {
const text = await navigator.clipboard.readText();
const model = editor.getModel();
const selection = editor.getSelection();
if (!model || !selection) return;
editor.executeEdits('clipboard-paste', [
{
range: selection,
text,
forceMoveMarkers: true,
},
]);
editor.pushUndoStop();
editor.focus();
} catch (err) {
console.error('Paste failed:', err);
}
},
});
// if i trigger monaco paste again it throws "unknown service 'productService'".
// i have registerd workers
// if i trigger monaco paste again it throws "unknown service 'productService'".