Page MenuHomeSealhub

monaco.stimulus.ts
No OneTemporary

monaco.stimulus.ts

/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/consistent-type-assertions */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-call */
import { Controller } from "stimulus";
import { debounce } from "throttle-debounce";
import { addJS } from "@sealcode/add-to-head";
declare global {
interface Window {
monaco: typeof import("monaco-editor");
}
}
declare const require: any;
type MonacoEditor =
import("monaco-editor/esm/vs/editor/editor.api").editor.IStandaloneCodeEditor;
export default class extends Controller<HTMLDivElement> {
editor: MonacoEditor | null = null;
resizeObserver: ResizeObserver | null = null;
static targets = ["textarea"];
declare textareaTarget: HTMLTextAreaElement;
defaultRowsNumber = 20;
private lastWidth: number = 0; // track last width
setupEditor() {
const container = this.element;
const monacoEditor = window.monaco.editor;
this.editor = monacoEditor.create(container, {
value: this.textareaTarget?.textContent?.trim() || "",
language: this.element.getAttribute("data-language") || "markdown",
automaticLayout: true,
minimap: { enabled: false },
scrollbar: { vertical: "hidden" },
scrollBeyondLastLine: false,
lineNumbers: "off",
});
const inner_container: HTMLDivElement =
container.querySelector(".monaco-editor")!;
inner_container.setAttribute("data-turbo-permanent", "");
const updateHeight = () => {
if (!this.editor) {
return;
}
const lineHeight = this.editor.getOption(
monacoEditor.EditorOption.lineHeight
);
const lines_count = this.editor.getValue().split("\n").length;
container.style.minHeight = `${(lines_count + 1) * lineHeight}px`;
this.editor.layout();
};
updateHeight();
const updateTextareaValue = debounce(30, () => {
if (this.textareaTarget && this.editor) {
this.textareaTarget.value = this.editor.getValue();
}
});
this.editor?.onDidChangeModelContent(() => {
updateTextareaValue();
updateHeight();
});
this.lastWidth = container.clientWidth;
this.resizeObserver = new ResizeObserver(() => {
const currentWidth = container.clientWidth;
if (currentWidth !== this.lastWidth) {
this.lastWidth = currentWidth;
this.editor?.layout();
}
});
this.resizeObserver.observe(container);
}
async connect() {
this.textareaTarget.style.display = "none";
await addJS(`${location.origin}/dist/monaco-editor/min/vs/loader.js`);
if (!window.monaco?.editor) {
require.config({
paths: {
vs: `${location.origin}/dist/monaco-editor/min/vs`,
},
});
require(["vs/editor/editor.main"], this.setupEditor.bind(this));
return;
}
this.setupEditor();
}
disconnect() {
this.editor?.dispose();
this.editor = null;
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
}
}

File Metadata

Mime Type
text/x-java
Expires
Sat, Nov 8, 12:12 (15 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1032514
Default Alt Text
monaco.stimulus.ts (2 KB)

Event Timeline