Skip to content

Commit 9e9dae6

Browse files
committed
Add editor page
1 parent e83b405 commit 9e9dae6

File tree

4 files changed

+92
-2
lines changed

4 files changed

+92
-2
lines changed

apps/components_guide_web/lib/components_guide_web/controllers/react_typescript_controller.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ defmodule ComponentsGuideWeb.ReactTypescriptController do
77
|> render("index.html", article: "tips")
88
end
99

10-
@articles ["testing", "forms", "event-handlers", "logical-clocks"]
10+
@articles ["testing", "forms", "event-handlers", "logical-clocks", "editor"]
1111

1212
def show(conn, %{"article" => article}) when article in @articles do
1313
render(conn, "index.html", article: article)
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<script src="https://unpkg.com/monaco-editor@latest/min/vs/loader.js"></script>
2+
3+
<script type="module">
4+
import * as esbuild from "https://cdn.jsdelivr.net/npm/[email protected]/esm/browser.min.js";
5+
const esbuildPromise = Promise.resolve(esbuild.initialize({
6+
wasmURL: 'https://cdn.jsdelivr.net/npm/[email protected]/esbuild.wasm',
7+
}).then(() => esbuild));
8+
9+
require.config({
10+
paths: {
11+
'vs': 'https://unpkg.com/monaco-editor@latest/min/vs'
12+
}
13+
});
14+
15+
const proxy = URL.createObjectURL(new Blob([`
16+
self.MonacoEnvironment = {
17+
baseUrl: 'https://unpkg.com/monaco-editor@latest/min/'
18+
};
19+
importScripts('https://unpkg.com/monaco-editor@latest/min/vs/base/worker/workerMain.js');
20+
`], { type: 'text/javascript' }));
21+
22+
window.MonacoEnvironment = { getWorkerUrl: () => proxy };
23+
24+
const theme = window.matchMedia &&
25+
window.matchMedia('(prefers-color-scheme: dark)').matches
26+
? 'vs-dark' : undefined;
27+
28+
const value = `
29+
const a = 1 + 1;
30+
`.trim();
31+
32+
const types = fetch("https://workers.cloudflare.com/index.d.ts", { cache: 'force-cache' })
33+
.then((response) => response.text())
34+
.catch((err) => `// ${err.message}`);
35+
36+
require(["vs/editor/editor.main"], function () {
37+
const typescript = monaco.languages.typescript;
38+
for (const lang of [typescript.typescriptDefaults, typescript.javascriptDefaults]) {
39+
lang.setCompilerOptions({
40+
noSemanticValidation: true,
41+
noSyntaxValidation: false
42+
});
43+
lang.setCompilerOptions({
44+
target: monaco.languages.typescript.ScriptTarget.ESNext,
45+
allowNonTsExtensions: true,
46+
allowJs: true,
47+
});
48+
/* FIXME: types.then(([uri, content]) => lang.addExtraLib(content, uri)); */
49+
}
50+
const input = monaco.editor.create(document.getElementById('input'), {
51+
language: 'typescript',
52+
model: monaco.editor.createModel(value, 'typescript', 'ts:worker.ts'),
53+
value,
54+
theme,
55+
minimap: false
56+
});
57+
console.log(input);
58+
const output = monaco.editor.create(document.getElementById('output'), {
59+
language: 'javascript',
60+
value: '//',
61+
theme,
62+
readOnly: true,
63+
minimap: false
64+
});
65+
const onEdit = () => {
66+
const body = input.getValue();
67+
esbuildPromise
68+
.then(esbuild => esbuild.transform(body, { loader: 'jsx' }))
69+
.then(content => output.getModel().setValue(content.code))
70+
.catch((err) => output.getModel().setValue(err.message.replace(/^/gm, '// $&')));
71+
/*fetch('/upload', { method: 'POST', body })
72+
.then(async (response) => {
73+
const content = await response.text();
74+
return response.ok ? content : '// ' + content.trimEnd().split('\n').join('\n// ');
75+
})
76+
.then((content) => output.getModel().setValue(content))
77+
.catch((err) => console.warn(err));*/
78+
};
79+
input.onDidChangeModelContent(onEdit);
80+
const model = input.getModel();
81+
model.setValue(input.getValue() + "\n");
82+
});
83+
</script>
84+
<div class="flex-container" id="container" style="display: flex; min-height: 100vh;">
85+
<div id="input" style="flex: 1;"></div>
86+
<div id="output" style="flex: 1;"></div>
87+
</div>

apps/components_guide_web/lib/components_guide_web/templates/react_typescript/index.html.eex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<article>
66
<div class="text-white bg-gray-900">
7-
<div class="content max-w-4xl mx-auto py-8 text-xl">
7+
<div class="<%= @view_module.article_content_class(@article) %>">
88
<%= render(@view_module, @article <> ".html", conn: @conn) %>
99
</div>
1010
</div>

apps/components_guide_web/lib/components_guide_web/views/react_typescript_view.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ defmodule ComponentsGuideWeb.ReactTypescriptView do
1717
"background-color: #{color |> Styling.to_css()}; background-image: #{gradient};"
1818
end
1919

20+
def article_content_class("editor"), do: "content text-xl"
21+
def article_content_class(_article), do: "content max-w-4xl mx-auto py-8 text-xl"
22+
2023
def collected_image(conn, name) do
2124
%{static_path: path_to_image, width: width, height: height} = render(name)
2225
url = Routes.static_path(conn, "/" <> path_to_image)

0 commit comments

Comments
 (0)