# @retray-dev/ui-kit — Composition Examples

This file contains full-code examples of complete app screens built by composing multiple UI kit components. These are working examples from the `example/` app, demonstrating real-world component patterns, state management, and navigation.

**For AI agents:** Use these examples as reference patterns when building screens with this UI kit. They show proper imports, state management, navigation, haptics integration, and component composition.

---

## Example 1: Finance Dashboard

**Use case:** Personal finance app home screen with budget tracking, transaction list, and expense breakdown.

**Components used:** MonthPicker, CurrencyDisplay, Progress, CategoryStrip, ListItem, DetailRow, Card, Button, Text, Icon

**Features:**
- Month selection with locale support
- Hero balance display with auto-scaling
- Budget progress tracking with visual indicator
- Category filtering with horizontal scrollable tabs
- Transaction list with custom icons and color-coded amounts
- Expense breakdown with separator hierarchy
- Export action with success toast

### State Setup

```tsx
const [financeMonth, setFinanceMonth] = useState({ month: 5, year: 2026 })
const [financeCategory, setFinanceCategory] = useState('all')

const FINANCE_CATEGORIES = [
  { label: 'Todo', value: 'all', icon: 'layers' },
  { label: 'Comida', value: 'food', icon: 'coffee' },
  { label: 'Transporte', value: 'transport', icon: 'truck' },
  { label: 'Salud', value: 'health', icon: 'heart' },
]
```

### Implementation

```tsx
import { View, ScrollView, StyleSheet } from 'react-native'
import {
  Card,
  CardContent,
  MonthPicker,
  CurrencyDisplay,
  Progress,
  CategoryStrip,
  ListItem,
  DetailRow,
  Separator,
  Button,
  Text,
  useTheme,
  useToast,
} from '@retray-dev/ui-kit'

function FinanceDashboard() {
  const { colors } = useTheme()
  const { toast } = useToast()

  return (
    <View style={[styles.fullScreen, { backgroundColor: colors.background }]}>
      {/* Header */}
      <View style={[styles.screenHeader, { backgroundColor: colors.card, borderBottomColor: colors.border }]}>
        <Button
          label="Volver"
          variant="text"
          size="sm"
          iconName="arrow-left"
          onPress={() => {/* navigate back */}}
        />
        <Text variant="title-sm">Resumen financiero</Text>
        <View style={{ width: 70 }} />
      </View>

      {/* Content */}
      <ScrollView contentContainerStyle={styles.screenContent}>
        {/* Month Selector */}
        <MonthPicker value={financeMonth} onChange={setFinanceMonth} locale="es" />
        <View style={{ height: 16 }} />

        {/* Balance Card */}
        <Card>
          <CardContent>
            <Text variant="caption" color={colors.foregroundMuted}>Gastos del mes</Text>
            <CurrencyDisplay value={1250000} variant="hero" autoScale />
            <View style={{ height: 8 }} />
            <Progress value={78} variant="destructive" />
            <Text variant="caption-sm" color={colors.foregroundMuted}>
              78% del presupuesto · $1.600.000
            </Text>
          </CardContent>
        </Card>
        <View style={{ height: 12 }} />

        {/* Category Filter */}
        <CategoryStrip
          categories={FINANCE_CATEGORIES}
          value={financeCategory}
          onValueChange={(v) => setFinanceCategory(Array.isArray(v) ? v[0] ?? 'all' : v)}
        />
        <View style={{ height: 16 }} />

        {/* Transaction List */}
        <Text variant="caption" style={{ marginBottom: 8 }}>Movimientos recientes</Text>
        <ListItem
          title="Rappi"
          subtitle="Comida · 12 may"
          leftRender={
            <View style={[styles.txIcon, { backgroundColor: '#fff3f0' }]}>
              <Text>🛵</Text>
            </View>
          }
          rightRender={<Text variant="title-sm" color={colors.destructive}>−$45.000</Text>}
          showSeparator
          onPress={() => {}}
        />
        <ListItem
          title="Metro"
          subtitle="Transporte · 11 may"
          leftRender={
            <View style={[styles.txIcon, { backgroundColor: '#f0f4ff' }]}>
              <Text>🚇</Text>
            </View>
          }
          rightRender={<Text variant="title-sm" color={colors.destructive}>−$5.200</Text>}
          showSeparator
          onPress={() => {}}
        />
        <ListItem
          title="Nómina"
          subtitle="Ingreso · 1 may"
          leftRender={
            <View style={[styles.txIcon, { backgroundColor: '#f0fdf4' }]}>
              <Text>💼</Text>
            </View>
          }
          rightRender={<Text variant="title-sm" color={colors.success}>+$3.500.000</Text>}
          onPress={() => {}}
        />
        <View style={{ height: 16 }} />

        {/* Expense Breakdown */}
        <Text variant="caption" style={{ marginBottom: 8 }}>Desglose</Text>
        <View style={{ gap: 8 }}>
          <DetailRow label="Comida & bebida" value="$380.000" leftIconName="coffee" />
          <DetailRow label="Transporte" value="$95.000" leftIconName="truck" />
          <DetailRow label="Entretenimiento" value="$210.000" leftIconName="music" />
          <DetailRow label="Salud" value="$85.000" leftIconName="heart" />
          <DetailRow label="Otros" value="$480.000" leftIconName="more-horizontal" />
          <Separator />
          <DetailRow label="Total" value="$1.250.000" labelWeight="bold" separator="none" rightIconName="trending-up" />
        </View>
        <View style={{ height: 24 }} />

        {/* Export Action */}
        <Button
          label="Exportar reporte"
          fullWidth
          iconName="download"
          onPress={() => {
            toast({ title: 'Reporte exportado', variant: 'success' })
          }}
        />
        <View style={{ height: 32 }} />
      </ScrollView>
    </View>
  )
}

const styles = StyleSheet.create({
  fullScreen: {
    flex: 1,
  },
  screenHeader: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingHorizontal: 8,
    paddingVertical: 8,
    borderBottomWidth: StyleSheet.hairlineWidth,
  },
  screenContent: {
    padding: 16,
    paddingBottom: 48,
  },
  txIcon: {
    width: 40,
    height: 40,
    borderRadius: 12,
    alignItems: 'center',
    justifyContent: 'center',
  },
})
```

---

## Example 2: Edit Profile

**Use case:** User profile settings editor with avatar, form fields, toggles, and verification status.

**Components used:** Avatar, Badge, Input, Select, Switch, Card, AlertBanner, Button, Text, Separator

**Features:**
- Avatar with online status indicator
- Membership tier badge
- Form fields with prefix icons and proper keyboard types
- Country selection dropdown
- Toggle switches for preferences
- Success banner for verification status
- Save/cancel navigation with toast feedback

### State Setup

```tsx
const [profileName, setProfileName] = useState('Julian Cruz')
const [profileEmail, setProfileEmail] = useState('julian@email.com')
const [switchOn, setSwitchOn] = useState(false)
const [darkMode, setDarkMode] = useState(false)
```

### Implementation

```tsx
import { View, ScrollView, StyleSheet } from 'react-native'
import {
  Avatar,
  Badge,
  Input,
  Select,
  Switch,
  Card,
  CardContent,
  Separator,
  AlertBanner,
  Button,
  Text,
  useTheme,
  useToast,
} from '@retray-dev/ui-kit'

function EditProfile() {
  const { colors } = useTheme()
  const { toast } = useToast()

  return (
    <View style={[styles.fullScreen, { backgroundColor: colors.background }]}>
      {/* Header */}
      <View style={[styles.screenHeader, { backgroundColor: colors.card, borderBottomColor: colors.border }]}>
        <Button
          label="Cancelar"
          variant="text"
          size="sm"
          onPress={() => {/* navigate back */}}
        />
        <Text variant="title-sm">Editar perfil</Text>
        <Button
          label="Guardar"
          variant="text"
          size="sm"
          onPress={() => {
            toast({ title: 'Perfil actualizado', variant: 'success' })
          }}
        />
      </View>

      {/* Content */}
      <ScrollView contentContainerStyle={styles.screenContent} keyboardShouldPersistTaps="handled">
        {/* Avatar Section */}
        <View style={{ alignItems: 'center', marginBottom: 24 }}>
          <Avatar fallbackText={profileName || 'Usuario'} size={80} status="online" />
          <View style={{ height: 12 }} />
          <Badge label="Pro Member" variant="success" iconName="check-circle" />
        </View>

        {/* Form Fields */}
        <Input
          label="Nombre completo"
          value={profileName}
          onChangeText={setProfileName}
          prefixIcon="user"
          placeholder="Tu nombre"
        />
        <View style={{ height: 12 }} />
        <Input
          label="Email"
          value={profileEmail}
          onChangeText={setProfileEmail}
          prefixIcon="mail"
          placeholder="tu@email.com"
          keyboardType="email-address"
          autoCapitalize="none"
        />
        <View style={{ height: 12 }} />
        <Select
          label="País"
          value="CO"
          onValueChange={() => {}}
          options={[
            { label: 'Colombia', value: 'CO' },
            { label: 'México', value: 'MX' },
            { label: 'Argentina', value: 'AR' },
          ]}
        />
        <View style={{ height: 20 }} />

        {/* Preferences Card */}
        <Text variant="caption" style={{ marginBottom: 8 }}>Preferencias</Text>
        <Card>
          <CardContent>
            <View style={{ gap: 12 }}>
              <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
                <Text variant="body-sm">Notificaciones</Text>
                <Switch checked={switchOn} onCheckedChange={setSwitchOn} />
              </View>
              <Separator />
              <View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
                <Text variant="body-sm">Modo oscuro</Text>
                <Switch checked={darkMode} onCheckedChange={setDarkMode} />
              </View>
            </View>
          </CardContent>
        </Card>
        <View style={{ height: 16 }} />

        {/* Verification Banner */}
        <AlertBanner
          variant="success"
          title="Cuenta verificada"
          description="Tu email ha sido verificado correctamente."
          iconName="shield"
        />
        <View style={{ height: 32 }} />
      </ScrollView>
    </View>
  )
}

const styles = StyleSheet.create({
  fullScreen: {
    flex: 1,
  },
  screenHeader: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingHorizontal: 8,
    paddingVertical: 8,
    borderBottomWidth: StyleSheet.hairlineWidth,
  },
  screenContent: {
    padding: 16,
    paddingBottom: 48,
  },
})
```

---

## Example 3: Onboarding Flow

**Use case:** Multi-step wizard for user onboarding with progress tracking and conditional rendering.

**Components used:** Badge, Progress, Input, RadioGroup, EmptyState, Button, Text

**Features:**
- 3-step wizard with step indicator and progress bar
- Conditional rendering per step
- Name input with icon
- Goal selection with radio options
- Success state with illustration
- Contextual navigation (back/continue/start)
- Completion toast with dynamic message

### State Setup

```tsx
const [onboardingStep, setOnboardingStep] = useState(0)
const [onboardingName, setOnboardingName] = useState('')
const [onboardingGoal, setOnboardingGoal] = useState('save')
```

### Implementation

```tsx
import { View, ScrollView, StyleSheet } from 'react-native'
import {
  Badge,
  Progress,
  Input,
  RadioGroup,
  EmptyState,
  Button,
  ButtonGroup,
  Text,
  useTheme,
  useToast,
} from '@retray-dev/ui-kit'

function OnboardingFlow() {
  const { colors } = useTheme()
  const { toast } = useToast()

  return (
    <View style={[styles.fullScreen, { backgroundColor: colors.background }]}>
      {/* Header */}
      <View style={[styles.screenHeader, { backgroundColor: colors.card, borderBottomColor: colors.border }]}>
        <Button
          label="Cerrar"
          variant="text"
          size="sm"
          onPress={() => {/* close onboarding */}}
        />
        <Text variant="title-sm">Bienvenido</Text>
        <View style={{ width: 70 }} />
      </View>

      {/* Content */}
      <ScrollView contentContainerStyle={styles.screenContent} keyboardShouldPersistTaps="handled">
        {/* Progress Indicator */}
        <View style={{ alignItems: 'center', marginBottom: 16 }}>
          <Badge label={`Paso ${onboardingStep + 1} de 3`} variant="secondary" />
          <View style={{ height: 12 }} />
          <Progress value={(onboardingStep + 1) * 33.3} style={{ width: '100%' }} />
        </View>

        {/* Step 1: Name */}
        {onboardingStep === 0 && (
          <View style={{ gap: 16 }}>
            <Text variant="display-md" style={{ textAlign: 'center' }}>¡Hola! 👋</Text>
            <Text variant="body-sm" color={colors.foregroundMuted} style={{ textAlign: 'center' }}>
              Cuéntanos un poco sobre ti para personalizar tu experiencia.
            </Text>
            <Input
              label="¿Cómo te llamas?"
              value={onboardingName}
              onChangeText={setOnboardingName}
              placeholder="Tu nombre"
              prefixIcon="user"
            />
          </View>
        )}

        {/* Step 2: Goal Selection */}
        {onboardingStep === 1 && (
          <View style={{ gap: 16 }}>
            <Text variant="display-md" style={{ textAlign: 'center' }}>¿Cuál es tu meta?</Text>
            <Text variant="body-sm" color={colors.foregroundMuted} style={{ textAlign: 'center' }}>
              Te ayudaremos a alcanzarla.
            </Text>
            <RadioGroup
              value={onboardingGoal}
              onValueChange={setOnboardingGoal}
              options={[
                { label: 'Ahorrar dinero', value: 'save' },
                { label: 'Pagar deudas', value: 'debt' },
                { label: 'Invertir', value: 'invest' },
                { label: 'Control de gastos', value: 'control' },
              ]}
            />
          </View>
        )}

        {/* Step 3: Completion */}
        {onboardingStep === 2 && (
          <View style={{ gap: 16 }}>
            <Text variant="display-md" style={{ textAlign: 'center' }}>
              ¡Listo, {onboardingName || 'amigo'}!
            </Text>
            <Text variant="body-sm" color={colors.foregroundMuted} style={{ textAlign: 'center' }}>
              Tu cuenta está configurada. Empieza a explorar.
            </Text>
            <EmptyState
              iconName="check-circle"
              title="Todo configurado"
              description="Toca continuar para empezar."
            />
          </View>
        )}

        <View style={{ height: 32 }} />

        {/* Navigation Buttons */}
        {onboardingStep === 0 ? (
          <Button
            label="Continuar"
            fullWidth
            iconName="arrow-right"
            onPress={() => setOnboardingStep((s) => s + 1)}
          />
        ) : (
          <ButtonGroup gap={8}>
            <Button
              label="Atrás"
              variant="secondary"
              onPress={() => setOnboardingStep((s) => s - 1)}
            />
            <Button
              label={onboardingStep === 2 ? 'Empezar' : 'Continuar'}
              iconName={onboardingStep === 2 ? 'check' : 'arrow-right'}
              onPress={() => {
                if (onboardingStep < 2) {
                  setOnboardingStep((s) => s + 1)
                } else {
                  setOnboardingStep(0)
                  toast({ 
                    title: `¡Bienvenido, ${onboardingName || 'amigo'}!`, 
                    variant: 'success' 
                  })
                }
              }}
            />
          </ButtonGroup>
        )}
        <View style={{ height: 32 }} />
      </ScrollView>
    </View>
  )
}

const styles = StyleSheet.create({
  fullScreen: {
    flex: 1,
  },
  screenHeader: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingHorizontal: 8,
    paddingVertical: 8,
    borderBottomWidth: StyleSheet.hairlineWidth,
  },
  screenContent: {
    padding: 16,
    paddingBottom: 48,
  },
})
```

---

## Common Patterns

### Full-Screen Overlay Pattern

All examples use a full-screen overlay with consistent header structure:

```tsx
<View style={styles.fullScreen}>
  {/* Header with navigation */}
  <View style={styles.screenHeader}>
    <Button label="Back" variant="text" size="sm" onPress={onBack} />
    <Text variant="title-sm">Screen Title</Text>
    <View style={{ width: 70 }} /> {/* Spacer for center alignment */}
  </View>

  {/* Scrollable content */}
  <ScrollView contentContainerStyle={styles.screenContent}>
    {/* content */}
  </ScrollView>
</View>
```

### Spacing Pattern

Consistent vertical rhythm with explicit `<View style={{ height: X }} />` separators:

```tsx
<ComponentA />
<View style={{ height: 16 }} />
<ComponentB />
```

### Color Usage

Always pull colors from theme via `useTheme()`:

```tsx
const { colors } = useTheme()

<View style={{ backgroundColor: colors.card, borderColor: colors.border }}>
  <Text color={colors.foregroundMuted}>Caption text</Text>
</View>
```

### Form Field Spacing

Standard 12px gap between fields:

```tsx
<Input label="Field 1" />
<View style={{ height: 12 }} />
<Input label="Field 2" />
```

### Toast Feedback

Use `useToast()` for success/error feedback after actions:

```tsx
const { toast } = useToast()

toast({ title: 'Action completed', variant: 'success' })
toast({ title: 'Error occurred', variant: 'destructive' })
```

### Button Pairs & Groups

Use `ButtonGroup` for equally-spaced button layouts (50%/50% split):

```tsx
// Horizontal pair (Cancel/Confirm pattern)
// Use size="sm" when icons are present to prevent text clipping on mobile
<ButtonGroup>
  <Button label="Cancel" variant="secondary" size="sm" iconName="x" onPress={handleCancel} />
  <Button label="Confirm" size="sm" iconName="check" onPress={handleConfirm} />
</ButtonGroup>

// Vertical stack
<ButtonGroup vertical gap={8}>
  <Button label="Primary Action" size="sm" iconName="zap" onPress={handlePrimary} />
  <Button label="Secondary Action" variant="secondary" size="sm" iconName="settings" onPress={handleSecondary} />
  <Button label="Delete" variant="destructive" size="sm" iconName="trash-2" onPress={handleDelete} />
</ButtonGroup>

// Conditional rendering (single vs pair)
{isFirstStep ? (
  <Button label="Continue" fullWidth iconName="arrow-right" onPress={handleNext} />
) : (
  <ButtonGroup>
    <Button label="Back" variant="secondary" onPress={handleBack} />
    <Button label="Continue" iconName="arrow-right" onPress={handleNext} />
  </ButtonGroup>
)}
```

---

## Running the Examples

These examples are live in the `example/` app included with the source. To run them:

```bash
# Clone the repo
git clone https://github.com/YOUR_USERNAME/retray-ui-kit
cd retray-ui-kit

# Install dependencies
pnpm install

# Build the library
pnpm build

# Run the example app
cd example
pnpm start
# Or: pnpm ios / pnpm android
```

Inside the example app, navigate to the "🖥 App Screen Compositions" accordion to access all three screens.

---

**For AI agents:** When generating screens, follow these patterns for consistency with the library's design philosophy. Use the theme colors, typography variants, spacing tokens, and component props shown in these examples.
