198 lines
4.4 KiB
TypeScript
198 lines
4.4 KiB
TypeScript
"use client";
|
|
|
|
import React from "react";
|
|
import styles from "./ColorChanger.module.css";
|
|
import Image from "next/image";
|
|
|
|
type ColorScheme = {
|
|
name: string;
|
|
|
|
bg: string;
|
|
bgDark: string;
|
|
bgDarker: string;
|
|
|
|
fg: string;
|
|
fgDark: string;
|
|
fgDarker: string;
|
|
|
|
error: string;
|
|
warning: string;
|
|
};
|
|
|
|
const colors: ColorScheme[] = [
|
|
{
|
|
// https://monokai.pro
|
|
name: "Monokai Pro",
|
|
bg: "#2d2a2e",
|
|
bgDark: "#403e41",
|
|
bgDarker: "#221f22",
|
|
fg: "#fcfcfa",
|
|
fgDark: "#727072",
|
|
fgDarker: "#5b595c",
|
|
error: "#ff6188",
|
|
warning: "#ffd866"
|
|
},
|
|
{
|
|
// https://github.com/morhetz/gruvbox
|
|
name: "Gruvbox Dark",
|
|
bg: "#282828",
|
|
bgDark: "#3c3836",
|
|
bgDarker: "#1d2021",
|
|
fg: "#ebdbb2",
|
|
fgDark: "#a89984",
|
|
fgDarker: "#928374",
|
|
error: "#fb4934",
|
|
warning: "#fabd2f"
|
|
},
|
|
{
|
|
// https://github.com/owozsh/amora
|
|
name: "Amora Focus",
|
|
bg: "#1a1a1a",
|
|
bgDark: "#171717",
|
|
bgDarker: "#141414",
|
|
fg: "#DEDBEB",
|
|
fgDark: "#5c5c5c",
|
|
fgDarker: "#292929",
|
|
error: "#fb5c8e",
|
|
warning: "#eacac0"
|
|
},
|
|
{
|
|
// https://rosepinetheme.com/palette
|
|
name: "Rosé Pine",
|
|
bg: "#191724",
|
|
bgDark: "#26233a",
|
|
bgDarker: "#1f1d2e",
|
|
fg: "#e0def4",
|
|
fgDark: "#908caa",
|
|
fgDarker: "#6e6a86",
|
|
error: "#eb6f92",
|
|
warning: "#f6c177"
|
|
},
|
|
{
|
|
// https://www.nordtheme.com/docs/colors-and-palettes
|
|
name: "Nord",
|
|
bg: "#2e3440",
|
|
bgDark: "#3b4252",
|
|
bgDarker: "#2E3440",
|
|
fg: "#eceff4",
|
|
fgDark: "#d8dee9",
|
|
fgDarker: "#E5E9F0",
|
|
error: "#BF616A",
|
|
warning: "#EBCB8B"
|
|
},
|
|
{
|
|
// https://github.com/elenapan/dotfiles/blob/master/.xfiles/lovelace
|
|
name: "lovelace",
|
|
bg: "#1d1f28",
|
|
bgDark: "#282a36",
|
|
bgDarker: "#141721",
|
|
fg: "#fdfdfd",
|
|
fgDark: "#414458",
|
|
fgDarker: "#bebec1",
|
|
error: "#F37F97",
|
|
warning: "#F2A272"
|
|
},
|
|
{
|
|
// https://github.com/elenapan/dotfiles/blob/master/.xfiles/skyfall
|
|
name: "skyfall",
|
|
bg: "#282f37",
|
|
bgDark: "#20262c",
|
|
bgDarker: "#1d2228", // guestimated, -6 value
|
|
fg: "#f1fcf9",
|
|
fgDark: "#465463",
|
|
fgDarker: "#e0e5e5",
|
|
error: "#DB86BA",
|
|
warning: "#E49186"
|
|
},
|
|
// {{{ https://github.com/catppuccin/catppuccin#-palette
|
|
{
|
|
name: "Catppuccin Frappe",
|
|
bg: "#303446", // base
|
|
bgDark: "#51576d", // surface 1
|
|
bgDarker: "#292c3c", // mantle
|
|
fg: "#c6d0f5", // text
|
|
fgDark: "#a5adce", // subtext 0
|
|
fgDarker: "#949cbb", // overlay 2
|
|
error: "#e78284",
|
|
warning: "#e5c890"
|
|
},
|
|
{
|
|
name: "Catppuccin Macchiato",
|
|
bg: "#24273a",
|
|
bgDark: "#494d64",
|
|
bgDarker: "#1e2030",
|
|
fg: "#cad3f5",
|
|
fgDark: "#a5adcb",
|
|
fgDarker: "#939ab7",
|
|
error: "#ed8796",
|
|
warning: "#eed49f"
|
|
},
|
|
{
|
|
name: "Catppuccin Mocha",
|
|
bg: "#1e1e2e",
|
|
bgDark: "#45475a",
|
|
bgDarker: "#181825",
|
|
fg: "#cdd6f4",
|
|
fgDark: "#a6adc8",
|
|
fgDarker: "#9399b2",
|
|
error: "#f38ba8",
|
|
warning: "#f9e2af"
|
|
}
|
|
// }}}
|
|
];
|
|
|
|
const fallback = colors[0];
|
|
|
|
function getFromLocalStorage() {
|
|
let color = localStorage.getItem("colorscheme");
|
|
if (!color) localStorage.setItem("colorscheme", fallback.name);
|
|
return color ?? fallback.name;
|
|
}
|
|
|
|
function set(colorScheme: ColorScheme) {
|
|
const fixedColors = {
|
|
"--bg": colorScheme.bg,
|
|
"--bg-dark": colorScheme.bgDark,
|
|
"--bg-darker": colorScheme.bgDarker,
|
|
"--fg": colorScheme.fg,
|
|
"--fg-dark": colorScheme.fgDark,
|
|
"--fg-darker": colorScheme.fgDarker,
|
|
"--error": colorScheme.error ?? fallback.error!,
|
|
"--warning": colorScheme.warning ?? fallback.warning!
|
|
};
|
|
|
|
for (const [k, v] of Object.entries(fixedColors)) {
|
|
document.documentElement.style.setProperty(k, v);
|
|
}
|
|
}
|
|
|
|
export default function ColorChanger() {
|
|
const [current, setCurrent] = React.useState<string>(fallback.name);
|
|
|
|
// this is a FOUC, but it's fine, right? right?
|
|
React.useEffect(() => {
|
|
const color = getFromLocalStorage();
|
|
setCurrent(color);
|
|
set(colors.find((x) => x.name === color)!);
|
|
}, []);
|
|
|
|
return (
|
|
<Image
|
|
src="/paint.svg"
|
|
width="32"
|
|
height="32"
|
|
alt="paint"
|
|
title={current}
|
|
onClick={() => {
|
|
const pool = colors.filter((x) => x.name !== current);
|
|
const idx = Math.floor(Math.random() * pool.length);
|
|
const colorScheme = pool[idx];
|
|
|
|
set(colorScheme);
|
|
setCurrent(colorScheme.name);
|
|
localStorage.setItem("colorscheme", colorScheme.name);
|
|
}}
|
|
className={styles["colorChanger"]}
|
|
/>
|
|
);
|
|
}
|