diff --git a/website/src/repl/Footer.jsx b/website/src/repl/Footer.jsx index c47f19a7..3ddf1dc4 100644 --- a/website/src/repl/Footer.jsx +++ b/website/src/repl/Footer.jsx @@ -5,12 +5,12 @@ import { nanoid } from 'nanoid'; import React, { useContext, useCallback, useLayoutEffect, useRef, useState } from 'react'; import { useEvent, loadedSamples, ReplContext } from './Repl'; import { Reference } from './Reference'; -import * as themes from './themes.mjs'; +import { themes, themeColors } from './themes.mjs'; export function Footer({ context }) { // const [activeFooter, setActiveFooter] = useState('console'); // const { activeFooter, setActiveFooter, isZen } = useContext?.(ReplContext); - const { activeFooter, setActiveFooter, isZen, setTheme } = context; + const { activeFooter, setActiveFooter, isZen, theme, setTheme } = context; const footerContent = useRef(); const [log, setLog] = useState([]); @@ -166,22 +166,31 @@ export function Footer({ context }) { ))} )} + {activeFooter === 'reference' && } {activeFooter === 'settings' && ( -
+
{Object.entries(themes).map(([k, t]) => ( -
  • - { - setTheme(t); - }} - > - {k} - -
  • +
    { + console.log(k, themeColors(t)); + setTheme(t); + }} + > +
    {k}
    +
    + {themeColors(t).map((c, i) => ( +
    + ))} +
    +
    ))}
    )} - {activeFooter === 'reference' && }
    )} @@ -212,3 +221,7 @@ function linkify(inputText) { return replacedText; } + +function classNames(...classes) { + return classes.filter(Boolean).join(' '); +} diff --git a/website/src/repl/themes.mjs b/website/src/repl/themes.mjs index f956a875..9303ca00 100644 --- a/website/src/repl/themes.mjs +++ b/website/src/repl/themes.mjs @@ -1,4 +1,4 @@ -export { +import { abcdef, androidstudio, atomone, @@ -29,3 +29,78 @@ export { tokyoNightDay, xcodeLight, } from '@uiw/codemirror-themes-all'; + +export const themes = { + abcdef, + androidstudio, + atomone, + aura, + bespin, + darcula, + dracula, + duotoneDark, + eclipse, + githubDark, + gruvboxDark, + materialDark, + nord, + okaidia, + solarizedDark, + sublime, + tokyoNight, + tokyoNightStorm, + vscodeDark, + xcodeDark, + bbedit, + duotoneLight, + githubLight, + gruvboxLight, + materialLight, + noctisLilac, + solarizedLight, + tokyoNightDay, + xcodeLight, +}; + +export const vars = { + abcdef: { + bg: '#0f0f0f', + activeLine: '#314151', + }, +}; + +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; +} + +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()); +}