# Theming

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

**BNA UI** — a React Native / Expo component library.
These components render through `react-native`, not the DOM: there are no HTML
elements, no Tailwind classes and no Radix primitives. Source is copied into your
project and imported through `@/components/ui/*`, `@/components/charts/*`,
`@/hooks/*` and `@/theme/*`. Colours come from the `useColor` hook rather than
hardcoded hex; sizing tokens (`HEIGHT`, `FONT_SIZE`, `BORDER_RADIUS`, `CORNERS`)
come from `@/theme/globals`.

- Docs: https://ui.ahmedbna.com/docs/theming
- Markdown: https://ui.ahmedbna.com/docs/theming.md

---

## 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

```typescript
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

```typescript
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

```typescript
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

```typescript
// 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

```typescript
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

```typescript
const Button = ({ children, variant = 'primary' }: ButtonProps) => {
  const color = useColor(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

```typescript
const Card = ({ children }: { children: React.ReactNode }) => {
  const color = useColor('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:

```typescript
const lightColors = {
  // ... existing colors
  success: '#34C759',
  successForeground: '#FFFFFF',
};

const darkColors = {
  // ... existing colors
  success: '#30D158',
  successForeground: '#FFFFFF',
};
```

2. Update the ColorKeys type:

```typescript
export type ColorKeys = keyof typeof lightColors;
```

### Modifying Global Constants

Update the global constants to match your design system:

```typescript
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:

```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.
