This repository has been archived on 2024-10-26. You can view files and clone it, but cannot push or open issues or pull requests.
staxman-old/static/components/editor/script.mjs

98 lines
2.2 KiB
JavaScript
Raw Normal View History

2023-11-30 00:57:45 +00:00
import "/static/vendor/ace/ace.js";
import { $el } from "../../vendor/domutil/domutil.js";
class Editor extends HTMLElement {
editor;
/** @type {HTMLDivElement} Tab container */
tabEl;
/** @type {Map<string, AceSession>} File name to file session */
files;
constructor() {
super();
this.files = {};
this.attachShadow({ mode: "open" });
}
connectedCallback() {
this.tabEl = $el("div", { className: "tab-container" });
this.shadowRoot.append(this.tabEl);
const style = $el("style");
style.textContent = `
.tab-container {
display: flex;
& .tab {
border: 2px solid var(--table-border-color);
padding: 0.5ch 0.8ch;
background-color: var(--button-bg);
cursor: pointer;
&.active {
background-color: var(--table-border-color);
}
&:not(:first-child) {
margin-left: -2px;
}
}
}
`;
const slot = $el("slot", { name: "body" });
this.shadowRoot.append(style, slot);
const editorEl = $el("div", { slot: "body" });
this.append(editorEl);
// Create editor
ace.config.set('basePath', '/static/vendor/ace')
this.editor = ace.edit(editorEl);
// todo make this stuff customizable??
this.editor.setTheme("ace/theme/dracula");
this.editor.setOptions({
fontFamily: "Iosevka Web",
fontSize: "12pt",
});
this.editor.getSession().setUseWrapMode(true);
this.editor.setKeyboardHandler("ace/keyboard/vim");
}
/**
* Add a file editing session
* @param {string} name File name
* @param {string} content File contents
*/
addFile(name, content) {
// Add to session list
this.files[name] = ace.createEditSession(content);
// TODO replace this with auto-detection
this.files[name].setMode("ace/mode/nix");
// Create tab and set as active
const tab = this.#addTab(name);
tab.click();
}
/**
* Create a new tab
* @param {string} name Tab name
* @returns Tab element
*/
#addTab(name) {
const tab = $el("div", {
className: "tab",
"@click": () => {
this.editor.setSession(this.files[name]);
this.tabEl.querySelectorAll(".tab").forEach(el => el.classList.remove("active"));
tab.classList.add("active");
}
}, name);
this.tabEl.append(tab);
return tab;
}
}
customElements.define("file-editor", Editor);