mirror of
https://github.com/eliasstepanik/strudel.git
synced 2026-01-11 05:38:35 +00:00
117 lines
2.9 KiB
JavaScript
117 lines
2.9 KiB
JavaScript
import strudelTheme from './themes/strudel-theme-vanilla.mjs';
|
|
import { setTheme } from '@strudel/draw';
|
|
|
|
export const themes = {
|
|
strudelTheme,
|
|
};
|
|
|
|
// lineBackground is background with 50% opacity, to make sure the selection below is visible
|
|
|
|
export const settings = {
|
|
strudelTheme: {
|
|
background: '#222',
|
|
lineBackground: '#22222299',
|
|
foreground: '#fff',
|
|
// foreground: '#75baff',
|
|
caret: '#ffcc00',
|
|
selection: 'rgba(128, 203, 196, 0.5)',
|
|
selectionMatch: '#036dd626',
|
|
// lineHighlight: '#8a91991a', // original
|
|
lineHighlight: '#00000050',
|
|
gutterBackground: 'transparent',
|
|
// gutterForeground: '#8a919966',
|
|
gutterForeground: '#8a919966',
|
|
},
|
|
};
|
|
|
|
function getColors(str) {
|
|
const colorRegex = /#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{3})/g;
|
|
const colors = [];
|
|
|
|
let match;
|
|
while ((match = colorRegex.exec(str)) !== null) {
|
|
const color = match[0];
|
|
if (!colors.includes(color)) {
|
|
colors.push(color);
|
|
}
|
|
}
|
|
|
|
return colors;
|
|
}
|
|
|
|
// TODO: remove
|
|
export function themeColors(theme) {
|
|
return getColors(stringifySafe(theme));
|
|
}
|
|
|
|
function getCircularReplacer() {
|
|
const seen = new WeakSet();
|
|
return (key, value) => {
|
|
if (typeof value === 'object' && value !== null) {
|
|
if (seen.has(value)) {
|
|
return;
|
|
}
|
|
seen.add(value);
|
|
}
|
|
return value;
|
|
};
|
|
}
|
|
|
|
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);
|
|
const styleSheet = newStyle.sheet;
|
|
const ruleIndex = styleSheet.insertRule(rule, 0);
|
|
return () => styleSheet.deleteRule(ruleIndex);
|
|
}
|
|
|
|
let currentTheme,
|
|
resetThemeStyle,
|
|
themeStyle,
|
|
styleID = 'strudel-theme-vars';
|
|
export function initTheme(theme) {
|
|
if (!document.getElementById(styleID)) {
|
|
themeStyle = document.createElement('style');
|
|
themeStyle.id = styleID;
|
|
document.head.append(themeStyle);
|
|
}
|
|
activateTheme(theme);
|
|
}
|
|
|
|
export function activateTheme(name) {
|
|
if (currentTheme === name) {
|
|
return;
|
|
}
|
|
currentTheme = name;
|
|
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')}
|
|
}`;
|
|
setTheme(themeSettings);
|
|
// 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);
|
|
}
|
|
}
|