feat: update theme handling and improve icons
All checks were successful
build dist / build-dist (push) Successful in 47s

This commit is contained in:
z0x 2025-05-23 21:04:11 -04:00
parent 0e48c6baf7
commit 17a1981fba
8 changed files with 45 additions and 49 deletions

View file

@ -27,7 +27,7 @@ export default defineConfig({
themes: ["github-light", "github-dark"], themes: ["github-light", "github-dark"],
plugins: [pluginCollapsibleSections(), pluginLineNumbers()], plugins: [pluginCollapsibleSections(), pluginLineNumbers()],
useDarkModeMediaQuery: false, useDarkModeMediaQuery: false,
themeCssSelector: (theme) => `.${theme.name.split("-")[1]}`, themeCssSelector: (theme) => `[data-theme="${theme.name.split("-")[1]}"]`,
defaultProps: { defaultProps: {
wrap: true, wrap: true,
collapseStyle: "collapsible-auto", collapseStyle: "collapsible-auto",

View file

@ -27,7 +27,7 @@ const { items, class: className } = Astro.props;
<BreadcrumbList> <BreadcrumbList>
<BreadcrumbItem> <BreadcrumbItem>
<BreadcrumbLink href="/"> <BreadcrumbLink href="/">
<Icon name="lucide:home" class="size-4" /> <Icon name="lucide:home" class="size-4 shrink-0" />
</BreadcrumbLink> </BreadcrumbLink>
</BreadcrumbItem> </BreadcrumbItem>
{ {
@ -38,15 +38,19 @@ const { items, class: className } = Astro.props;
{index === items.length - 1 ? ( {index === items.length - 1 ? (
<BreadcrumbPage> <BreadcrumbPage>
<span class="flex items-center gap-x-2"> <span class="flex items-center gap-x-2">
{item.icon && <Icon name={item.icon} class="size-4" />} {item.icon && (
{item.label} <Icon name={item.icon} class="size-4 shrink-0" />
)}
<span>{item.label}</span>
</span> </span>
</BreadcrumbPage> </BreadcrumbPage>
) : ( ) : (
<BreadcrumbLink href={item.href}> <BreadcrumbLink href={item.href}>
<span class="flex items-center gap-x-2"> <span class="flex items-center gap-x-2">
{item.icon && <Icon name={item.icon} class="size-4" />} {item.icon && (
{item.label} <Icon name={item.icon} class="size-4 shrink-0" />
)}
<span>{item.label}</span>
</span> </span>
</BreadcrumbLink> </BreadcrumbLink>
)} )}

View file

@ -18,6 +18,7 @@ const { title, description } = Astro.props;
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<meta name="generator" content={Astro.generator} /> <meta name="generator" content={Astro.generator} />
<meta name="HandheldFriendly" content="True" /> <meta name="HandheldFriendly" content="True" />
<meta name="mobile-web-app-capable" content="yes" /> <meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" />

View file

@ -3,7 +3,13 @@ import { Button } from "@/components/ui/button";
import { Icon } from "astro-icon/components"; import { Icon } from "astro-icon/components";
--- ---
<Button id="theme-toggle" variant="ghost" size="icon" title="Toggle theme" className="-me-2 size-8"> <Button
id="theme-toggle"
variant="ghost"
size="icon"
title="Toggle theme"
className="-me-2 size-8"
>
<Icon <Icon
name="lucide:sun" name="lucide:sun"
class="size-4 scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" class="size-4 scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90"
@ -27,30 +33,31 @@ import { Icon } from "astro-icon/components";
return 'light' return 'light'
})() })()
if (theme === 'light') { document.documentElement.setAttribute('data-theme', theme)
document.documentElement.classList.remove('dark') document.documentElement.classList.add(
} else { theme === 'dark' ? 'scheme-dark' : 'scheme-light',
document.documentElement.classList.add('dark') )
}
window.localStorage.setItem('theme', theme) window.localStorage.setItem('theme', theme)
</script> </script>
<script> <script>
function handleToggleClick() { function handleToggleClick() {
const element = document.documentElement const element = document.documentElement
const currentTheme = element.getAttribute('data-theme')
const newTheme = currentTheme === 'dark' ? 'light' : 'dark'
element.classList.add('disable-transitions') element.classList.add('[&_*]:transition-none')
element.classList.toggle('dark') element.setAttribute('data-theme', newTheme)
element.classList.remove('scheme-dark', 'scheme-light')
element.classList.add(newTheme === 'dark' ? 'scheme-dark' : 'scheme-light')
window.getComputedStyle(element).getPropertyValue('opacity') window.getComputedStyle(element).getPropertyValue('opacity')
requestAnimationFrame(() => { requestAnimationFrame(() => {
element.classList.remove('disable-transitions') element.classList.remove('[&_*]:transition-none')
}) })
const isDark = element.classList.contains('dark') localStorage.setItem('theme', newTheme)
localStorage.setItem('theme', isDark ? 'dark' : 'light')
} }
function initThemeToggle() { function initThemeToggle() {
@ -63,21 +70,21 @@ import { Icon } from "astro-icon/components";
initThemeToggle() initThemeToggle()
document.addEventListener('astro:after-swap', () => { document.addEventListener('astro:after-swap', () => {
const storedTheme = localStorage.getItem('theme') const storedTheme = localStorage.getItem('theme') || 'light'
const element = document.documentElement const element = document.documentElement
element.classList.add('disable-transitions') element.classList.add('[&_*]:transition-none')
window.getComputedStyle(element).getPropertyValue('opacity') window.getComputedStyle(element).getPropertyValue('opacity')
if (storedTheme === 'dark') { element.setAttribute('data-theme', storedTheme)
element.classList.add('dark') element.classList.remove('scheme-dark', 'scheme-light')
} else { element.classList.add(
element.classList.remove('dark') storedTheme === 'dark' ? 'scheme-dark' : 'scheme-light',
} )
requestAnimationFrame(() => { requestAnimationFrame(() => {
element.classList.remove('disable-transitions') element.classList.remove('[&_*]:transition-none')
}) })
initThemeToggle() initThemeToggle()

View file

@ -19,7 +19,7 @@ const { title, description } = Astro.props;
--- ---
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en" class="bg-background text-foreground">
<head> <head>
<Head title={`${title} | ${SITE.title}`} description={description} /> <Head title={`${title} | ${SITE.title}`} description={description} />
</head> </head>

View file

@ -55,8 +55,8 @@ const { Content, headings } = await render(post);
> >
<Breadcrumbs <Breadcrumbs
items={[ items={[
{ href: '/blog', label: 'Blog', icon: 'lucide:archive' }, { href: '/blog', label: 'Blog', icon: 'lucide:library-big' },
{ label: post.data.title, icon: 'lucide:file-text' }, { label: post.data.title, icon: 'lucide:book-open-text' },
]} ]}
class="col-start-2" class="col-start-2"
/> />

View file

@ -40,8 +40,8 @@ const years = Object.keys(postsByYear).sort(
<Container class="flex grow flex-col gap-y-6"> <Container class="flex grow flex-col gap-y-6">
<Breadcrumbs <Breadcrumbs
items={[ items={[
{ label: 'Blog', href: '/blog', icon: 'lucide:archive' }, { label: 'Blog', href: '/blog', icon: 'lucide:library-big' },
{ label: `Page ${page.currentPage}`, icon: 'lucide:folder-open' }, { label: `Page ${page.currentPage}`, icon: 'lucide:book-copy' },
]} ]}
/> />

View file

@ -1,6 +1,6 @@
@import "tailwindcss"; @import "tailwindcss";
@custom-variant dark (&:is(.dark *)); @custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
@theme inline { @theme inline {
--font-sans: "Geist Variable", ui-sans-serif, system-ui, sans-serif, --font-sans: "Geist Variable", ui-sans-serif, system-ui, sans-serif,
@ -49,7 +49,7 @@
--ring: oklch(0.708 0 0); --ring: oklch(0.708 0 0);
} }
.dark { [data-theme="dark"] {
--background: oklch(0.145 0 0); --background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0); --foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0); --primary: oklch(0.922 0 0);
@ -73,20 +73,4 @@
::file-selector-button { ::file-selector-button {
@apply border-border outline-ring/50 tracking-tight; @apply border-border outline-ring/50 tracking-tight;
} }
html {
@apply bg-background text-foreground scheme-light;
&.dark {
@apply scheme-dark;
}
::-webkit-scrollbar-corner {
@apply bg-transparent;
}
}
.disable-transitions * {
@apply transition-none!;
}
} }