Skip to content

HashaamKhan19/react-native-multitheme

Repository files navigation

React Native Multi-Theme System

A comprehensive theming system for React Native applications that supports multiple color themes with light/dark mode variants, built with NativeWind & Zustand.

🎨 Features

  • Distinct Color Themes: Default Abyss, Fiery Ember, Malignant Moss, Crimson Bloom, Golden Hour, and Abyssal Depths
  • Light/Dark Mode Support: Each theme has both light and dark variants
  • Persistent Storage: Theme preferences are saved across app sessions
  • Semantic Color System: Colors are organized by semantic meaning (background, text, stroke, etc.)
  • React Navigation Integration: Automatic theme application to navigation components
  • Type-Safe: Full TypeScript support with proper type definitions
  • Cross-Platform: Works on iOS, Android, and Web

πŸ—οΈ Architecture Overview

The theming system follows a layered architecture:

User Interaction (Components)
          ↓
State Management (Zustand Store)
          ↓
Theme Provider (CSS Variables)
          ↓
Color System (Semantic Tokens)
          ↓
Primitive Colors (Base Palette)

πŸ“ File Structure & Responsibilities

Core Files

utils/colors.ts

Purpose: The foundation of the theming system containing all color definitions.

Structure:

  • Primitives: Base color palettes (AbyssalDepths, CrimsonBloom, EmberGlow, etc.) with scales from 0-900
  • Semantic Mappings: Maps primitive colors to semantic meanings (background-void, text-rich, brand-primary-base)
  • Theme Definitions: Combines semantic mappings for each theme in light/dark variants

Key Features:

  • Common semantic colors for light/dark modes
  • buildBrand() function to create consistent brand color mappings
  • 6 theme variants with primary/secondary color combinations

providers/theme-provider.tsx

Purpose: React context provider that applies the current theme using CSS variables.

Functionality:

  • Reads current theme and color scheme from Zustand store
  • Converts theme object to CSS variables using NativeWind's vars() function
  • Wraps the app with theme-aware styling
  • Integrates with React Navigation's theme provider

store/useThemeStore.ts

Purpose: Zustand store for managing theme state.

State:

  • theme: Current theme name (default, ember, moss, etc.)
  • colorScheme: Current mode (light/dark)
  • Actions for updating theme and color scheme

Hooks

hooks/useSelectedTheme.ts

Purpose: Main hook for theme management with persistence.

Features:

  • Loads saved theme preferences on app start
  • Persists changes to SecureStore (mobile) or localStorage (web)
  • Synchronizes with NativeWind's color scheme
  • Provides convenient setters for theme and mode changes
  • Cross-platform storage handling

hooks/useThemeColors.ts

Purpose: Simple hook to access current theme's color values.

Returns: The complete color object for the current theme and mode combination.

hooks/useThemeConfig.ts

Purpose: Generates React Navigation theme configuration.

Functionality:

  • Maps semantic colors to React Navigation's expected color structure
  • Dynamically updates based on current theme and mode
  • Provides proper navigation theming

Components

components/ThemeSelector.tsx

Purpose: UI component for selecting color themes.

Features:

  • Displays color swatches for each available theme
  • Shows current selection with border highlighting
  • Supports accessibility labels and states
  • Callback support for theme selection events

components/ThemeModeToggle.tsx

Purpose: Radio button component for light/dark mode selection.

Features:

  • Custom radio button design
  • Accessibility support
  • Visual feedback for current selection

Utility Files

utils/themes.ts

Purpose: Configuration for theme selector UI.

Contains:

  • Theme metadata (names, labels, CSS classes)
  • Used by ThemeSelector component to render options

utils/cn.ts

Purpose: Utility for merging Tailwind classes.

Functionality:

  • Combines clsx and tailwind-merge
  • Handles conditional classes and deduplication

Configuration

tailwind.config.js

Purpose: Tailwind CSS configuration that integrates the color system.

Features:

  • Dynamically generates color classes from semantic tokens
  • Maps color keys to CSS variables
  • Includes primitive colors for direct access
  • Configured for React Native with NativeWind preset

πŸ”„ Theming Flow

1. Initialization

App Start β†’ useSelectedTheme loads saved preferences β†’ Store updated β†’ Provider applies CSS vars

2. Theme Change

User selects theme β†’ ThemeSelector calls setSelectedTheme β†’ Store updated β†’ Provider re-renders with new CSS vars

3. Mode Change

User toggles mode β†’ ThemeModeToggle calls setSelectedScheme β†’ Store + NativeWind updated β†’ Provider re-renders

4. Color Access

Component needs colors β†’ useThemeColors reads from store β†’ Returns current theme's color object

🎯 Usage Examples

Basic Component Styling

// Using semantic classes
<View className="bg-surface-primary border-stroke-subtle">
  <Text className="text-text-void">Hello World</Text>
</View>

Direct Color Access

const themeColors = useThemeColors();

<View style={{ backgroundColor: themeColors["brand-primary-base"] }}>
  <Text style={{ color: themeColors["text-void"] }}>Styled Text</Text>
</View>;

Theme Selection

const { selectedTheme, setSelectedTheme } = useSelectedTheme();

// Change theme
await setSelectedTheme("crimson");

🎨 Color System

Semantic Categories

Background Colors: background-void to background-pure

  • Used for different levels of background prominence

Text Colors: text-void to text-pure

  • Hierarchical text emphasis levels

Stroke Colors: stroke-void to stroke-pure

  • Border and divider colors

Brand Colors: brand-primary-* and brand-secondary-*

  • Theme-specific accent colors

Surface Colors: surface-primary and surface-secondary

  • Card and container backgrounds

Static Colors: static-white and static-black

  • Colors that flips between modes

Available Themes

  1. Default Abyss - Navy blue primary, orange secondary
  2. Fiery Ember - Orange primary, gray secondary
  3. Abyssal Depths - Deep blue primary, gray secondary
  4. Malignant Moss - Green primary, gray secondary
  5. Crimson Bloom - Red primary, gray secondary
  6. Golden Hour - Yellow primary, gray secondary

πŸ”§ Adding New Themes

  1. Add primitive colors in utils/colors.ts:
const primitives = {
  // ... existing colors
  NewColorName: {
    0: "#ffffff",
    50: "#f0f0f0",
    // ... define 100-900
  },
};
  1. Add theme definition:
export const themes = {
  // ... existing themes
  newtheme: {
    light: {
      ...commonSemanticColorsLight,
      ...buildBrand(primitives.NewColorName, primitives.ObsidianWhisper),
    },
    dark: {
      ...commonSemanticColorsDark,
      ...buildBrand(primitives.NewColorName, primitives.ObsidianWhisper),
    },
  },
};
  1. Update theme selector in utils/themes.ts:
export const themes = [
  // ... existing themes
  {
    name: "newtheme",
    label: "New Theme",
    colorClass: "bg-NewColorName-500",
    borderColorClass: "border-NewColorName-500",
  },
];
  1. Update TypeScript types in providers/theme-provider.tsx if needed.

πŸ’Ύ Persistence

Theme preferences are automatically saved and restored:

  • Mobile: Uses Expo SecureStore for secure storage
  • Web: Uses localStorage for browser storage
  • Loading: Preferences load on app initialization
  • Fallbacks: Graceful handling of missing or invalid stored values

β™Ώ Accessibility

The theming system includes comprehensive accessibility support:

  • Proper ARIA labels and roles
  • Keyboard navigation support
  • Screen reader compatibility
  • High contrast considerations in color selection
  • Semantic HTML structure

πŸ”§ Integration Points

React Navigation

Themes automatically apply to:

  • Navigation headers
  • Tab bars
  • Background colors
  • Text colors
  • Border colors

NativeWind

  • CSS variables for dynamic theming
  • Class-based styling with semantic names
  • Responsive design support
  • Dark mode integration

This theming system provides a robust, scalable foundation for building visually cohesive React Native applications with multiple theme options and accessibility support.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages