Skip to content

Theming & Dark Mode

@masumdev/rn-ui features a typed theme engine with built-in dark mode support, reactive hooks, dynamic style resolution, and storage hydration.

ThemeProvider API

PropTypeDefaultDescription
childrenReactNodeApplication components wrapped by the provider.
colorScheme'light' | 'dark' | 'system'Controlled color scheme value.
defaultColorScheme'light' | 'dark' | 'system''system'Uncontrolled initial color scheme preference.
themes{ light?: ThemeInput; dark?: ThemeInput }Custom light and dark theme object overrides.
storage{ getItem: (key: string) => Promise<string | null>; setItem: (key: string, val: string) => Promise<void> }Storage instance for persisting color scheme (e.g., SecureStore or AsyncStorage).
storageKeystring'rn-ui-color-scheme'Key name used in persistent storage.
onColorSchemeChange(colorScheme: ColorSchemePreference) => voidCallback triggered whenever the user updates the color scheme.

Using the useTheme Hook

Access active theme colors, mode state, and toggle functions from any component:

ThemeToggleExample.tsx
import React from 'react';
import { useTheme, Button, Text, Box } from '@masumdev/rn-ui';
export function ThemeToggleExample() {
const { colors, colorScheme, isDark, toggleColorScheme, setColorScheme } = useTheme();
return (
<Box style={{ backgroundColor: colors.background, padding: 16 }}>
<Text style={{ color: colors.text }}>
Current Mode: {colorScheme} (Active: {isDark ? 'Dark' : 'Light'})
</Text>
<Box row gap="sm" style={{ marginTop: 12 }}>
<Button size="sm" tone="primary" onPress={toggleColorScheme}>
Toggle Dark Mode
</Button>
<Button size="sm" variant="outline" onPress={() => setColorScheme('system')}>
Use System
</Button>
</Box>
</Box>
);
}

Using the useThemeStyles Hook

Create type-safe, performance-optimized style objects driven by active theme tokens:

CustomStyledCard.tsx
import React from 'react';
import { View, Text } from 'react-native';
import { useThemeStyles } from '@masumdev/rn-ui';
export function CustomStyledCard() {
const styles = useStyles();
return (
<View style={styles.card}>
<Text style={styles.title}>Type-Safe Theme Stylesheet</Text>
</View>
);
}
function useStyles() {
return useThemeStyles((theme) => ({
card: {
backgroundColor: theme.colors.surface,
borderRadius: theme.radii.xl,
padding: theme.spacing.lg,
borderWidth: 1,
borderColor: theme.colors.border,
},
title: {
color: theme.colors.text,
fontFamily: theme.fonts.bold,
fontSize: 18,
},
}));
}

Custom Themes & Font Customization

Pass custom ThemeInput definitions to ThemeProvider to change colors, fonts, spacing, or border radii:

App.tsx
import { ThemeProvider, type ThemeInput } from '@masumdev/rn-ui';
const customLight: ThemeInput = {
colors: {
primary: '#06B6D4',
background: '#F6FBFC',
surface: '#FFFFFF',
text: '#06202A',
border: '#B8D4DD',
},
fonts: {
regular: 'OutfitRegular',
medium: 'OutfitMedium',
bold: 'OutfitBold',
},
};
const customDark: ThemeInput = {
colors: {
primary: '#67E8F9',
background: '#06141B',
surface: '#0B202A',
text: '#F2FBFD',
border: '#2A5260',
},
};
export default function App() {
return (
<ThemeProvider themes={{ light: customLight, dark: customDark }}>
<RootNavigation />
</ThemeProvider>
);
}