npm package: @joshuarileydev/phone-ui
Description: React Native UI library for iOS-style phone call interfaces
Author: Joshua Riley
Latest version: 1.0.6

# @joshuarileydev/phone-ui

A React Native UI library for creating iOS-style phone call interfaces with SF Symbols and modern design patterns.

## Features

- 🎨 iOS-style call screen interfaces
- 📞 Incoming call screen with accept/decline actions
- 📱 SF Symbols integration via expo-symbols
- 🎯 Simple API with press and long press handlers
- 🔄 Toggleable speaker and mute states
- 🖼️ Customizable background images
- 📦 TypeScript support
- ⚡ Expo and React Native compatible

## Installation

```sh
npm install @joshuarileydev/phone-ui
# or
yarn add @joshuarileydev/phone-ui
```

### Peer Dependencies

Make sure you have the required peer dependencies installed:

```sh
npm install react react-native expo-symbols
# or
yarn add react react-native expo-symbols
```

## Usage

### CallScreen (Active Call)

The `CallScreen` component displays an active call interface with controls for speaker, mute, FaceTime, add contact, keypad, and end call.

#### Basic Example

```tsx
import React, { useState } from 'react';
import { View } from 'react-native';
import { CallScreen } from '@joshuarileydev/phone-ui';

export default function App() {
  const [isSpeakerOn, setIsSpeakerOn] = useState(false);
  const [isMuted, setIsMuted] = useState(false);

  const handlePress = (buttonName: string) => {
    console.log(`${buttonName} pressed`);

    switch (buttonName) {
      case 'speaker':
        setIsSpeakerOn(!isSpeakerOn);
        break;
      case 'mute':
        setIsMuted(!isMuted);
        break;
      case 'end':
        // Handle call end
        break;
      case 'add':
        // Handle add contact/call
        break;
      case 'facetime':
        // Handle FaceTime
        break;
      case 'keypad':
        // Handle keypad
        break;
      case 'info':
        // Handle info button
        break;
    }
  };

  const handleLongPress = (buttonName: string) => {
    console.log(`${buttonName} long pressed`);
    // Handle long press actions
  };

  return (
    <View style={{ flex: 1, backgroundColor: '#000' }}>
      <CallScreen
        duration="00:02"
        contactName="John Doe"
        isSpeakerOn={isSpeakerOn}
        isMuted={isMuted}
        onPress={handlePress}
        onLongPress={handleLongPress}
      />
    </View>
  );
}
```

### CallingScreen (Incoming Call)

The `CallingScreen` component displays an incoming call interface with accept, decline, message, and voicemail actions.

#### Basic Example

```tsx
import React from 'react';
import { View } from 'react-native';
import { CallingScreen } from '@joshuarileydev/phone-ui';

export default function App() {
  const handleAccept = () => {
    console.log('Call accepted');
    // Navigate to active call screen
  };

  const handleDecline = () => {
    console.log('Call declined');
    // Dismiss call screen
  };

  const handleMessage = () => {
    console.log('Send message');
    // Open messaging
  };

  const handleVoicemail = () => {
    console.log('Send to voicemail');
    // Send to voicemail
  };

  return (
    <View style={{ flex: 1 }}>
      <CallingScreen
        name="John Doe"
        callType="mobile"
        onAccept={handleAccept}
        onDecline={handleDecline}
        onMessage={handleMessage}
        onVoicemail={handleVoicemail}
      />
    </View>
  );
}
```

#### With Custom Background

```tsx
import { CallingScreen } from '@joshuarileydev/phone-ui';

<CallingScreen
  name="Sarah Wilson"
  callType="iPhone"
  backgroundImage={require('./assets/custom-bg.jpg')}
  onAccept={handleAccept}
  onDecline={handleDecline}
  onMessage={handleMessage}
  onVoicemail={handleVoicemail}
/>;
```

## API Reference

### CallScreen Props

| Prop          | Type                           | Default       | Description               |
| ------------- | ------------------------------ | ------------- | ------------------------- |
| `duration`    | `string`                       | `"00:02"`     | Call duration display     |
| `contactName` | `string`                       | `"Chloe xxx"` | Contact name to display   |
| `isSpeakerOn` | `boolean`                      | `true`        | Speaker state             |
| `isMuted`     | `boolean`                      | `false`       | Mute state                |
| `onPress`     | `(buttonName: string) => void` | `undefined`   | Button press handler      |
| `onLongPress` | `(buttonName: string) => void` | `undefined`   | Button long press handler |

### Button Names

The `onPress` and `onLongPress` handlers receive one of these button names:

- `'info'` - Top right info button
- `'speaker'` - Speaker/Audio button
- `'facetime'` - FaceTime button
- `'mute'` - Mute button
- `'add'` - Add contact button
- `'end'` - End call button
- `'keypad'` - Keypad button

### Button States

#### Speaker Button

- **Inactive**: Gray background, white speaker icon, "Audio" label
- **Active**: White background, black speaker icon, "Audio" label

#### Mute Button

- **Inactive**: Gray background, white microphone icon, "Mute" label
- **Active**: White background, red microphone-slash icon, "Mute" label

### CallingScreen Props

| Prop              | Type                  | Default       | Description                                |
| ----------------- | --------------------- | ------------- | ------------------------------------------ |
| `name`            | `string`              | **Required**  | Contact name to display                    |
| `callType`        | `string`              | `"mobile"`    | Call type label (e.g., "mobile", "iPhone") |
| `backgroundImage` | `ImageSourcePropType` | Default image | Custom background image                    |
| `onAccept`        | `() => void`          | `undefined`   | Accept call button handler                 |
| `onDecline`       | `() => void`          | `undefined`   | Decline call button handler                |
| `onMessage`       | `() => void`          | `undefined`   | Send message button handler                |
| `onVoicemail`     | `() => void`          | `undefined`   | Send to voicemail button handler           |

## Examples

### With Custom Background

```tsx
import { LinearGradient } from 'expo-linear-gradient';

<LinearGradient colors={['#1a1a1a', '#0a0a0a']} style={{ flex: 1 }}>
  <CallScreen
    duration="01:23"
    contactName="Sarah Wilson"
    isSpeakerOn={false}
    isMuted={true}
    onPress={handlePress}
    onLongPress={handleLongPress}
  />
</LinearGradient>;
```

### Different Call States

```tsx
// Incoming call
<CallScreen
  duration="Incoming..."
  contactName="Mom"
  isSpeakerOn={false}
  isMuted={false}
  onPress={handlePress}
/>

// Active call
<CallScreen
  duration="02:45"
  contactName="Dr. Smith"
  isSpeakerOn={true}
  isMuted={false}
  onPress={handlePress}
/>
```

## Font Requirements

This component uses SF Pro font family. Make sure your app has access to SF Pro fonts, or the system will fall back to default fonts.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

MIT

---

Made with ❤️ by [@joshuarileydev](https://github.com/joshuarileydev)