Mode Switching
Switch between light, dark, and system modes with automatic detection.
Implement smooth, user-friendly theme switching with animations, persistence, and advanced transition effects. RNC Theme provides powerful tools for creating seamless theme experiences.
Theme switching in RNC Theme supports:
Mode Switching
Switch between light, dark, and system modes with automatic detection.
Preset Switching
Change between registered theme presets instantly.
Smooth Animations
Animated transitions with customizable duration and easing.
Persistence
Automatic saving and restoration of user theme preferences.
Targeted Updates
Update specific theme properties without full theme replacement.
Performance
Optimized switching with minimal re-renders and smooth performance.
import { useTheme } from 'rnc-theme';
function ThemeModeToggle() { const { themeMode, setThemeMode, isDark, } = useTheme();
const toggleMode = () => { setThemeMode(isDark ? 'light' : 'dark'); };
return ( <TouchableOpacity onPress={toggleMode}> <Text>{isDark ? '☀️' : '🌙'}</Text> <Text>{themeMode} mode</Text> </TouchableOpacity> );}
import { useTheme } from 'rnc-theme';
function ThemeCustomizer() { const { updateCustomTheme } = useTheme();
const preset = { colors: { primary: 'blue', background: 'white', }, // ...rest };
const applyBrandTheme = () => { updateCustomTheme( // ...preset ); };
return ( <Button onPress={applyBrandTheme}> Apply Brand Theme </Button> );}
updateCustomTheme
is used to apply custom theme presets to your app. You can create a theme preset object with the desired color, spacing, and other theme properties, and then pass it to updateCustomTheme
to apply it to your app.
<ToggleMode/>
You can simply use <ToggleMode/>
component to switch between light and dark modes.
import { View } from 'react-native';import { ToggleMode } from 'rnc-theme';
function ThemeSwitcher() { return ( <View> <ToggleMode /> </View> );}
<ThemeManager/>
You can use <ThemeManager/>
component to manage theme presets and switch between them.
import { useMemo } from 'react';import { ThemeManager, Box } from 'rnc-theme';
function ThemeManagerComponent() { const materialThemeConfig: CustomThemeConfigFactory = useMemo( () => (isDark: boolean) => ({ colors: { primary: '#6200EE', secondary: '#03DAC6', background: isDark ? '#121212' : '#FFFFFF', surface: isDark ? '#1E1E1E' : '#FFFFFF', text: isDark ? '#FFFFFF' : '#000000', textSecondary: isDark ? '#B3B3B3' : '#757575', border: isDark ? '#2C2C2C' : '#E0E0E0', error: '#B00020', warning: '#FF6F00', success: '#00C853', info: '#2962FF', muted: isDark ? '#666666' : '#999999', accent: '#6200EE', destructive: '#B00020', }, components: { height: { xs: 32, sm: 36, md: 40, lg: 44, xl: 48, }, padding: { xs: 8, sm: 12, md: 16, lg: 20, xl: 24, }, borderRadius: { xs: 4, sm: 4, md: 4, lg: 8, xl: 12, full: 9999, }, }, spacing: { xs: 4, sm: 8, md: 16, lg: 24, xl: 32, xxl: 48, }, typography: { caption: { fontSize: 10, lineHeight: 14, fontWeight: '400' }, small: { fontSize: 12, lineHeight: 16, fontWeight: '400' }, body: { fontSize: 16, lineHeight: 24, fontWeight: '400' }, subtitle: { fontSize: 18, lineHeight: 26, fontWeight: '500' }, title: { fontSize: 20, lineHeight: 28, fontWeight: '600' }, heading: { fontSize: 24, lineHeight: 32, fontWeight: '700' }, }, fontSizes: { xs: 12, sm: 14, md: 16, lg: 18, xl: 20, xxl: 24, }, }), [] );
const neonThemeConfig: CustomThemeConfigFactory = useMemo( () => (isDark: boolean) => ({ colors: { primary: '#00FFFF', secondary: '#FF00FF', background: isDark ? '#0a0a0a' : '#f0f0f0', surface: isDark ? '#1a1a1a' : '#ffffff', text: isDark ? '#00FFFF' : '#333333', textSecondary: isDark ? '#FF00FF' : '#666666', border: isDark ? '#00FFFF' : '#e0e0e0', error: '#FF0040', warning: '#FFFF00', success: '#00FF40', info: '#4080FF', muted: isDark ? '#666666' : '#999999', accent: '#FF00FF', destructive: '#FF0040', }, components: { height: { xs: 32, sm: 36, md: 40, lg: 44, xl: 48, }, padding: { xs: 8, sm: 12, md: 16, lg: 20, xl: 24, }, borderRadius: { xs: 2, sm: 2, md: 4, lg: 8, xl: 16, full: 9999, }, }, spacing: { xs: 4, sm: 8, md: 16, lg: 24, xl: 32, xxl: 48, }, typography: { caption: { fontSize: 10, lineHeight: 14, fontWeight: '400' }, small: { fontSize: 12, lineHeight: 16, fontWeight: '400' }, body: { fontSize: 16, lineHeight: 24, fontWeight: '400' }, subtitle: { fontSize: 18, lineHeight: 26, fontWeight: '500' }, title: { fontSize: 20, lineHeight: 28, fontWeight: '600' }, heading: { fontSize: 24, lineHeight: 32, fontWeight: '700' }, }, fontSizes: { xs: 12, sm: 14, md: 16, lg: 18, xl: 20, xxl: 24, }, }), [] );
const themePresets: ThemePresetConfig[] = useMemo( () => [ { key: 'material', label: 'Material Design', config: materialThemeConfig, }, { key: 'neon', label: 'Neon Glow', config: neonThemeConfig, }, ], [materialThemeConfig, neonThemeConfig] );
const handleThemeApplied = (theme: string) => { console.log(`Theme applied: ${theme}`); };
const handleThemePreview = (theme: string) => { console.log(`Theme previewed: ${theme}`); }; return ( <Box> <ThemeManager themePresets={themePresets} initialTheme="default" onThemeApplied={handleThemeApplied} onThemePreview={handleThemePreview} > {/* Demo content for default version */} <Card style={styles.demoCard}> <CardHeader title="Demo Content - Default" /> <CardContent> <Typography variant="body" style={styles.demoText}> This is the default ThemeManager with standard labels and messages. </Typography <View style={styles.buttonContainer}> <Button variant="primary" style={styles.demoButton}> <ButtonText>Primary Button</ButtonText> </Button <Button variant="secondary" style={styles.demoButton}> <ButtonText>Secondary Button</ButtonText> </Button <Button variant="outline" style={styles.demoButton}> <ButtonText>Outline Button</ButtonText> </Button> </View <View style={styles.colorDemo}> <View style={[ styles.colorBox, { backgroundColor: theme.colors.primary }, ]} /> <View style={[ styles.colorBox, { backgroundColor: theme.colors.secondary }, ]} /> <View style={[ styles.colorBox, { backgroundColor: theme.colors.accent }, ]} /> <View style={[ styles.colorBox, { backgroundColor: theme.colors.success }, ]} /> <View style={[ styles.colorBox, { backgroundColor: theme.colors.warning }, ]} /> <View style={[ styles.colorBox, { backgroundColor: theme.colors.error }, ]} /> </View> </CardContent> </Card> </ThemeManager> </Box> );}
Using preset builtin, import { presetThemes } from 'rnc-theme'
import { presetThemes } from 'rnc-theme'
export default function Component() { const handleThemeApplied = (theme: string) => { console.log(`Theme applied: ${theme}`); };
const handleThemePreview = (theme: string) => { console.log(`Theme previewed: ${theme}`); };
return ( <ThemeManager themePresets={presetThemes} initialTheme="default" onThemeApplied={handleThemeApplied} onThemePreview={handleThemePreview} > {/* children */} </ThemeManager> )}
Need more details?
Check out our API reference documentation for complete details on ToggleModeProps
and ThemeManagerProps
types.