# src/components/

74 flat Rtk*.tsx component files — the entire UI surface of the library.

## STRUCTURE

Flat directory. No subdirs, no barrels, no index.ts. Every component is a single `.tsx` file with a default export. All exports registered in `src/index.tsx`.

## COMPONENT PATTERN

Every component follows this skeleton:

```tsx
import React, { useContext } from 'react';
import { StyleSheet, View } from 'react-native';
import { RtkUIContext } from '../lib/context-provider/ui-context';
import { useRealtimeKitSelector } from '@cloudflare/realtimekit-react-native';
import { useLanguage } from '../lib/lang';

export default function ({
  someProp,
  style,
}: {
  someProp?: string;
  style?: object;
}) {
  const { storeStates, setStates } = useContext(RtkUIContext);
  const { colors } = storeStates.designSystem;
  const t = useLanguage();
  const self = useRealtimeKitSelector((m) => m.self);

  const styles = StyleSheet.create({
    container: {
      backgroundColor: colors.background[900],
    },
  });

  return <View style={styles.container}>...</View>;
}
```

Key hooks used across components:
- `useContext(RtkUIContext)` — global state + design tokens (virtually all components)
- `useRealtimeKitSelector()` — meeting/participant data from SDK
- `useLanguage()` — i18n translation function `t(key)`
- `getIconPack()` or `iconPack` from render defaults — icon rendering

## WHERE TO LOOK

| Task | Files | Notes |
|------|-------|-------|
| Top-level meeting orchestrator | `RtkMeeting.tsx` | Lifecycle, config, render entry |
| Video grids | `RtkGrid.tsx`, `RtkSimpleGrid.tsx`, `RtkSpotlightGrid.tsx`, `RtkMixedGrid.tsx`, `RtkHighligtedGrid.tsx` | Note typo in Highligted |
| Individual participant | `RtkParticipantTile.tsx`, `RtkParticipant.tsx`, `RtkParticipants.tsx` | Tile < Participant < List |
| Controls (mic/cam/screen) | `RtkMicToggle.tsx`, `RtkCameraToggle.tsx`, `RtkScreenShareToggle.tsx` | All toggle buttons |
| Chat | `RtkChat.tsx`, `RtkChatToggle.tsx`, `RtkTextMessage.tsx`, `RtkImageMessage.tsx`, `RtkFileMessage.tsx` | Main chat is complex (~280 lines) |
| Settings/sidebar | `RtkSettings.tsx`, `RtkSidebar.tsx`, `RtkSettingsAudio.tsx`, `RtkSettingsVideo.tsx` | |
| Polls | `RtkPoll.tsx`, `RtkPollForm.tsx`, `RtkPolls.tsx`, `RtkPollsToggle.tsx` | |
| Meeting lifecycle screens | `RtkSetupScreen.tsx`, `RtkWaitingScreen.tsx`, `RtkEndedScreen.tsx`, `RtkIdleScreen.tsx` | |
| Livestream | `RtkLiveStreamPlayer.tsx`, `RtkLiveStreamToggle.tsx`, `RtkLiveStreamIndicator.tsx`, `RtkLiveStreamStageToggle.tsx`, `RtkLiveStreamViewerCount.tsx` | |
| Shared primitives | `RtkText.tsx` (52 imports), `RtkButton.tsx`, `RtkIcon.tsx`, `RtkSpinner.tsx`, `RtkTextField.tsx` | RtkText is a critical base |

## CONVENTIONS

- **Anonymous default exports**: `export default function ({ ... })` — no named function, no `React.FC`
- **Inline object types for props** — NOT separate interfaces or type aliases
- **StyleSheet.create() inside function body** — always dynamic, reads `colors` from context
- **No prop destructuring at top level** — props destructured in function signature directly
- **`eslint-disable react-hooks/exhaustive-deps`** appears in ~10 effect hooks with stale closure patterns
- **`eslint-disable react-native/no-inline-styles`** used at file level when inline styles dominate

## ANTI-PATTERNS

- Do NOT add an index.ts barrel here — all exports go through `src/index.tsx`
- Do NOT create subdirectories — keep flat, one file per component
- Do NOT use named exports from component files — always default export
- Do NOT extract styles to separate files — keep inline with `StyleSheet.create()`
- Do NOT add `RtkHighlightedGrid.tsx` (correct spelling) — existing file is `RtkHighligtedGrid.tsx` (typo preserved)
- Do NOT forget to register new components in `src/index.tsx` AND `src/lib/render/mapping.ts` (if config-driven)