Skip to content

Commit 2d2de6c

Browse files
mkdir700claude
andauthored
fix: Fix system theme toggle in Sidebar (#224)
* conductor-checkpoint-start * feat(sidebar): add system theme option to sidebar theme toggle Enhance the theme toggle functionality in the sidebar to support cycling through all three theme modes: light → dark → system → light, instead of just alternating between light and dark. - Add Monitor icon from lucide-react for system theme display - Update click handler to cycle through ThemeMode.light, ThemeMode.dark, and ThemeMode.system - Update icon rendering logic to show Monitor icon when system theme is active 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * conductor-checkpoint-msg_2025101919535727204b0a6f3c438c * conductor-checkpoint-msg_20251019195555b541a7966005447a * fix(sidebar): use settedTheme for theme switching logic Fix the theme switching functionality when in system mode by using settedTheme instead of actualTheme for state comparison and icon display. - Use settedTheme to determine current theme mode for switching logic - Use settedTheme to display correct icon (Sun/Moon/Monitor) - Keep theme prop for Icon component styling (actual theme appearance) - Update tooltip to show settedTheme label instead of actualTheme Resolves issue where theme switching was stuck after selecting system theme. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor(sidebar): update lucide-react icon imports to use direct exports * refactor(sidebar): replace theme switching if/else with array-based cycle Replace verbose three-branch if/else structure with a simple array-based cycle mechanism. This eliminates branching logic, centralizes the theme sequence, and makes the code easier to test and maintain. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor(sidebar): rename theme prop to $resolvedTheme to avoid conflicts - rename styled component prop from 'theme' to '$resolvedTheme' to prevent naming conflicts - update all Icon component usages to use the new prop name - maintain same functionality while improving prop naming clarity --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent d87a723 commit 2d2de6c

1 file changed

Lines changed: 27 additions & 17 deletions

File tree

src/renderer/src/components/app/Sidebar.tsx

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ import { isMac, ThemeMode } from '@renderer/infrastructure'
44
import { useFullscreen } from '@renderer/infrastructure/hooks/useFullscreen'
55
import useNavBackgroundColor from '@renderer/infrastructure/hooks/useNavBackgroundColor'
66
import { Tooltip } from 'antd'
7-
import { LucideHeart, LucideHome, Moon, Settings, Sun } from 'lucide-react'
7+
import { Heart, Home, Monitor, Moon, Settings, Sun } from 'lucide-react'
88
import { FC } from 'react'
99
import { useTranslation } from 'react-i18next'
1010
import { useLocation, useNavigate } from 'react-router-dom'
1111
import styled from 'styled-components'
1212

1313
const Sidebar: FC = () => {
14-
const { token, theme, setTheme } = useTheme()
14+
const { token, theme, settedTheme, setTheme } = useTheme()
1515
const backgroundColor = useNavBackgroundColor()
1616
const isFullscreen = useFullscreen()
1717
const { pathname } = useLocation()
@@ -22,6 +22,14 @@ const Sidebar: FC = () => {
2222
navigate(path)
2323
}
2424

25+
const themeRotation = [ThemeMode.light, ThemeMode.dark, ThemeMode.system]
26+
27+
const cycleTheme = () => {
28+
const currentIndex = themeRotation.indexOf(settedTheme)
29+
const nextIndex = (currentIndex + 1) % themeRotation.length
30+
setTheme(themeRotation[nextIndex])
31+
}
32+
2533
return (
2634
<Container
2735
$isFullscreen={isFullscreen}
@@ -34,15 +42,14 @@ const Sidebar: FC = () => {
3442
<Divider />
3543
<Menus>
3644
<Tooltip
37-
title={t('settings.theme.title') + ': ' + getThemeModeLabel(theme)}
45+
title={t('settings.theme.title') + ': ' + getThemeModeLabel(settedTheme)}
3846
mouseEnterDelay={0.8}
3947
placement="right"
4048
>
41-
<Icon
42-
theme={theme}
43-
onClick={() => setTheme(theme === ThemeMode.dark ? ThemeMode.light : ThemeMode.dark)}
44-
>
45-
{theme === ThemeMode.dark ? (
49+
<Icon $resolvedTheme={theme} onClick={cycleTheme}>
50+
{settedTheme === ThemeMode.system ? (
51+
<Monitor size={20} className="icon" />
52+
) : settedTheme === ThemeMode.dark ? (
4653
<Moon size={20} className="icon" />
4754
) : (
4855
<Sun size={20} className="icon" />
@@ -55,7 +62,10 @@ const Sidebar: FC = () => {
5562
await to('/settings/appearance')
5663
}}
5764
>
58-
<Icon theme={theme} className={pathname.startsWith('/settings') ? 'active' : ''}>
65+
<Icon
66+
$resolvedTheme={theme}
67+
className={pathname.startsWith('/settings') ? 'active' : ''}
68+
>
5969
<Settings size={20} className="icon" />
6070
</Icon>
6171
</StyledLink>
@@ -83,13 +93,13 @@ const MainMenus: FC = () => {
8393
const menuItems = {
8494
home: {
8595
path: '/',
86-
icon: <LucideHome size={20} className="icon" />,
96+
icon: <Home size={20} className="icon" />,
8797
label: t('common.home'),
8898
disabled: false
8999
},
90100
favorites: {
91101
path: '/favorites',
92-
icon: <LucideHeart size={20} className="icon" />,
102+
icon: <Heart size={20} className="icon" />,
93103
label: t('common.favorites'),
94104
disabled: true
95105
}
@@ -112,7 +122,7 @@ const MainMenus: FC = () => {
112122
className={isActive ? 'active' : ''}
113123
>
114124
<Icon
115-
theme={theme}
125+
$resolvedTheme={theme}
116126
className={`${isActive ? 'active' : ''} ${item.disabled ? 'disabled' : ''}`}
117127
>
118128
{item.icon}
@@ -160,7 +170,7 @@ const Menus = styled.div`
160170
gap: 5px;
161171
`
162172

163-
const Icon = styled.div<{ theme: string }>`
173+
const Icon = styled.div<{ $resolvedTheme: string }>`
164174
width: 35px;
165175
height: 35px;
166176
display: flex;
@@ -171,8 +181,8 @@ const Icon = styled.div<{ theme: string }>`
171181
-webkit-app-region: none;
172182
border: 0.5px solid transparent;
173183
&:hover {
174-
background-color: ${({ theme }) =>
175-
theme === 'dark' ? 'var(--color-black)' : 'var(--color-white)'};
184+
background-color: ${({ $resolvedTheme }) =>
185+
$resolvedTheme === 'dark' ? 'var(--color-black)' : 'var(--color-white)'};
176186
opacity: 0.8;
177187
cursor: pointer;
178188
.icon {
@@ -195,8 +205,8 @@ const Icon = styled.div<{ theme: string }>`
195205
}
196206
}
197207
&.active {
198-
background-color: ${({ theme }) =>
199-
theme === 'dark' ? 'var(--color-black)' : 'var(--color-white)'};
208+
background-color: ${({ $resolvedTheme }) =>
209+
$resolvedTheme === 'dark' ? 'var(--color-black)' : 'var(--color-white)'};
200210
border: 0.5px solid var(--color-border);
201211
.icon {
202212
color: var(--color-primary);

0 commit comments

Comments
 (0)