44 lines
1.4 KiB
TypeScript
44 lines
1.4 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
|
|
|
export function ThemeToggle() {
|
|
const [theme, setTheme] = useState<'dark' | 'light'>('dark');
|
|
|
|
useEffect(() => {
|
|
const stored = localStorage.getItem('theme') as 'dark' | 'light' | null;
|
|
const current = document.documentElement.getAttribute('data-theme') as 'dark' | 'light';
|
|
setTheme(stored || current || 'dark');
|
|
}, []);
|
|
|
|
function toggle() {
|
|
const next = theme === 'dark' ? 'light' : 'dark';
|
|
setTheme(next);
|
|
document.documentElement.setAttribute('data-theme', next);
|
|
localStorage.setItem('theme', next);
|
|
}
|
|
|
|
return (
|
|
<button
|
|
onClick={toggle}
|
|
title={`Switch to ${theme === 'dark' ? 'light' : 'dark'} mode`}
|
|
style={{
|
|
background: 'none',
|
|
border: '1px solid var(--border)',
|
|
borderRadius: 'var(--radius-sm)',
|
|
cursor: 'pointer',
|
|
padding: '5px 10px',
|
|
color: 'var(--ink-muted)',
|
|
fontSize: 12,
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
gap: 6,
|
|
transition: 'border-color 0.15s, color 0.15s',
|
|
}}
|
|
onMouseEnter={e => (e.currentTarget.style.borderColor = 'var(--accent)')}
|
|
onMouseLeave={e => (e.currentTarget.style.borderColor = 'var(--border)')}
|
|
>
|
|
<span>{theme === 'dark' ? '☀️' : '🌙'}</span>
|
|
<span>{theme === 'dark' ? 'Light' : 'Dark'}</span>
|
|
</button>
|
|
);
|
|
}
|