diff --git a/packages/codemirror/codemirror.mjs b/packages/codemirror/codemirror.mjs
index 7933600e..5ceb9619 100644
--- a/packages/codemirror/codemirror.mjs
+++ b/packages/codemirror/codemirror.mjs
@@ -3,7 +3,7 @@ import { closeBrackets } from '@codemirror/autocomplete';
import { history } from '@codemirror/commands';
import { javascript } from '@codemirror/lang-javascript';
import { defaultHighlightStyle, syntaxHighlighting } from '@codemirror/language';
-import { Compartment, EditorState } from '@codemirror/state';
+import { Compartment, EditorState, Prec } from '@codemirror/state';
import { EditorView, highlightActiveLineGutter, highlightActiveLine, keymap, lineNumbers } from '@codemirror/view';
import { Pattern, Drawer, repl, cleanupDraw } from '@strudel.cycles/core';
// import { isAutoCompletionEnabled } from './Autocomplete';
@@ -44,27 +44,28 @@ export function initEditor({ initialCode = '', onChange, onEvaluate, onStop, set
syntaxHighlighting(defaultHighlightStyle),
history(),
EditorView.updateListener.of((v) => onChange(v)),
- keymap.of([
- {
- key: 'Ctrl-Enter',
- run: () => onEvaluate?.(),
- },
- {
- key: 'Alt-Enter',
- run: () => onEvaluate?.(),
- },
- {
- key: 'Ctrl-.',
- run: () => onStop?.(),
- },
- {
- key: 'Alt-.',
- run: (_, e) => {
- e.preventDefault();
- onStop?.();
+ Prec.highest(
+ keymap.of([
+ {
+ key: 'Ctrl-Enter',
+ run: () => onEvaluate?.(),
},
- },
- /* {
+ {
+ key: 'Alt-Enter',
+ run: () => onEvaluate?.(),
+ },
+ {
+ key: 'Ctrl-.',
+ run: () => onStop?.(),
+ },
+ {
+ key: 'Alt-.',
+ run: (_, e) => {
+ e.preventDefault();
+ onStop?.();
+ },
+ },
+ /* {
key: 'Ctrl-Shift-.',
run: () => (onPanic ? onPanic() : onStop?.()),
},
@@ -72,7 +73,8 @@ export function initEditor({ initialCode = '', onChange, onEvaluate, onStop, set
key: 'Ctrl-Shift-Enter',
run: () => (onReEvaluate ? onReEvaluate() : onEvaluate?.()),
}, */
- ]),
+ ]),
+ ),
],
});
@@ -150,6 +152,11 @@ export class StrudelMirror {
onEvaluate: () => this.evaluate(),
onStop: () => this.stop(),
});
+ const cmEditor = this.root.querySelector('.cm-editor');
+ if (cmEditor) {
+ this.root.style.backgroundColor = 'var(--background)';
+ cmEditor.style.backgroundColor = 'transparent';
+ }
}
async drawFirstFrame() {
if (!this.onDraw) {
@@ -190,6 +197,10 @@ export class StrudelMirror {
}
setFontFamily(family) {
this.root.style.fontFamily = family;
+ const scroller = this.root.querySelector('.cm-scroller');
+ if (scroller) {
+ scroller.style.fontFamily = family;
+ }
}
reconfigureExtension(key, value) {
if (!extensions[key]) {
diff --git a/packages/codemirror/index.mjs b/packages/codemirror/index.mjs
index c847c32c..8f2d1630 100644
--- a/packages/codemirror/index.mjs
+++ b/packages/codemirror/index.mjs
@@ -2,3 +2,4 @@ export * from './codemirror.mjs';
export * from './highlight.mjs';
export * from './flash.mjs';
export * from './slider.mjs';
+export * from './themes.mjs';
diff --git a/packages/codemirror/themes.mjs b/packages/codemirror/themes.mjs
index 1f520623..71fb7642 100644
--- a/packages/codemirror/themes.mjs
+++ b/packages/codemirror/themes.mjs
@@ -473,6 +473,9 @@ function stringifySafe(json) {
return JSON.stringify(json, getCircularReplacer());
}
+export const theme = (theme) => themes[theme] || themes.strudelTheme;
+
+// css style injection helpers
export function injectStyle(rule) {
const newStyle = document.createElement('style');
document.head.appendChild(newStyle);
@@ -481,4 +484,38 @@ export function injectStyle(rule) {
return () => styleSheet.deleteRule(ruleIndex);
}
-export const theme = (theme) => themes[theme] || themes.strudelTheme;
+let currentTheme, resetThemeStyle, themeStyle;
+export function initTheme(theme) {
+ themeStyle = document.createElement('style');
+ themeStyle.id = 'strudel-theme';
+ document.head.append(themeStyle);
+ activateTheme(theme);
+}
+
+export function activateTheme(name) {
+ if (currentTheme === name) {
+ return;
+ }
+ if (!settings[name]) {
+ console.warn('theme', name, 'has no settings.. defaulting to strudelTheme settings');
+ }
+ const themeSettings = settings[name] || settings.strudelTheme;
+ // set css variables
+ themeStyle.innerHTML = `:root {
+ ${Object.entries(themeSettings)
+ // important to override fallback
+ .map(([key, value]) => `--${key}: ${value} !important;`)
+ .join('\n')}
+ }`;
+ // tailwind dark mode
+ if (themeSettings.light) {
+ document.documentElement.classList.remove('dark');
+ } else {
+ document.documentElement.classList.add('dark');
+ }
+ resetThemeStyle?.();
+ resetThemeStyle = undefined;
+ if (themeSettings.customStyle) {
+ resetThemeStyle = injectStyle(themeSettings.customStyle);
+ }
+}
diff --git a/website/src/components/HeadCommonNew.astro b/website/src/components/HeadCommonNew.astro
new file mode 100644
index 00000000..9f323a7a
--- /dev/null
+++ b/website/src/components/HeadCommonNew.astro
@@ -0,0 +1,58 @@
+---
+import { pwaInfo } from 'virtual:pwa-info';
+import '../styles/index.css';
+
+const { BASE_URL } = import.meta.env;
+const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL;
+---
+
+
+
+
+
+
+
+
+
+
+
+
+
+