1import strudelTheme, { settings as strudelThemeSettings } from './themes/strudel-theme.mjs'; 2import bluescreen, { settings as bluescreenSettings } from './themes/bluescreen.mjs'; 3import blackscreen, { settings as blackscreenSettings } from './themes/blackscreen.mjs'; 4import whitescreen, { settings as whitescreenSettings } from './themes/whitescreen.mjs'; 5import teletext, { settings as teletextSettings } from './themes/teletext.mjs'; 6import algoboy, { settings as algoboySettings } from './themes/algoboy.mjs'; 7import CutiePi, { settings as CutiePiSettings } from './themes/CutiePi.mjs'; 8import sonicPink, { settings as sonicPinkSettings } from './themes/sonic-pink.mjs'; 9import redText, { settings as redTextSettings } from './themes/red-text.mjs'; 10import greenText, { settings as greenTextSettings } from './themes/green-text.mjs'; 11import archBtw, { settings as archBtwSettings } from './themes/archBtw.mjs'; 12import fruitDaw, { settings as fruitDawSettings } from './themes/fruitDaw.mjs'; 13 14import bluescreenlight, { settings as bluescreenlightsettings } from './themes/bluescreenlight.mjs'; 15 16import androidstudio, { settings as androidstudioSettings } from './themes/androidstudio.mjs'; 17import atomone, { settings as atomOneSettings } from './themes/atomone.mjs'; 18import aura, { settings as auraSettings } from './themes/aura.mjs'; 19import darcula, { settings as darculaSettings } from './themes/darcula.mjs'; 20import dracula, { settings as draculaSettings } from './themes/dracula.mjs'; 21import duotoneDark, { settings as duotoneDarkSettings } from './themes/duotoneDark.mjs'; 22import eclipse, { settings as eclipseSettings } from './themes/eclipse.mjs'; 23import githubDark, { settings as githubDarkSettings } from './themes/githubDark.mjs'; 24import githubLight, { settings as githubLightSettings } from './themes/githubLight.mjs'; 25import gruvboxDark, { settings as gruvboxDarkSettings } from './themes/gruvboxDark.mjs'; 26import gruvboxLight, { settings as gruvboxLightSettings } from './themes/gruvboxLight.mjs'; 27import materialDark, { settings as materialDarkSettings } from './themes/materialDark.mjs'; 28import materialLight, { settings as materialLightSettings } from './themes/materialLight.mjs'; 29import nord, { settings as nordSettings } from './themes/nord.mjs'; 30import monokai, { settings as monokaiSettings } from './themes/monokai.mjs'; 31import solarizedDark, { settings as solarizedDarkSettings } from './themes/solarizedDark.mjs'; 32import solarizedLight, { settings as solarizedLightSettings } from './themes/solarizedLight.mjs'; 33import sublime, { settings as sublimeSettings } from './themes/sublime.mjs'; 34import tokyoNight, { settings as tokyoNightSettings } from './themes/tokyoNight.mjs'; 35import tokyoNightStorm, { settings as tokyoNightStormSettings } from './themes/tokioNightStorm.mjs'; 36import tokyoNightDay, { settings as tokyoNightDaySettings } from './themes/tokyoNightDay.mjs'; 37import vscodeDark, { settings as vscodeDarkSettings } from './themes/vscodeDark.mjs'; 38import vscodeLight, { settings as vscodeLightSettings } from './themes/vscodeLight.mjs'; 39import xcodeLight, { settings as xcodeLightSettings } from './themes/xcodeLight.mjs'; 40import bbedit, { settings as bbeditSettings } from './themes/bbedit.mjs'; 41import noctisLilac, { settings as noctisLilacSettings } from './themes/noctisLilac.mjs'; 42 43import { setTheme } from '@strudel/draw'; 44export const themes = { 45 strudelTheme, 46 algoboy, 47 archBtw, 48 androidstudio, 49 atomone, 50 aura, 51 bbedit, 52 blackscreen, 53 bluescreen, 54 bluescreenlight, 55 CutiePi, 56 darcula, 57 dracula, 58 duotoneDark, 59 eclipse, 60 fruitDaw, 61 githubDark, 62 githubLight, 63 greenText, 64 gruvboxDark, 65 gruvboxLight, 66 sonicPink, 67 materialDark, 68 materialLight, 69 monokai, 70 noctisLilac, 71 nord, 72 redText, 73 solarizedDark, 74 solarizedLight, 75 sublime, 76 teletext, 77 tokyoNight, 78 tokyoNightDay, 79 tokyoNightStorm, 80 vscodeDark, 81 vscodeLight, 82 whitescreen, 83 xcodeLight, 84}; 85 86export const settings = { 87 strudelTheme: strudelThemeSettings, 88 bluescreen: bluescreenSettings, 89 bluescreenlight: bluescreenlightsettings, 90 blackscreen: blackscreenSettings, 91 whitescreen: whitescreenSettings, 92 teletext: teletextSettings, 93 algoboy: algoboySettings, 94 archBtw: archBtwSettings, 95 androidstudio: androidstudioSettings, 96 atomone: atomOneSettings, 97 aura: auraSettings, 98 bbedit: bbeditSettings, 99 darcula: darculaSettings, 100 dracula: draculaSettings, 101 duotoneDark: duotoneDarkSettings, 102 eclipse: eclipseSettings, 103 CutiePi: CutiePiSettings, 104 sonicPink: sonicPinkSettings, 105 fruitDaw: fruitDawSettings, 106 githubLight: githubLightSettings, 107 githubDark: githubDarkSettings, 108 greenText: greenTextSettings, 109 110 gruvboxDark: gruvboxDarkSettings, 111 gruvboxLight: gruvboxLightSettings, 112 materialDark: materialDarkSettings, 113 materialLight: materialLightSettings, 114 noctisLilac: noctisLilacSettings, 115 nord: nordSettings, 116 monokai: monokaiSettings, 117 redText: redTextSettings, 118 solarizedLight: solarizedLightSettings, 119 solarizedDark: solarizedDarkSettings, 120 sublime: sublimeSettings, 121 tokyoNight: tokyoNightSettings, 122 tokyoNightStorm: tokyoNightStormSettings, 123 vscodeDark: vscodeDarkSettings, 124 vscodeLight: vscodeLightSettings, 125 xcodeLight: xcodeLightSettings, 126 tokyoNightDay: tokyoNightDaySettings, 127}; 128 129function getColors(str) { 130 const colorRegex = /#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{3})/g; 131 const colors = []; 132 133 let match; 134 while ((match = colorRegex.exec(str)) !== null) { 135 const color = match[0]; 136 if (!colors.includes(color)) { 137 colors.push(color); 138 } 139 } 140 141 return colors; 142}
TODO: remove
149function getCircularReplacer() { 150 const seen = new WeakSet(); 151 return (key, value) => { 152 if (typeof value === 'object' && value !== null) { 153 if (seen.has(value)) { 154 return; 155 } 156 seen.add(value); 157 } 158 return value; 159 }; 160} 161 162function stringifySafe(json) { 163 return JSON.stringify(json, getCircularReplacer()); 164} 165 166export const theme = (theme) => themes[theme] || themes.strudelTheme;
css style injection helpers
177let currentTheme, 178 resetThemeStyle, 179 themeStyle, 180 styleID = 'strudel-theme-vars'; 181export function initTheme(theme) { 182 if (!document.getElementById(styleID)) { 183 themeStyle = document.createElement('style'); 184 themeStyle.id = styleID; 185 document.head.append(themeStyle); 186 } 187 activateTheme(theme); 188} 189 190export function activateTheme(name) { 191 if (currentTheme === name) { 192 return; 193 } 194 currentTheme = name; 195 if (!settings[name]) { 196 console.warn('theme', name, 'has no settings.. defaulting to strudelTheme settings'); 197 } 198 const themeSettings = settings[name] || settings.strudelTheme; 199 // set css variables 200 themeStyle.innerHTML = `:root { 201 color-scheme: ${themeSettings.light ? 'light' : 'dark'}; 202 ${Object.entries(themeSettings) 203 // important to override fallback 204 .map(([key, value]) => `--${key}: ${value} !important;`) 205 .join('\n')} 206 }`; 207 setTheme(themeSettings); 208 // tailwind dark mode 209 if (themeSettings.light) { 210 document.documentElement.classList.remove('dark'); 211 } else { 212 document.documentElement.classList.add('dark'); 213 } 214 resetThemeStyle?.(); 215 resetThemeStyle = undefined; 216 if (themeSettings.customStyle) { 217 resetThemeStyle = injectStyle(themeSettings.customStyle); 218 } 219}