Skip to content

Commit d9732e4

Browse files
committed
refactor: improve ModeToggle code clarity
1 parent b23ac9c commit d9732e4

File tree

1 file changed

+41
-34
lines changed

1 file changed

+41
-34
lines changed

src/components/ModeToggle.tsx

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,53 @@
11
import { cn } from '@/lib/utils';
22
import { Monitor, Moon, Sun } from 'lucide-react';
3+
import { useMemo } from 'react';
34
import { useTheme } from '@/components/themeProvider';
45
import { Button } from '@/components/ui/button';
56

7+
type Theme = 'dark' | 'light' | 'system';
8+
69
export function ModeToggle() {
710
const { theme, setTheme } = useTheme();
811

12+
const options: Array<{
13+
value: Theme;
14+
label: string;
15+
Icon: React.ComponentType<any>;
16+
}> = useMemo(
17+
() => [
18+
{ value: 'system', label: 'System', Icon: Monitor },
19+
{ value: 'light', label: 'Light', Icon: Sun },
20+
{ value: 'dark', label: 'Dark', Icon: Moon },
21+
],
22+
[]
23+
);
24+
925
return (
10-
<div className="rounded-full border p-1">
11-
<Button
12-
variant={'link'}
13-
size={'none'}
14-
className={cn(
15-
'text-foreground hover:bg-muted border p-1',
16-
theme === 'system' ? 'border' : 'border-transparent'
17-
)}
18-
onClick={() => setTheme('system')}
19-
>
20-
<Monitor />
21-
</Button>
22-
<Button
23-
variant={'link'}
24-
size={'none'}
25-
className={cn(
26-
'text-foreground hover:bg-muted border p-1',
27-
theme === 'light' ? 'border' : 'border-transparent'
28-
)}
29-
onClick={() => setTheme('light')}
30-
>
31-
<Sun />
32-
</Button>
33-
<Button
34-
variant={'link'}
35-
size={'none'}
36-
className={cn(
37-
'text-foreground hover:bg-muted border p-1',
38-
theme === 'dark' ? 'border' : 'border-transparent'
39-
)}
40-
onClick={() => setTheme('dark')}
41-
>
42-
<Moon />
43-
</Button>
26+
<div className="flex items-center rounded-full border p-1">
27+
{options.map(({ value, label, Icon }) => {
28+
const selected = theme === value;
29+
return (
30+
<Button
31+
key={value}
32+
type="button"
33+
variant="link"
34+
size="none"
35+
role="radio"
36+
aria-checked={selected}
37+
aria-label={label}
38+
title={label}
39+
className={cn(
40+
'text-foreground hover:bg-muted p-1',
41+
selected && 'bg-transparent'
42+
)}
43+
onClick={() => {
44+
if (theme !== value) setTheme(value as Theme);
45+
}}
46+
>
47+
<Icon />
48+
</Button>
49+
);
50+
})}
4451
</div>
4552
);
4653
}

0 commit comments

Comments
 (0)