feat: add theme switcher and themes

This commit is contained in:
Youwen Wu 2024-05-24 21:55:11 -07:00
parent 80fa321ea9
commit f7ca0fc2e9
Signed by: youwen5
GPG key ID: 865658ED1FE61EC3
10 changed files with 137 additions and 18 deletions

View file

@ -1,2 +1,3 @@
lineWidth = 70 lineWidth = 70
proseWrap = "always" proseWrap = "always"
semi = false

View file

@ -1,4 +1,4 @@
# Hakyll-powered blog # gradient ascent
This repository hosts the source code for my blog, powered by This repository hosts the source code for my blog, powered by
[hakyll](https://jaspervdj.be/hakyll/). [hakyll](https://jaspervdj.be/hakyll/).

View file

@ -5,8 +5,8 @@
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1", "test": "echo \"Error: no test specified\" && exit 1",
"build": "postcss -o src/build/css/bundle.css src/css/*.css", "build": "rollup -c",
"watch": "postcss -o src/build/css/bundle.css src/css/*.css --watch" "watch": "rollup -c -w"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",

View file

@ -7,16 +7,16 @@
@layer base { @layer base {
body { body {
@apply bg-gray-950 text-gray-100 font-serif; @apply dark:bg-background-dark bg-background-light dark:text-primary-dark text-primary-light font-serif;
} }
} }
@layer utilities { @layer utilities {
.external-link { .external-link {
@apply text-violet-600 pl-1 pr-4 rounded-sm hover:bg-violet-950 transition-colors duration-300 relative; @apply dark:text-violet-600 text-indigo-600 hover:bg-indigo-200 pr-3 rounded-sm dark:hover:bg-violet-950 transition-colors duration-300 relative;
} }
.external-link::after { .external-link::after {
@apply absolute top-1 right-2 w-2 h-2 border-2 border-violet-600 rounded-full translate-x-1/2 -translate-y-1/2; @apply absolute top-1 right-2 w-2 h-2 border-2 border-indigo-600 dark:border-violet-600 rounded-full translate-x-1/2 -translate-y-1/2;
content: ""; content: "";
} }
.small-caps { .small-caps {

View file

@ -3,27 +3,29 @@ desc: "a blog about computers, math, hacks, games, and life"
image: "./images/robert-pearce-UwHN0jU_YqQ-unsplash-800w.jpg" image: "./images/robert-pearce-UwHN0jU_YqQ-unsplash-800w.jpg"
lang: "en" lang: "en"
stylesheet: "default" stylesheet: "default"
title: "gradient ascent" title: "blog | youwen wu"
--- ---
<main> <main>
<section> <section>
<h2 class="text-3xl">Latest</h2> <h2 class="text-3xl">Latest</h2>
<hr class="sm:mr-2 max-w-sm border-0 h-0.5 bg-gray-500 rounded-md mt-2" /> <hr
class="sm:mr-2 max-w-sm border-0 h-0.5 dark:bg-muted-dark bg-muted-light rounded-md mt-2"
/>
<ul class="mt-6 space-y-4 md:space-y-8"> <ul class="mt-6 space-y-4 md:space-y-8">
$for(posts)$ $for(posts)$
<li class="group"> <li class="group">
<div class="rounded-md p-2"> <div class="rounded-md p-2">
<a <a
href=".$url$" href=".$url$"
class="w-fit group-hover:text-gray-400 transition-colors" class="w-fit dark:group-hover:text-muted-dark group-hover:text-muted-light transition-colors"
> >
<h3 class="text-2xl">$title$</h3> <h3 class="text-2xl">$title$</h3>
<p class="text-sm">$date$</p> <p class="text-sm">$date$</p>
</a> </a>
</div> </div>
<hr <hr
class="max-w-[200px] border-0 h-1 bg-gray-800 rounded-lg px-2 group-hover:max-w-[250px] group-hover:bg-violet-950 transition-all duration-400" class="max-w-[200px] border-0 h-1 dark:bg-accent-dark bg-accent-light rounded-lg px-2 group-hover:max-w-[250px] dark:group-hover:bg-secondary-dark group-hover:bg-secondary-light transition-all duration-400"
/> />
</li> </li>
$endfor$ $endfor$

View file

@ -1 +1,57 @@
import "../css/default.css"; import "../css/default.css"
// @ts-check
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches
const themeSystem = () => {
if (prefersDark) {
document.documentElement.classList.add("dark")
} else {
document.documentElement.classList.remove("dark")
}
}
const themeLight = () => {
document.documentElement.classList.remove("dark")
}
const themeDark = () => {
document.documentElement.classList.add("dark")
}
let currentTheme =
localStorage.getItem("theme") === "dark"
? 2
: localStorage.getItem("theme") === "light"
? 1
: 0
const themeButton = document.getElementById("theme-toggle")
themeButton.addEventListener("click", () => {
currentTheme = (currentTheme + 1) % 3
switch (currentTheme) {
case 0:
localStorage.removeItem("theme")
themeSystem()
themeButton.innerText = "theme: system"
break
case 1:
if (prefersDark) {
localStorage.setItem("theme", "light")
themeLight()
themeButton.innerText = "theme: light"
} else {
localStorage.setItem("theme", "dark")
themeDark()
themeButton.innerText = "theme: dark"
}
break
case 2:
if (prefersDark) {
localStorage.setItem("theme", "dark")
themeDark()
themeButton.innerText = "theme: dark"
} else {
localStorage.setItem("theme", "light")
themeLight()
themeButton.innerText = "theme: light"
}
break
}
})

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
const e=window.matchMedia("(prefers-color-scheme: dark)").matches,t=()=>{document.documentElement.classList.remove("dark")},m=()=>{document.documentElement.classList.add("dark")};let a="dark"===localStorage.getItem("theme")?2:"light"===localStorage.getItem("theme")?1:0;const c=document.getElementById("theme-toggle");c.addEventListener("click",(()=>{switch(a=(a+1)%3,a){case 0:localStorage.removeItem("theme"),e?document.documentElement.classList.add("dark"):document.documentElement.classList.remove("dark"),c.innerText="theme: system";break;case 1:e?(localStorage.setItem("theme","light"),t(),c.innerText="theme: light"):(localStorage.setItem("theme","dark"),m(),c.innerText="theme: dark");break;case 2:e?(localStorage.setItem("theme","dark"),m(),c.innerText="theme: dark"):(localStorage.setItem("theme","light"),t(),c.innerText="theme: light")}}));

View file

@ -51,11 +51,34 @@
<link rel="stylesheet" href="./out/bundle.css" /> <link rel="stylesheet" href="./out/bundle.css" />
<link rel="stylesheet" href="./css/code.css" /> <link rel="stylesheet" href="./css/code.css" />
<script>
if (
localStorage.theme === "dark" ||
(!("theme" in localStorage) &&
window.matchMedia("(prefers-color-scheme: dark)").matches)
) {
document.documentElement.classList.add("dark")
} else {
document.documentElement.classList.remove("dark")
}
window.onload = () => {
var themeButton = document.getElementById("theme-toggle")
const theme = localStorage.getItem("theme")
if (theme === "light") {
themeButton.innerText = "theme: light"
} else if (theme === "dark") {
themeButton.innerText = "theme: dark"
} else {
themeButton.innerText = "theme: system"
}
}
</script>
</head> </head>
<body class="container max-w-3xl mx-auto px-4"> <body class="container max-w-3xl mx-auto px-4">
<header class="mt-14 md:mt-24 mb-14"> <header class="mt-14 md:mt-24 mb-14">
<h1 class="text-4xl md:text-5xl font-serif font-medium"> <h1 class="text-4xl md:text-5xl font-serif font-medium">
<a href="/" class="hover:text-gray-500 transition-colors" <a href="/" class="dark:hover:text-muted-dark transition-colors"
>Gradient Ascent</a >Gradient Ascent</a
> >
</h1> </h1>
@ -65,19 +88,33 @@
<a class="text-sm external-link" href="https://youwen.dev" <a class="text-sm external-link" href="https://youwen.dev"
>by Youwen Wu</a >by Youwen Wu</a
> >
<span class="ml-2 font-serif">|</span>
<button
id="theme-toggle"
class="ml-2 text-sm hover:bg-secondary-light dark:hover:bg-secondary-dark rounded-sm transition-colors p-1"
></button>
</header> </header>
$body$ $body$
<footer class="mt-14 md:mt-24 pb-12"> <footer class="mt-14 md:mt-24 pb-12">
<hr class="border-0 bg-gray-400 rounded-xl h-0.5 mb-4" /> <hr
<p class="text-sm"> class="border-0 dark:bg-muted-dark bg-muted-light rounded-xl h-0.5 mb-4"
&copy; 2024 Youwen Wu. Powered by />
<p class="text-sm leading-relaxed">
&copy; 2024 Youwen Wu. Generated by
<a <a
href="https://jaspervdj.be/hakyll/" href="https://jaspervdj.be/hakyll/"
class="external-link" class="external-link"
target="__blank" target="__blank"
>Hakyll.</a >Hakyll.</a
> >
Content freely available under View the source
<a
href="https://github.com/couscousdude/blog"
class="external-link"
target="__blank"
>on GitHub.</a
>
<br />Content freely available under
<a <a
class="external-link" class="external-link"
target="__blank" target="__blank"

View file

@ -1,5 +1,6 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
module.exports = { module.exports = {
darkMode: "selector",
content: ["./src/**/*.{html,js}"], content: ["./src/**/*.{html,js}"],
theme: { theme: {
extend: { extend: {
@ -7,6 +8,28 @@ module.exports = {
sans: ["Inter", "sans-serif"], sans: ["Inter", "sans-serif"],
serif: ["Merriweather", "serif"], serif: ["Merriweather", "serif"],
}, },
colors: {
primary: {
dark: "#e2e8f0",
light: "#0a0a0a",
},
secondary: {
dark: "#2e1065",
light: "#4f46e5",
},
accent: {
dark: "#9ca3af",
light: "#78716c",
},
muted: {
dark: "#6b7280",
light: "#a8a29e",
},
background: {
light: "#d6d3d1",
dark: "#030712",
},
},
}, },
}, },
plugins: [require("@tailwindcss/typography")], plugins: [require("@tailwindcss/typography")],