> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mutalabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Code Screens

> Inject native React components into your Muta flows for custom functionality

Code Screens enable you to seamlessly integrate custom native React components into your remotely configured Muta flows. This powerful feature allows you to combine the flexibility of no-code flow management with the full capabilities of native development.

## Overview

Code Screens act as placeholders in your Muta flows that are replaced with native React components at runtime. This enables you to:

* Add authentication screens to your onboarding flows
* Integrate payment processing directly in your flows
* Include complex native UI that requires custom logic
* Maintain remote configurability while using native code

## How It Works

<Steps>
  <Step title="Create a Code Screen">
    In the Muta web editor, add a "Code Screen" to your flow and give it a unique name (e.g., "Login Screen", "Payment Form")
  </Step>

  <Step title="Configure Navigation">
    Set up the continue and back navigation destinations for your code screen
  </Step>

  <Step title="Inject Components">
    Pass your React components when displaying the placement in your app
  </Step>
</Steps>

## Implementation

### Basic Setup

Pass your custom components when calling `displayPlacement`:

```tsx theme={null}
import { Muta } from '@mutalabs/react-native-muta';
import { LoginScreen } from './screens/LoginScreen';
import { PaymentScreen } from './screens/PaymentScreen';

Muta.displayPlacement({
  placementId: 'onboarding',
  bgColor: '#000000',
  presentationType: 'none',
  injectedScreens: [
    {
      screenName: 'Login Screen',  // Must match the name in Muta editor
      component: LoginScreen,
    },
    {
      screenName: 'Payment Form',
      component: PaymentScreen,
    },
  ],
});
```

### Component Interface

Your injected components receive the following props:

```tsx theme={null}
interface CodeScreenProps {
  onContinue: () => void      // Navigate to configured continue destination
  onBack: () => void          // Navigate to configured back destination
  variables: any[]            // Current flow variables
  screenId: string            // Unique screen ID
  screenIndex: number         // Screen position in flow
}
```

### Example Component

Here's a complete example of a login screen component:

```tsx theme={null}
import React, { useState } from 'react';
import { View, TextInput, Button, StyleSheet, Text } from 'react-native';

function LoginScreen({ onContinue, onBack, variables }: CodeScreenProps) {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const [loading, setLoading] = useState(false);

  const handleLogin = async () => {
    setError('');
    setLoading(true);

    try {
      // Your authentication logic
      const response = await fetch('https://api.example.com/login', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email, password }),
      });

      if (response.ok) {
        const data = await response.json();
        // Store auth token, update user state, etc.
        await AsyncStorage.setItem('authToken', data.token);

        // Navigate to the next screen in the flow
        onContinue();
      } else {
        setError('Invalid email or password');
      }
    } catch (err) {
      setError('Network error. Please try again.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Welcome Back</Text>

      <TextInput
        style={styles.input}
        value={email}
        onChangeText={setEmail}
        placeholder="Email"
        keyboardType="email-address"
        autoCapitalize="none"
        editable={!loading}
      />

      <TextInput
        style={styles.input}
        value={password}
        onChangeText={setPassword}
        placeholder="Password"
        secureTextEntry
        editable={!loading}
      />

      {error ? <Text style={styles.error}>{error}</Text> : null}

      <Button
        title={loading ? "Logging in..." : "Login"}
        onPress={handleLogin}
        disabled={loading || !email || !password}
      />

      <Button
        title="Back"
        onPress={onBack}
        disabled={loading}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    padding: 20,
    justifyContent: 'center',
  },
  title: {
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 30,
    textAlign: 'center',
  },
  input: {
    borderWidth: 1,
    borderColor: '#ddd',
    padding: 15,
    marginBottom: 15,
    borderRadius: 8,
  },
  error: {
    color: 'red',
    marginBottom: 15,
    textAlign: 'center',
  },
});
```

## Animations

Code screens automatically animate in and out matching your flow's configured animations:

* **Entry Animation**: Matches the animation used when navigating TO the code screen
* **Exit Animation**: Uses the configured continue/back animation settings
* **Seamless Transitions**: Native screens blend smoothly with your flow screens

## Use Cases

### Authentication Flows

Integrate login, signup, or authentication screens directly into your onboarding:

```tsx theme={null}
injectedScreens: [
  { screenName: 'Login', component: LoginScreen },
  { screenName: 'Signup', component: SignupScreen },
  { screenName: 'Verify Email', component: VerifyEmailScreen },
]
```

### Payment Integration

Add payment processing without breaking the flow experience:

```tsx theme={null}
injectedScreens: [
  { screenName: 'Payment Method', component: PaymentMethodScreen },
  { screenName: 'Billing Details', component: BillingDetailsScreen },
  { screenName: 'Confirm Purchase', component: ConfirmPurchaseScreen },
]
```

### Complex Forms

Handle multi-step forms or complex data entry:

```tsx theme={null}
injectedScreens: [
  { screenName: 'Profile Setup', component: ProfileSetupScreen },
  { screenName: 'Preferences', component: PreferencesScreen },
  { screenName: 'Location Permissions', component: LocationPermissionScreen },
]
```

## Best Practices

<AccordionGroup>
  <Accordion title="Screen Naming">
    * Use descriptive, unique names for your code screens
    * Keep names consistent between the Muta editor and your code
    * Avoid special characters in screen names
  </Accordion>

  <Accordion title="Error Handling">
    * Always handle errors gracefully in your components
    * Provide clear feedback to users
    * Consider offering retry options for network failures
  </Accordion>

  <Accordion title="Navigation">
    * Always call `onContinue()` or `onBack()` to maintain flow continuity
    * Disable navigation buttons during async operations
    * Consider confirmation dialogs for destructive back actions
  </Accordion>

  <Accordion title="Performance">
    * Keep components lightweight and focused
    * Avoid heavy computations in render methods
    * Use React.memo for performance-critical components
  </Accordion>
</AccordionGroup>

## Troubleshooting

<Warning>
  Screen names must match exactly between the Muta editor and your injected screens configuration. A mismatch will result in the code screen not displaying.
</Warning>

### Common Issues

**Code screen not appearing:**

* Verify the screen name matches exactly (case-sensitive)
* Ensure the component is properly imported
* Check that injectedScreens is passed to displayPlacement

**Navigation not working:**

* Confirm you're calling onContinue() or onBack()
* Check that navigation destinations are configured in the editor
* Ensure no JavaScript errors are preventing execution

**Animation issues:**

* Verify presentationType is set appropriately
* Check that animation durations are reasonable (200-500ms)
* Ensure components render quickly to avoid animation lag

## Advanced Usage

### Accessing Flow Variables

Code screens can read and react to flow variables:

```tsx theme={null}
function PaymentScreen({ variables, onContinue }: CodeScreenProps) {
  // Find specific variable by ID
  const planType = variables.find(v => v.id === 'selected_plan')?.value;
  const userEmail = variables.find(v => v.id === 'user_email')?.value;

  // Use variables to customize the screen
  const price = planType === 'premium' ? '$9.99' : '$4.99';

  // ... rest of component
}
```

### Sequential Code Screens

You can navigate directly from one code screen to another:

```tsx theme={null}
// In Muta editor: Login Screen → Verification Screen → Welcome Screen

injectedScreens: [
  { screenName: 'Login Screen', component: LoginScreen },
  { screenName: 'Verification Screen', component: VerificationScreen },
  // Welcome Screen is a regular Muta screen
]
```

The SDK handles transitions smoothly between consecutive code screens without any special configuration.
