Skip to content

Commit

Permalink
basic editor
Browse files Browse the repository at this point in the history
  • Loading branch information
mdynnl committed Aug 18, 2024
1 parent 4a24d34 commit 97a39fb
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 21 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"vite-plugin-solid": "^2.10.2"
},
"dependencies": {
"monaco-editor": "^0.50.0",
"solid-js": "^1.8.21"
}
}
7 changes: 7 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

147 changes: 129 additions & 18 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,136 @@
import type { Component } from 'solid-js';
import {
createEffect,
createRenderEffect,
createSignal,
on,
onCleanup,
type Component,
} from 'solid-js';

import logo from './logo.svg';
import styles from './App.module.css';
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
import './userWorker';

const initialScript = /* javascript */ `\
let count = 0
const button = document.createElement('button')
const update = () => {
button.textContent = count
}
button.onclick = () => {
count++
update()
}
update()
document.getElementById('root').appendChild(button)
`;

const createDoc = (script: string) => {
const scriptUrl = URL.createObjectURL(
new Blob([script], { type: 'application/javascript' }),
);

return /* html */ `
<!doctype html>
<html>
<head>
<title>result</title>
</head>
<body>
<div id="root"></div>
<script>
console.clear();
</script>
<script src="${scriptUrl}" type="module"></script>
</body>
</html>
`;
};

const App: Component = () => {
const [container, setContainer] = createSignal<HTMLElement>();
const [editor, setEditor] =
createSignal<monaco.editor.IStandaloneCodeEditor>();

const [value, _setValue] = createSignal(
localStorage.getItem('value') || initialScript,
);

const saveValue = (next: ReturnType<typeof value>) => {
localStorage.setItem('value', next);
_setValue(next);
};

const setValue = (next: ReturnType<typeof value>) => {
editor()?.setValue(next);
return saveValue(next);
};

const reset = () => setValue(initialScript);

createEffect(
on(container, container => {
if (!container) return;

const editor = monaco.editor.create(container, {
value: value(),
language: 'javascript',
glyphMargin: false,
folding: false,
lineNumbers: 'off',
padding: { top: 5 },
minimap: { enabled: false },
});

onCleanup(() => editor.dispose());

setEditor(editor);

editor.onDidChangeModelContent(() => saveValue(editor.getValue()));
}),
);

const [doc, setDoc] = createSignal();
const [track, trigger] = createSignal(void 0, { equals: false });
createRenderEffect(() => {
track();
setDoc(createDoc(value()));
});

const refresh = () => trigger();

return (
<div class={styles.App}>
<header class={styles.header}>
<img src={logo} class={styles.logo} alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
class={styles.link}
href="https://github.com/solidjs/solid"
target="_blank"
rel="noopener noreferrer"
>
Learn Solid
</a>
</header>
<div
style={{
padding: '1rem',
height: '100%',
gap: '5px',
display: 'grid',
'grid-template-columns': '1fr 1fr',
}}
>
<div style={{ display: 'grid', 'grid-template-rows': 'auto 1fr' }}>
<div>
<button onClick={reset}>reset</button>
</div>
<div ref={setContainer}></div>
</div>
<div style={{ display: 'grid', 'grid-template-rows': 'auto 1fr' }}>
<div>
<button onClick={refresh}>refresh</button>
</div>
<iframe
style={{
width: '100%',
height: '100%',
border: 'none',
}}
srcdoc={doc()}
/>
</div>
</div>
);
};
Expand Down
10 changes: 7 additions & 3 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ body {
-moz-osx-font-smoothing: grayscale;
}

code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
#root {
width: 100vw;
height: 100vh;
}

* {
box-sizing: border-box;
}
26 changes: 26 additions & 0 deletions src/userWorker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import * as monaco from 'monaco-editor';
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';

self.MonacoEnvironment = {
getWorker(moduleId, label) {
if (label === 'json') {
return new jsonWorker();
}
if (label === 'css' || label === 'scss' || label === 'less') {
return new cssWorker();
}
if (label === 'html' || label === 'handlebars' || label === 'razor') {
return new htmlWorker();
}
if (label === 'typescript' || label === 'javascript') {
return new tsWorker();
}
return new editorWorker();
},
};

monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true);

0 comments on commit 97a39fb

Please sign in to comment.