# Related RN Component Library

## Introduction

Internal React Native component library designed to streamline development across all company mobile applications. The published package is kept separate from its Expo application so each consuming app owns the exact Expo and native-module versions required by its SDK.

## Table of Contents

- [Installation](#installation)
- [Expo compatibility](#expo-compatibility)
- [Development](#development)
- [Components](#components)
- [Theming](#theming)

## Installation

### Prerequisites

- Expo SDK 56 or 57
- React Native 0.85 or 0.86
- React 19.2.3
- Node.js 22.13 or newer for the Expo SDK 57 example app

### Setup

```bash
npm install related-ui-components
```

Install the package's native peers in the consuming Expo application with `npx expo install` so Expo selects the versions compatible with that application's SDK:

```bash
npx expo install \
  @expo/vector-icons \
  @react-native-community/slider \
  @react-native-picker/picker \
  @shopify/react-native-skia \
  expo-checkbox \
  expo-clipboard \
  expo-image \
  expo-linear-gradient \
  react-native-gesture-handler \
  react-native-keyboard-controller \
  react-native-reanimated \
  react-native-safe-area-context \
  react-native-svg \
  react-native-worklets
```

Install the remaining JavaScript peers with the application's package manager if they are not already present. Do not force or duplicate native dependencies inside the library.

## Expo compatibility

The package declares Expo and native runtime packages as peer dependencies. `expo` intentionally uses the `*` peer range, following Expo's library guidance, so the application provides exactly one Expo runtime. API compatibility is constrained by the remaining peer ranges.

| Expo SDK | React Native | React | Status |
|----------|--------------|-------|--------|
| 57 | 0.86 | 19.2.3 | Validated by the example app |
| 56 | 0.85 | 19.2.3 | Accepted by the compatibility ranges |

When adding support for another Expo SDK, update the example app with `npx expo install --fix`, run Expo Doctor, and widen peer ranges only after the library builds and the example runs successfully.

## Development

The repository follows a library-plus-example structure:

```text
src/       published TypeScript library source
lib/       generated package output (ignored by Git)
example/   Expo SDK 57 workspace consuming the package through file:..
```

Install and verify the library:

```bash
npm install
npm run typecheck
npm run build
```

The library and example use one npm workspace installation so native modules are never duplicated. Install and run the Expo 57 example from the repository root:

```bash
npm install
npm run doctor
npm run example:android
```

From the repository root, `npm run example`, `npm run example:android`, `npm run example:ios`, and `npm run example:web` forward to the example application.

## Components

Our component library includes a comprehensive set of pre-built UI components designed for React Native applications. Each component is fully documented with examples, props, and customization options.

| Component | Description |
|-----------|-------------|
| [Badges](./src/components/Badges/README.md) | Reward badges |
| [Banner](./src/components/Banner/README.md) | Advertisement banner with multiple themes |
| [BrandIcon](./src/components/BrandIcon/README.md) | Display brand-specific icons with consistent styling. |
| [Card](./src/components/Card/templates/README.md) | Container component for grouping related content with multiple themes. |
| [CloseIcon](./src/components/CloseIcon/README.md) | Standard close button for modals, popups, and other dismissible elements. |
| [Filters](./src/components/Filters/README.md) | Interactive filtering components for data lists and collections. |
| [Input](./src/components/Input/README.md) | Text input components with validation and styling options. |
| [LockOverlay](./src/components/LockOverlay/README.md) | Overlay component to indicate locked content or functionality. |
| [Popup](./src/components/Popup/README.md) | Modal dialog components for alerts, confirmations, and user interactions. |
| [ProgressBar](./src/components/ProgressBar/README.md) | Visual indicators for progress tracking. |
| [RedemptionOption](./src/components/RedemptionOption/README.md) | Components for displaying and selecting redemption options. |
| [ScratchCard](./src/components/ScratchCard/README.md) | Interactive scratch card component for revealing hidden content. |
| [UnlockRewards](./src/components/UnlockRewards/README.md) | Components for displaying and interacting with reward unlocking functionality. |
| [Wheel](./src/components/Wheel/README.md) | Spin the wheel component |

## Theming

Our component library supports a flexible theming system through the `ThemeProvider`. The system automatically detects and applies the user's system color preference (light or dark mode) while allowing for custom theme overrides.

### Theme Structure

Themes are defined using the `ThemeType` interface which includes colors for:

- Core UI elements (background, surface, primary, secondary, etc.)
- Text and icons
- Borders and dividers
- UI states
- Form-specific elements

### Using the Theme Provider

Wrap your application with the `ThemeProvider` component:

```tsx
import { ThemeProvider } from '@related/ui-components';

export default function App() {
  return (
    <ThemeProvider>
      {/* Your application */}
    </ThemeProvider>
  );
}
```

### Customizing Themes

You can customize the light and dark themes by providing `customLightTheme` and/or `customDarkTheme` props:

```tsx
import { ThemeProvider, ThemeType } from '@related/ui-components';

// Create custom theme overrides
const customLightTheme: Partial<ThemeType> = {
  primary: '#0066CC',
  secondary: '#FF6B00',
  // Override any other properties as needed
};

const customDarkTheme: Partial<ThemeType> = {
  primary: '#4D94FF',
  secondary: '#FF9E4D',
  // Override any other properties as needed
};

export default function App() {
  return (
    <ThemeProvider 
      customLightTheme={customLightTheme}
      customDarkTheme={customDarkTheme}
    >
      {/* Your application */}
    </ThemeProvider>
  );
}
```

### Accessing Theme in Components

Use the `useTheme` hook to access the current theme within your components:

```tsx
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { useTheme } from '@related/ui-components';

const MyComponent = () => {
  const theme = useTheme();
  
  return (
    <View style={[styles.container, { backgroundColor: theme.background }]}>
      <Text style={{ color: theme.text }}>
        Themed Component
      </Text>
      <View style={[styles.card, { 
        backgroundColor: theme.surface,
        borderColor: theme.border 
      }]}>
        <Text style={{ color: theme.text }}>
          This card uses theme colors
        </Text>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 16,
  },
  card: {
    borderWidth: 1,
    borderRadius: 8,
    padding: 16,
    marginTop: 8,
  },
});

export default MyComponent;
```

### System Theme Detection

The `ThemeProvider` automatically detects the user's system color scheme preference using React Native's `useColorScheme` hook and applies the appropriate theme. No additional configuration is required for this behavior.

### Available Theme Properties

The full list of available theme properties can be found in the `ThemeType` interface:

```ts
interface ThemeType {
  // Core
  background: string;    // Main screen background
  surface: string;       // Background for components like cards, dialogs, sheets
  primary: string;       // Main accent color for interactive elements
  secondary: string;     // Secondary accent color
  error: string;         // Error states, destructive actions
  success: string;       // Success states
  warning: string;       // Warning states
  info: string;          // Informational states

  // Text & Icons
  text: string;          // Default text color
  onPrimary: string;     // Text/icon color on primary background
  onSecondary: string;   // Text/icon color on secondary background
  onError: string;       // Text/icon color on error background
  onBackground: string;  // Text/icon color explicitly for background
  onSurface: string;     // Text/icon color explicitly for surface

  // Borders & Dividers
  border: string;        // Borders for inputs, cards, etc.
  divider: string;       // Separators, lines

  // UI States
  disabled: string;      // Disabled state elements

  // Form Specific
  inputBackground: string;    // Background of text inputs
  inputText: string;          // Color of text entered into inputs
  labelText: string;          // Color of labels for inputs
  placeholderText: string;    // Color of placeholder text in inputs
  helper: string;             // Helper text below inputs
}
```
