summaryrefslogtreecommitdiff
path: root/src/ts/script.ts
diff options
context:
space:
mode:
authorElizabeth Hunt <me@liz.coffee>2026-01-04 20:58:28 -0800
committerElizabeth Hunt <me@liz.coffee>2026-01-04 20:58:28 -0800
commitacfea7c9e0129168205c374783e7036e5018c9a5 (patch)
treec94ca7170552ef59425203c9150f0523cdd514dd /src/ts/script.ts
parent4dd5994b27bb32d93efacd6d3a42b130f81425df (diff)
downloadadelie-acfea7c9e0129168205c374783e7036e5018c9a5.tar.gz
adelie-acfea7c9e0129168205c374783e7036e5018c9a5.zip
Claude: first attempt at code editor
Diffstat (limited to 'src/ts/script.ts')
-rw-r--r--src/ts/script.ts113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/ts/script.ts b/src/ts/script.ts
index 79a9a75..e8502c8 100644
--- a/src/ts/script.ts
+++ b/src/ts/script.ts
@@ -5,10 +5,14 @@ import 'prismjs/components/prism-markup';
import { initOneko } from './oneko';
type Theme = 'light' | 'dark';
+type EditorView = any;
const THEME_STORAGE_KEY = 'theme';
const DARK_THEME_ATTRIBUTE = 'data-theme';
+let editorInstance: EditorView | null = null;
+let editorModule: typeof import('./editor') | null = null;
+
function detectAssetBase(): string {
const currentScript = document.currentScript as HTMLScriptElement | null;
const scriptSrc =
@@ -58,6 +62,10 @@ function initThemeToggle(): void {
const nextTheme: Theme = toggleButton.checked ? 'dark' : 'light';
applyTheme(nextTheme);
sessionStorage.setItem(THEME_STORAGE_KEY, nextTheme);
+
+ if (editorInstance && editorModule) {
+ editorModule.setEditorTheme(editorInstance, nextTheme);
+ }
});
}
@@ -142,11 +150,116 @@ function initFileInputs(): void {
});
}
+async function loadEditor() {
+ if (!editorModule) {
+ editorModule = await import('./editor');
+ }
+ return editorModule;
+}
+
+function initCodeEditor(): void {
+ const editorContainer = document.getElementById('code-editor');
+ const languageSelect = document.getElementById('language-select');
+
+ if (!editorContainer || !(languageSelect instanceof HTMLSelectElement)) return;
+
+ const initialCode = {
+ javascript: `// Welcome to the live code editor!
+function greet(name) {
+ return \`Hello, \${name}! 👋\`;
+}
+
+console.log(greet('World'));`,
+ css: `/* Try editing this CSS! */
+.retro-box {
+ background: var(--primary);
+ color: var(--text);
+ padding: var(--space-md);
+ border-radius: var(--border-radius);
+ box-shadow: var(--shadow-box);
+}`,
+ html: `<!-- Try editing this HTML! -->
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>Retro Page</title>
+</head>
+<body>
+ <h1>Hello, World!</h1>
+ <p>Welcome to the retro web.</p>
+</body>
+</html>`,
+ };
+
+ let editorLoaded = false;
+
+ const currentTheme = getStoredTheme() ?? getSystemTheme();
+
+ async function createEditorInstance() {
+ if (editorLoaded) return;
+ editorLoaded = true;
+
+ const { createEditor } = await loadEditor();
+ const language = languageSelect.value as 'javascript' | 'css' | 'html';
+
+ editorInstance = createEditor({
+ parent: editorContainer,
+ language,
+ initialCode: initialCode[language],
+ theme: currentTheme,
+ });
+ }
+
+ // Lazy load on intersection (when editor scrolls into view)
+ const observer = new IntersectionObserver(
+ (entries) => {
+ entries.forEach((entry) => {
+ if (entry.isIntersecting) {
+ createEditorInstance();
+ observer.disconnect();
+ }
+ });
+ },
+ { rootMargin: '100px' }
+ );
+
+ observer.observe(editorContainer);
+
+ // Also load on language change
+ languageSelect.addEventListener('change', async () => {
+ const language = languageSelect.value as 'javascript' | 'css' | 'html';
+
+ if (!editorModule) {
+ await createEditorInstance();
+ return;
+ }
+
+ if (editorInstance && editorContainer) {
+ editorContainer.innerHTML = '';
+
+ const { createEditor } = editorModule;
+ editorInstance = createEditor({
+ parent: editorContainer,
+ language,
+ initialCode: initialCode[language],
+ theme: currentTheme,
+ });
+ }
+ });
+}
+
function init(): void {
setAssetBase();
initThemeToggle();
initFairyDust();
initFileInputs();
+
+ // Only initialize code editor if the container exists
+ if (document.getElementById('code-editor')) {
+ initCodeEditor();
+ }
+
Prism.highlightAll();
initOneko();
}