ThemeProvider
Root provider component that manages the theme context throughout your application, handles font loading, and integrates with React Native Paper's Material Design 3 theming system.
Quick Example
import React from "react";
import { ThemeProvider, DEFAULT_COLORS } from "@ovok/native";
export const App = () => {
const themeConfig = {
colors: {
...DEFAULT_COLORS,
primary: "#0066CC",
secondary: "#FF6B35",
},
dark: false,
spacingMultiplier: 4,
borderRadiusMultiplier: 4,
};
return (
<ThemeProvider theme={themeConfig}>{/* Your app content */}</ThemeProvider>
);
};
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
children | React.ReactNode | ✓ | - | App components to wrap with theme context |
theme | ThemeProviderProps["theme"] | ✓ | - | Theme configuration object |
Theme Configuration Object
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
colors | Partial<MD3Theme["colors"]> & typeof DEFAULT_COLORS | ✓ | - | Color palette configuration |
dark | boolean | ✓ | - | Enable dark mode |
spacingMultiplier | number | ✓ | - | Base spacing unit multiplier |
borderRadiusMultiplier | number | ✓ | - | Base border radius multiplier |
Component Behavior
The ThemeProvider component manages several critical aspects of your app's theming:
- Font Loading: Loads DM Sans font family variants and shows loading state until ready
- Theme Generation: Converts configuration into a complete Material Design 3 theme
- Context Provision: Makes theme available to all child components via React context
- Paper Integration: Wraps app with React Native Paper's PaperProvider
- Device Integration: Includes DeviceListProvider for Bluetooth device management
Font Loading Process
The component loads these DM Sans font variants:
- DMSans_400Regular
- DMSans_400Regular_Italic
- DMSans_500Medium
- DMSans_500Medium_Italic
- DMSans_700Bold
- DMSans_700Bold_Italic
Returns null until all fonts are loaded to prevent FOUC (Flash of Unstyled Content).
Theme Configuration Examples
Basic Configuration
import { ThemeProvider, DEFAULT_COLORS } from "@ovok/mobile";
const basicTheme = {
colors: DEFAULT_COLORS,
dark: false,
spacingMultiplier: 4,
borderRadiusMultiplier: 4,
};
export const App = () => (
<ThemeProvider theme={basicTheme}>
<YourApp />
</ThemeProvider>
);
Custom Brand Colors
const brandTheme = {
colors: {
...DEFAULT_COLORS,
primary: "#1E40AF", // Custom blue
secondary: "#7C3AED", // Custom purple
tertiary: "#059669", // Custom green
success: "#10B981", // Custom success green
error: "#EF4444", // Custom error red
warning: "#F59E0B", // Custom warning amber
},
dark: false,
spacingMultiplier: 4,
borderRadiusMultiplier: 6,
};
Healthcare-Specific Colors
const healthcareTheme = {
colors: {
...DEFAULT_COLORS,
primary: "#0EA5E9", // Medical blue
secondary: "#8B5CF6", // Healthcare purple
success: "#22C55E", // Healthy green
error: "#EF4444", // Critical red
warning: "#F97316", // Caution orange
// Custom healthcare color extensions
blue: {
...DEFAULT_COLORS.blue,
500: "#0EA5E9", // Medical devices
600: "#0284C7", // Primary actions
},
green: {
...DEFAULT_COLORS.green,
500: "#22C55E", // Normal vitals
600: "#16A34A", // Excellent health
},
},
dark: false,
spacingMultiplier: 4,
borderRadiusMultiplier: 4,
};
Dark Mode Configuration
const darkTheme = {
colors: {
...DEFAULT_COLORS,
// Dark mode automatically handled by Material Design 3
// Custom colors still apply
primary: "#60A5FA", // Lighter blue for dark backgrounds
secondary: "#A78BFA", // Lighter purple for dark backgrounds
},
dark: true,
spacingMultiplier: 4,
borderRadiusMultiplier: 4,
};
Responsive Design Configuration
// For tablet/larger screens
const tabletTheme = {
colors: DEFAULT_COLORS,
dark: false,
spacingMultiplier: 6, // Larger spacing for tablets
borderRadiusMultiplier: 8, // More pronounced borders
};
// For compact/mobile screens
const mobileTheme = {
colors: DEFAULT_COLORS,
dark: false,
spacingMultiplier: 3, // Tighter spacing for mobile
borderRadiusMultiplier: 2, // Subtle borders for small screens
};
Dynamic Theme Switching
Runtime Theme Updates
import React from "react";
import { ThemeProvider, DEFAULT_COLORS } from "@ovok/mobile";
export const App = () => {
const [isDark, setIsDark] = React.useState(false);
const [primaryColor, setPrimaryColor] = React.useState("#0066CC");
const currentTheme = React.useMemo(
() => ({
colors: {
...DEFAULT_COLORS,
primary: primaryColor,
},
dark: isDark,
spacingMultiplier: 4,
borderRadiusMultiplier: 4,
}),
[isDark, primaryColor],
);
return (
<ThemeProvider theme={currentTheme}>
<YourAppWithThemeControls
onToggleDark={() => setIsDark(!isDark)}
onColorChange={setPrimaryColor}
/>
</ThemeProvider>
);
};
System Theme Detection
import { useColorScheme } from "react-native";
import { ThemeProvider, DEFAULT_COLORS } from "@ovok/mobile";
export const App = () => {
const systemColorScheme = useColorScheme();
const themeConfig = {
colors: DEFAULT_COLORS,
dark: systemColorScheme === "dark",
spacingMultiplier: 4,
borderRadiusMultiplier: 4,
};
return (
<ThemeProvider theme={themeConfig}>
<YourApp />
</ThemeProvider>
);
};
Performance Considerations
Theme Memoization
The ThemeProvider automatically memoizes theme generation, but you should memoize your theme configuration:
export const App = () => {
const themeConfig = React.useMemo(
() => ({
colors: {
...DEFAULT_COLORS,
primary: "#0066CC",
},
dark: false,
spacingMultiplier: 4,
borderRadiusMultiplier: 4,
}),
[],
); // Dependencies array for dynamic values
return (
<ThemeProvider theme={themeConfig}>
<YourApp />
</ThemeProvider>
);
};
Font Loading Optimization
The component handles font loading efficiently:
- Shows loading state until fonts are ready
- Prevents component tree from rendering with fallback fonts
- Uses Expo's optimized font loading system
Error Handling
Font Loading Failures
import { ThemeProvider, DEFAULT_COLORS } from "@ovok/mobile";
export const App = () => {
const [fontError, setFontError] = React.useState(false);
React.useEffect(() => {
// Monitor font loading timeout
const timeout = setTimeout(() => {
setFontError(true);
}, 10000); // 10 second timeout
return () => clearTimeout(timeout);
}, []);
if (fontError) {
return <FallbackApp />; // Your fallback component
}
return (
<ThemeProvider theme={themeConfig}>
<YourApp />
</ThemeProvider>
);
};
Integration with Other Providers
Provider Stack Order
import { ThemeProvider } from "@ovok/mobile";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { SafeAreaProvider } from "react-native-safe-area-context";
const queryClient = new QueryClient();
export const App = () => (
<QueryClientProvider client={queryClient}>
<SafeAreaProvider>
<ThemeProvider theme={themeConfig}>
<YourApp />
</ThemeProvider>
</SafeAreaProvider>
</QueryClientProvider>
);
Accessibility Features
- High Contrast: Material Design 3 automatically provides accessible color contrasts
- Font Scaling: DM Sans fonts support system font scaling preferences
- Dark Mode: Proper dark mode implementation for accessibility needs
- Color Semantics: Semantic color system supports screen readers and accessibility tools
Related Components
- useAppTheme - Hook for accessing theme values in components
- Colors - Color system and palette definitions