Fix syntax coloring, modernize toolbar UI, and clean up CSS

- Fix Monarch tokenizer loading: await initLinter() before editor creation
  so loadScript() doesn't clobber window.define during lazy tokenizer init
- Fix JSX/TSX coloring: use file URIs with proper extensions (.jsx/.tsx)
  so Monaco enables JSX tokenization via the TypeScript language service
- Modernize toolbar: move settings to gear popover, replace text buttons
  with SVG icons, consolidate toggle checkboxes into compact group
- Clean up CSS: remove duplicate toggle classes, dead selectors, orphaned rules
This commit is contained in:
root
2026-02-27 15:19:10 -06:00
parent 0d84c56008
commit 26e232fd41
4 changed files with 222 additions and 140 deletions

View File

@@ -37,41 +37,41 @@ const editorOpts = {
export const MODE_TABS = {
'html-css-js': [
{ id: 'html', label: 'HTML', lang: 'html' },
{ id: 'css', label: 'CSS', lang: 'css' },
{ id: 'js', label: 'JavaScript', lang: 'javascript' },
{ id: 'html', label: 'HTML', lang: 'html', ext: 'html' },
{ id: 'css', label: 'CSS', lang: 'css', ext: 'css' },
{ id: 'js', label: 'JavaScript', lang: 'javascript', ext: 'js' },
],
'typescript': [
{ id: 'html', label: 'HTML', lang: 'html' },
{ id: 'css', label: 'CSS', lang: 'css' },
{ id: 'js', label: 'TypeScript', lang: 'typescript' },
{ id: 'html', label: 'HTML', lang: 'html', ext: 'html' },
{ id: 'css', label: 'CSS', lang: 'css', ext: 'css' },
{ id: 'js', label: 'TypeScript', lang: 'typescript', ext: 'ts' },
],
'react': [
{ id: 'js', label: 'JSX', lang: 'javascript' },
{ id: 'css', label: 'CSS', lang: 'css' },
{ id: 'html', label: 'HTML', lang: 'html' },
{ id: 'js', label: 'JSX', lang: 'javascript', ext: 'jsx' },
{ id: 'css', label: 'CSS', lang: 'css', ext: 'css' },
{ id: 'html', label: 'HTML', lang: 'html', ext: 'html' },
],
'react-ts': [
{ id: 'js', label: 'TSX', lang: 'typescript' },
{ id: 'css', label: 'CSS', lang: 'css' },
{ id: 'html', label: 'HTML', lang: 'html' },
{ id: 'js', label: 'TSX', lang: 'typescript', ext: 'tsx' },
{ id: 'css', label: 'CSS', lang: 'css', ext: 'css' },
{ id: 'html', label: 'HTML', lang: 'html', ext: 'html' },
],
'vue': [
{ id: 'js', label: 'Vue SFC', lang: 'html' },
{ id: 'css', label: 'CSS', lang: 'css' },
{ id: 'js', label: 'Vue SFC', lang: 'html', ext: 'vue' },
{ id: 'css', label: 'CSS', lang: 'css', ext: 'css' },
],
'svelte': [
{ id: 'js', label: 'Svelte', lang: 'html' },
{ id: 'css', label: 'CSS', lang: 'css' },
{ id: 'js', label: 'Svelte', lang: 'html', ext: 'svelte' },
{ id: 'css', label: 'CSS', lang: 'css', ext: 'css' },
],
'markdown': [
{ id: 'js', label: 'Markdown', lang: 'markdown' },
{ id: 'css', label: 'CSS', lang: 'css' },
{ id: 'js', label: 'Markdown', lang: 'markdown', ext: 'md' },
{ id: 'css', label: 'CSS', lang: 'css', ext: 'css' },
],
'wasm': [
{ id: 'html', label: 'HTML', lang: 'html' },
{ id: 'css', label: 'CSS', lang: 'css' },
{ id: 'js', label: 'JavaScript', lang: 'javascript' },
{ id: 'html', label: 'HTML', lang: 'html', ext: 'html' },
{ id: 'css', label: 'CSS', lang: 'css', ext: 'css' },
{ id: 'js', label: 'JavaScript', lang: 'javascript', ext: 'js' },
],
};
@@ -179,16 +179,20 @@ function configureJsxSupport(mode) {
}
}
let modelCounter = 0;
function createEditor(tabDef) {
const container = document.createElement('div');
container.className = 'editor-container';
container.id = `editor-${tabDef.id}`;
editorArea().appendChild(container);
const uri = monaco.Uri.parse(`file:///fiddle-${++modelCounter}.${tabDef.ext}`);
const model = monaco.editor.createModel('', tabDef.lang, uri);
const editor = monaco.editor.create(container, {
...editorOpts,
language: tabDef.lang,
value: '',
model,
});
if (onChangeCallback) {
@@ -289,11 +293,13 @@ export function initEditors(mode = 'html-css-js') {
export function switchMode(mode) {
if (mode === currentMode) return;
// Dispose existing editors
// Dispose existing editors and their models
const oldTabs = MODE_TABS[currentMode];
oldTabs.forEach((tab) => {
if (editors[tab.id]) {
const model = editors[tab.id].getModel();
editors[tab.id].dispose();
if (model) model.dispose();
}
const container = editors[`_container_${tab.id}`];
if (container && container.parentNode) {