Skip to main content

Dark Mode

md3-react provides built-in support for light, dark, and system color modes.

Basic Usage

The ThemeProvider handles dark mode automatically:

import { ThemeProvider } from '@md3-react/theme';

function App() {
return (
<ThemeProvider defaultColorMode="system">
{/* Components adapt to system preference */}
</ThemeProvider>
);
}

Color Mode Options

ModeDescription
'light'Always use light theme
'dark'Always use dark theme
'system'Follow system preference

Toggling Color Mode

Use the useTheme hook to toggle color modes:

import { useTheme } from '@md3-react/theme';

function ThemeToggle() {
const { colorMode, setColorMode, resolvedColorMode } = useTheme();

return (
<div>
<p>Current mode: {resolvedColorMode}</p>
<button onClick={() => setColorMode('light')}>Light</button>
<button onClick={() => setColorMode('dark')}>Dark</button>
<button onClick={() => setColorMode('system')}>System</button>
</div>
);
}

Theme Toggle Component Example

Here's a complete theme toggle button:

import { useTheme } from '@md3-react/theme';
import { Button, Icon } from '@md3-react/core';

function ThemeToggle() {
const { resolvedColorMode, setColorMode } = useTheme();

const toggleTheme = () => {
setColorMode(resolvedColorMode === 'light' ? 'dark' : 'light');
};

return (
<Button
variant="text"
onClick={toggleTheme}
icon={<Icon name={resolvedColorMode === 'light' ? 'dark_mode' : 'light_mode'} />}
>
{resolvedColorMode === 'light' ? 'Dark Mode' : 'Light Mode'}
</Button>
);
}

Persistence

User color mode preference is automatically persisted to localStorage. The storage key can be customized:

<ThemeProvider storageKey="my-app-theme">{/* ... */}</ThemeProvider>

SSR Considerations

When using SSR, the server doesn't know the user's color preference. The ThemeProvider:

  1. Defaults to 'light' during SSR
  2. Hydrates on the client with the correct preference
  3. Uses useEffect to avoid hydration mismatches

For SSR applications, you may want to add a color scheme meta tag:

<meta name="color-scheme" content="light dark" />

And apply CSS to prevent flash of unstyled content:

html {
color-scheme: light dark;
}

Listening to System Changes

The ThemeProvider automatically listens for system color scheme changes when colorMode is set to 'system'. No additional code is needed.

// Automatically updates when user changes system preference
<ThemeProvider defaultColorMode="system">{/* Components update in real-time */}</ThemeProvider>