Skip to content

Implement theme toggle and dark mode support#66

Merged
algotyrnt merged 6 commits into
mainfrom
dev
May 15, 2026
Merged

Implement theme toggle and dark mode support#66
algotyrnt merged 6 commits into
mainfrom
dev

Conversation

@algotyrnt
Copy link
Copy Markdown
Owner

@algotyrnt algotyrnt commented May 15, 2026

This pull request introduces a dark mode theme to the application and refactors the theme system for better support of dynamic color schemes. It adds a theme toggle button to the header, updates global CSS variables for both light and dark modes, and integrates the next-themes package for seamless theme switching. There are also several adjustments to the MUI theme setup to ensure consistent appearance across modes.

Dark mode support and theme system refactor:

  • Added CSS variables for colors, shadows, and borders in both light and dark modes in globals.css, and updated background and selection styles to use these variables. (src/app/globals.css) [1] [2] [3]
  • Refactored the MUI theme system to dynamically generate themes based on the current mode using a new getTheme function, and updated token usage to rely on CSS variables. (src/components/theme/theme.ts, src/components/theme/tokens.ts) [1] [2] [3]
  • Replaced the default MUI ThemeProvider with a wrapper that uses next-themes for theme detection and switching, enabling system and user-controlled themes. (src/components/theme/registry.tsx) [1] [2]

UI enhancements for theme switching:

  • Added a ThemeToggle button to the header navigation, allowing users to switch between light and dark themes. (src/components/layout/header.tsx, src/components/theme/theme-toggle.tsx) [1] [2] [3]
  • Updated the viewport themeColor to reflect the active color scheme for better browser integration. (src/app/layout.tsx)

Dependency updates:

  • Added the next-themes package and bumped the app version to 2.5.0 in package.json. (package.json) [1] [2]

Summary by CodeRabbit

  • New Features
    • Added a theme toggle button to switch between light and dark modes
    • System color scheme preferences are automatically detected and applied
    • Browser UI elements now adapt their color based on your selected theme

Review Change Stack

Copilot AI review requested due to automatic review settings May 15, 2026 05:59
@algotyrnt algotyrnt self-assigned this May 15, 2026
@vercel
Copy link
Copy Markdown

vercel Bot commented May 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
personal-site Ready Ready Preview, Comment May 15, 2026 6:17am

@algotyrnt algotyrnt added the enhancement New feature or request label May 15, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

Warning

Rate limit exceeded

@algotyrnt has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 41 minutes and 24 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fcf456b4-295f-4830-b7ae-842574f6a5b5

📥 Commits

Reviewing files that changed from the base of the PR and between faa6450 and 8b44955.

📒 Files selected for processing (3)
  • src/components/theme/registry.tsx
  • src/components/theme/theme-toggle.tsx
  • src/components/theme/tokens.ts
📝 Walkthrough

Walkthrough

The PR implements a complete dark mode theme system using CSS custom properties and the next-themes library. It refactors static MUI theming to dynamic mode-aware configuration, adds a theme toggle control to the UI, and updates metadata to reflect light/dark preferences.

Changes

Dark Mode Theme System

Layer / File(s) Summary
CSS Variables and Design Tokens
src/app/globals.css, src/components/theme/tokens.ts
CSS custom properties for colors, shadows, borders, and effects are defined in :root with .dark overrides; design tokens are refactored to reference these variables instead of hardcoded values, adding primaryMainHex for MUI integration.
MUI Theme Factory Refactoring
src/components/theme/theme.ts
Static theme export is replaced with getTheme(mode: PaletteMode) factory that dynamically selects palette colors and text based on light/dark mode while maintaining all component overrides and typography rules.
Theme Provider and next-themes Setup
src/components/theme/registry.tsx
New MuiThemeWrapper component resolves the active mode via useTheme() and passes the corresponding MUI theme to ThemeProvider; ThemeRegistry wraps the app under NextThemesProvider with system preference detection.
Theme Toggle Component
src/components/theme/theme-toggle.tsx
Client-side component that tracks mount state, reads the resolved theme from next-themes, renders dark/light icons, and toggles the active theme on click using design token colors.
Header Integration and Viewport Metadata
src/components/layout/header.tsx, src/app/layout.tsx
Theme toggle is rendered in the header navigation with spacing and border styling; viewport meta tag is updated to support light/dark colors based on prefers-color-scheme media query.
Dependencies and Version Update
package.json
Version bumped to 2.5.0 and next-themes@^0.4.6 is added to dependencies.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • algotyrnt/nova#59: Establishes the initial theming foundation that this PR extends by refactoring tokens and adding dynamic mode-aware theme generation.

Suggested labels

enhancement, dependencies

Poem

🐰 A toggle appears, light becomes dark,
CSS variables spark a thematic arc,
MUI themes dance to next-themes' call,
The rabbit grins—dark mode for all! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Implement theme toggle and dark mode support' clearly and specifically summarizes the main changes across the PR, which add dark mode support, theme toggling, CSS variables, and dynamic theme generation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a 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 adds dark mode support and a theme toggle to the Next.js + MUI app by integrating next-themes, introducing light/dark CSS variables, and refactoring theme creation to be mode-aware.

Changes:

  • Added CSS variables for light/dark design tokens (shadows, borders, selection, scrollbar) and hooked them into global styles.
  • Refactored MUI theme creation into a getTheme(mode) function and updated the theme registry to follow the resolved next-themes mode.
  • Introduced a header theme toggle control and added next-themes as a dependency.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/components/theme/tokens.ts Moves several tokens to CSS-variable-based values and adds a hex primary for MUI palette usage.
src/components/theme/theme.ts Replaces a static theme with a mode-based getTheme generator.
src/components/theme/theme-toggle.tsx Adds a client-side theme toggle button using next-themes.
src/components/theme/registry.tsx Wraps MUI theming with next-themes to sync theme mode and apply baseline styles.
src/components/layout/header.tsx Adds the theme toggle to the header UI.
src/app/layout.tsx Updates viewport.themeColor to include light/dark media variants.
src/app/globals.css Adds light/dark CSS variables and updates selection/scrollbar/background styling.
package.json Bumps version and adds next-themes.
package-lock.json Locks next-themes and updates app version.
Comments suppressed due to low confidence (1)

src/app/globals.css:76

  • The @media (prefers-color-scheme: dark) block forces html { color-scheme: dark; } based on OS preference, so if a user manually toggles to light theme on a dark system (or vice versa), form controls/scrollbars may remain in the wrong color-scheme. Consider tying color-scheme to the .dark class (or enabling next-themes’ color-scheme support) so it follows the selected theme.
@media (prefers-color-scheme: dark) {
  html {
    color-scheme: dark;
  }
}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/app/layout.tsx
Comment on lines 19 to +25
export const viewport: Viewport = {
width: 'device-width',
initialScale: 1,
themeColor: '#fcfcfc',
themeColor: [
{ media: '(prefers-color-scheme: light)', color: '#fcfcfc' },
{ media: '(prefers-color-scheme: dark)', color: '#09090b' },
],
Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

too much for too little.

Comment thread src/components/theme/tokens.ts
Comment thread src/components/theme/theme-toggle.tsx Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/components/theme/theme-toggle.tsx (1)

23-23: ⚡ Quick win

Make the toggle’s ARIA semantics state-aware.

Line 23 uses a static label; expose current state/action for assistive tech (aria-pressed + dynamic label).

♿ Suggested update
-      aria-label="Toggle theme"
+      aria-label={isDark ? 'Switch to light mode' : 'Switch to dark mode'}
+      aria-pressed={isDark}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/theme/theme-toggle.tsx` at line 23, The theme toggle currently
uses a static aria-label ("Toggle theme") which doesn't communicate the current
state; update the ThemeToggle component to expose state-aware ARIA semantics by
adding aria-pressed bound to the dark/light state (e.g., aria-pressed={isDark})
and replacing the static aria-label with a dynamic label reflecting the action
(e.g., "Switch to light theme" or "Switch to dark theme" based on isDark).
Locate the toggle element in src/components/theme/theme-toggle.tsx and update
its attributes (aria-pressed and aria-label) to derive from the component's
state/prop that indicates the current theme.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/components/theme/registry.tsx`:
- Around line 12-15: The component computes currentTheme using resolvedTheme in
a useMemo which falls back to 'light' on SSR, causing FOUC; modify the component
to track mount status (e.g., a mounted state set to true inside useEffect) and
only derive/render currentTheme (via getTheme and the useMemo that depends on
resolvedTheme) after mounted is true so the theme is computed with the
client-resolved resolvedTheme; update any JSX that uses currentTheme to render a
placeholder or null until mounted to avoid rendering the light fallback on
server.

---

Nitpick comments:
In `@src/components/theme/theme-toggle.tsx`:
- Line 23: The theme toggle currently uses a static aria-label ("Toggle theme")
which doesn't communicate the current state; update the ThemeToggle component to
expose state-aware ARIA semantics by adding aria-pressed bound to the dark/light
state (e.g., aria-pressed={isDark}) and replacing the static aria-label with a
dynamic label reflecting the action (e.g., "Switch to light theme" or "Switch to
dark theme" based on isDark). Locate the toggle element in
src/components/theme/theme-toggle.tsx and update its attributes (aria-pressed
and aria-label) to derive from the component's state/prop that indicates the
current theme.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: aa20964a-0b1c-4aa4-a9d0-1b2774fe19c4

📥 Commits

Reviewing files that changed from the base of the PR and between 76f1e53 and faa6450.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (8)
  • package.json
  • src/app/globals.css
  • src/app/layout.tsx
  • src/components/layout/header.tsx
  • src/components/theme/registry.tsx
  • src/components/theme/theme-toggle.tsx
  • src/components/theme/theme.ts
  • src/components/theme/tokens.ts

Comment thread src/components/theme/registry.tsx
@algotyrnt algotyrnt merged commit 3c3ad57 into main May 15, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants