-
Notifications
You must be signed in to change notification settings - Fork 38
fix: improved theme logic #504
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🦋 Changeset detectedLatest commit: 5714a28 The changes in this PR will be included in the next version bump. This PR includes changesets to release 9 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Claude finished @ignaciosantise's task —— View job PR Review: Theme Logic ImprovementsSummaryThis PR improves the theme management architecture by introducing a derived state pattern using Issues Found1. Type Safety Issue in
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refactors the theme management logic to introduce a clearer separation between system theme and user-defined default theme using valtio's derived state pattern.
Key Changes:
- Introduced
derive-valtioto create a computedthemeModethat prioritizesdefaultThemeModeoversystemThemeMode - Renamed
setThemeModetosetDefaultThemeModefor the user-facing API and addedsetSystemThemeModefor tracking system theme changes - Updated the modal to always track system theme changes via
setSystemThemeMode, while the hook API usessetDefaultThemeModeto respect user preferences
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/core/src/controllers/ThemeController.ts | Refactored to use derived state pattern with separate system and default theme modes |
| packages/appkit/src/modal/w3m-modal/index.tsx | Updated to use setSystemThemeMode for tracking system theme changes |
| packages/appkit/src/hooks/useAppKitTheme.ts | Changed setThemeMode to call setDefaultThemeMode internally |
| packages/appkit/src/tests/hooks/useAppKitTheme.test.tsx | Updated test expectations to reflect new default behavior and API changes |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| systemThemeMode?: ThemeMode | null; | ||
| defaultThemeMode?: ThemeMode | null; |
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Type inconsistency: systemThemeMode and defaultThemeMode are typed as ThemeMode | null but are initialized with undefined. This creates a mismatch between the type definition and the actual runtime values. Consider either:
- Changing the type to
ThemeMode | null | undefinedorThemeMode | undefined - Initializing with
nullinstead ofundefinedon lines 14-15
This inconsistency could lead to type-safety issues when accessing these properties.
| state.themeMode = themeMode; | ||
| } | ||
| setSystemThemeMode(systemThemeMode?: ThemeControllerState['systemThemeMode']) { | ||
| baseState.systemThemeMode = systemThemeMode ?? 'light'; |
Copilot
AI
Nov 14, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The setSystemThemeMode function always defaults to 'light' when the parameter is undefined or null. However, when the system theme changes to null (which useColorScheme() can return), this will force it to 'light' rather than preserving the null value. This could prevent proper fallback to the default theme mode. Consider allowing null to be set when explicitly passed, or handle the React Native's useColorScheme() null return value more gracefully.
| baseState.systemThemeMode = systemThemeMode ?? 'light'; | |
| baseState.systemThemeMode = systemThemeMode === undefined ? 'light' : systemThemeMode; |
|
|
@claude review |
|
Claude finished @ignaciosantise's task —— View job 🔄 Incremental PR ReviewSummary: 3 of 5 previously identified issues have been resolved. 1 minor type safety issue remains. 2 new minor issues found related to API clarity and documentation. Validation of Previous IssuesIssue #1: Type Safety Issue in
|
Since ThemeController now always provides a defined themeMode via derived state, the useColorScheme fallback in useTheme() is no longer needed. The theme priority is now handled entirely by ThemeController. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| return useMemo(() => { | ||
| // If the theme mode is not set, use the system color scheme | ||
| const themeMode = context?.themeMode ?? scheme; | ||
| const themeMode = context?.themeMode ?? 'light'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Theme defaults to light before system theme initializes
Medium Severity
The refactored theme logic causes a brief flash from light to dark theme on initial render for users with dark system preference. Previously, useTheme() in ThemeContext.tsx called useColorScheme() directly as a fallback when context.themeMode was undefined. Now, the derived themeMode in ThemeController defaults to 'light' when both defaultThemeMode and systemThemeMode are undefined, and setSystemThemeMode is only called in the modal's useEffect (after first render). Components like ConnectButton and AccountButton will initially render with light theme regardless of system preference until the modal mounts and sets the system theme.
Additional Locations (2)
Use a native JavaScript getter instead of derive-valtio for computing themeMode. This ensures synchronous updates and removes the external dependency. The getter pattern is the recommended valtio approach for computed properties that reference sibling properties. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|



Summary
Improved theme and setTheme logic
Note
Refactors theme management to decouple system theme from user-defined default and compute
themeModefrom those sources.systemThemeModeanddefaultThemeModeinThemeControllerwith a computedthemeMode(priority: default > system >light), removesAppearancedependency, and addssetSystemThemeMode/setDefaultThemeModeuseAppKitThemeto expose non-optionalthemeModeand routesetThemeModetoThemeController.setDefaultThemeModew3m-modalnow wires system theme viaThemeController.setSystemThemeModeand passes resolvedthemeMode/themeVariablestoThemeProviderThemeContextnow requiresthemeModeand defaults tolightwhen absentWritten by Cursor Bugbot for commit 5714a28. This will update automatically on new commits. Configure here.