Skip to main content

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

PropTypeRequiredDefaultDescription
childrenReact.ReactNode-App components to wrap with theme context
themeThemeProviderProps["theme"]-Theme configuration object

Theme Configuration Object

PropertyTypeRequiredDefaultDescription
colorsPartial<MD3Theme["colors"]> & typeof DEFAULT_COLORS-Color palette configuration
darkboolean-Enable dark mode
spacingMultipliernumber-Base spacing unit multiplier
borderRadiusMultipliernumber-Base border radius multiplier

Component Behavior

The ThemeProvider component manages several critical aspects of your app's theming:

  1. Font Loading: Loads DM Sans font family variants and shows loading state until ready
  2. Theme Generation: Converts configuration into a complete Material Design 3 theme
  3. Context Provision: Makes theme available to all child components via React context
  4. Paper Integration: Wraps app with React Native Paper's PaperProvider
  5. 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
  • useAppTheme - Hook for accessing theme values in components
  • Colors - Color system and palette definitions