BNA

BNA UI
22

BNA UI theming system for your React Native UI components using TypeScript constants and color utilities.

Overview

Your theming system provides a structured approach to managing colors, dimensions, and styling across your React Native application. The theme is built around light and dark color schemes with support for semantic color naming.

Color System

Light Theme

const lightColors = {
  // Base colors
  background: '#FFFFFF',
  foreground: '#000000',
 
  // Card colors
  card: '#F2F2F7',
  cardForeground: '#000000',
 
  // Primary colors
  primary: '#18181b',
  primaryForeground: '#FFFFFF',
 
  // Secondary colors
  secondary: '#F2F2F7',
  secondaryForeground: '#18181b',
 
  // System colors
  destructive: '#ef4444',
  destructiveForeground: '#FFFFFF',
 
  // Interactive colors
  blue: '#007AFF',
  green: '#34C759',
  red: '#FF3B30',
  orange: '#FF9500',
  yellow: '#FFCC00',
  pink: '#FF2D92',
  purple: '#AF52DE',
  teal: '#5AC8FA',
  indigo: '#5856D6',
};

Dark Theme

const darkColors = {
  // Base colors
  background: '#000000',
  foreground: '#FFFFFF',
 
  // Card colors
  card: '#1C1C1E',
  cardForeground: '#FFFFFF',
 
  // Primary colors
  primary: '#e4e4e7',
  primaryForeground: '#18181b',
 
  // Secondary colors
  secondary: '#1C1C1E',
  secondaryForeground: '#FFFFFF',
 
  // System colors
  destructive: '#dc2626',
  destructiveForeground: '#FFFFFF',
 
  // Interactive colors (adapted for dark mode)
  blue: '#0A84FF',
  green: '#30D158',
  red: '#FF453A',
  orange: '#FF9F0A',
  yellow: '#FFD60A',
  pink: '#FF375F',
  purple: '#BF5AF2',
  teal: '#64D2FF',
  indigo: '#5E5CE6',
};

Global Constants

Dimensions

export const HEIGHT = 48; // Standard component height
export const FONT_SIZE = 17; // Base font size
export const BORDER_RADIUS = 26; // Standard border radius
export const CORNERS = 999; // Fully rounded corners

Usage Examples

// Using in StyleSheet
const styles = StyleSheet.create({
  button: {
    height: HEIGHT,
    borderRadius: BORDER_RADIUS,
    backgroundColor: Colors.light.primary,
  },
 
  roundedButton: {
    height: HEIGHT,
    borderRadius: CORNERS,
    backgroundColor: Colors.light.blue,
  },
 
  text: {
    fontSize: FONT_SIZE,
    color: Colors.light.foreground,
  },
});

Color Conventions

Semantic Naming

The color system follows a semantic naming convention where each color has a corresponding foreground color:

  • background / foreground - Main app background and text
  • card / cardForeground - Card backgrounds and text
  • primary / primaryForeground - Primary actions and buttons
  • secondary / secondaryForeground - Secondary actions
  • destructive / destructiveForeground - Error states and dangerous actions

iOS System Colors

The theme includes iOS system colors that automatically adapt to the user's appearance settings:

  • blue - Default buttons, links, selected tabs
  • green - Success states, completed tasks
  • red - Delete buttons, error states
  • orange - Warning states
  • yellow - Highlights and accents
  • pink - Creative accents
  • purple - Feature highlights
  • teal - Communication features
  • indigo - System features

Theme Context

Setting Up Theme Provider

import { Colors } from './colors';
import { useColorScheme } from 'react-native';
 
export const ThemeProvider = ({ children }: { children: React.ReactNode }) => {
  const colorScheme = useColorScheme();
 
  // Create custom themes that use your Colors
  const customLightTheme = {
    ...DefaultTheme,
    colors: {
      ...DefaultTheme.colors,
      primary: Colors.light.primary,
      background: Colors.light.background,
      card: Colors.light.card,
      text: Colors.light.text,
      border: Colors.light.border,
      notification: Colors.light.red,
    },
  };
 
  const customDarkTheme = {
    ...DarkTheme,
    colors: {
      ...DarkTheme.colors,
      primary: Colors.dark.primary,
      background: Colors.dark.background,
      card: Colors.dark.card,
      text: Colors.dark.text,
      border: Colors.dark.border,
      notification: Colors.dark.red,
    },
  };
 
  return (
    <ThemeContext.Provider
      value={colorScheme === 'dark' ? customDarkTheme : customLightTheme}
    >
      {children}
    </ThemeContext.Provider>
  );
};

Using Theme in Components

const Button = ({ children, variant = 'primary' }: ButtonProps) => {
  const color = useThemeColor({}, variant);
 
  const buttonStyle = {
    height: HEIGHT,
    borderRadius: BORDER_RADIUS,
    backgroundColor: color,
    justifyContent: 'center' as const,
    alignItems: 'center' as const,
  };
 
  const textStyle = {
    color: colors[`${variant}Foreground`],
    fontSize: FONT_SIZE,
    fontWeight: '600' as const,
  };
 
  return (
    <Pressable style={buttonStyle}>
      <Text style={textStyle}>{children}</Text>
    </Pressable>
  );
};

Component Examples

Card Component

const Card = ({ children }: { children: React.ReactNode }) => {
  const color = useThemeColor({}, 'card');
 
  return (
    <View
      style={{
        backgroundColor: color,
        borderRadius: BORDER_RADIUS,
        padding: 16,
        marginVertical: 8,
      }}
    >
      {children}
    </View>
  );
};

Customization

Adding New Colors

To add new colors to your theme:

  1. Add the color to both light and dark color objects:
const lightColors = {
  // ... existing colors
  success: '#34C759',
  successForeground: '#FFFFFF',
};
 
const darkColors = {
  // ... existing colors
  success: '#30D158',
  successForeground: '#FFFFFF',
};
  1. Update the ColorKeys type:
export type ColorKeys = keyof typeof lightColors;

Modifying Global Constants

Update the global constants to match your design system:

export const HEIGHT = 44; // Smaller height
export const FONT_SIZE = 16; // Smaller font
export const BORDER_RADIUS = 12; // Less rounded
export const CORNERS = 22; // Moderately rounded

TypeScript Support

The theme system is fully typed with TypeScript:

// Color keys are typed
export type ColorKeys = keyof typeof lightColors;
 
// Theme context is typed
export interface ThemeContextType {
  colors: typeof lightColors;
  isDark: boolean;
}
 
// Component props can use color keys
interface ButtonProps {
  variant?: ColorKeys;
  children: React.ReactNode;
}

Best Practices

  1. Use semantic colors - Prefer primary over specific colors like blue
  2. Consistent spacing - Use the global constants for consistent dimensions
  3. Automatic dark mode - Always provide both light and dark variants
  4. Accessibility - Ensure sufficient contrast between foreground and background colors
  5. Platform consistency - Use iOS system colors where appropriate

This theming system provides a solid foundation for building consistent, accessible, and platform-appropriate React Native applications.