Files
zeekayandHanzo Dev 17bd239f2a no utility engine
Tailwind 4 out — the engine import, the `@custom-variant`, and the `@theme
inline` wrapper. The tokens inside it were always plain custom properties and
are untouched; what goes is the thing that was reading them.

Every class attribute now reaches a converter rather than the document: Box for
an element, css for an icon, the component itself for anything from @hanzo/ui.
The body's ground moves into the sheet, since <body> sits outside the provider
and reads no classes.

The library's sheets are imported from the LAYOUT rather than @import-ed from
the app's CSS: a bare package specifier does not resolve in this pipeline and
the failure is silent — the whole file is dropped, so every token goes missing
and the page renders on browser defaults.

Also on the current toolchain: React 19.2.8, Next 16.3.3, TypeScript 7.
Measured at 390px and 1280px: 4/4 page-widths clean, nothing unread.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 02:37:59 -07:00

50 lines
1.7 KiB
TypeScript

'use client';
import { useTheme } from 'next-themes';
import { Box } from '@hanzo/ui'
import { useEffect, useState } from 'react';
export function ThemeToggle() {
const { setTheme, resolvedTheme } = useTheme();
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
if (!mounted) {
return (
<Box tag="button"
className="rounded-lg p-2 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
aria-label="Toggle theme"
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<circle cx="12" cy="12" r="5" />
<path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" />
</svg>
</Box>
);
}
const isDark = resolvedTheme === 'dark';
return (
<Box tag="button"
onClick={() => setTheme(isDark ? 'light' : 'dark')}
className="rounded-lg p-2 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground"
aria-label={`Switch to ${isDark ? 'light' : 'dark'} theme`}
>
{isDark ? (
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<circle cx="12" cy="12" r="5" />
<path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" />
</svg>
) : (
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
</svg>
)}
</Box>
);
}