npm package: @joshuarileydev/whatsappui
Description: ui for whatsapp
Author: Joshua Riley
Latest version: 0.1.5

# @joshuarileydev/whatsappui

A React Native WhatsApp UI component library that provides an authentic WhatsApp interface with chat list, search functionality, and navigation.

## Installation

```sh
npm install @joshuarileydev/whatsappui
```

**Dependencies:**

- `react-native-svg` (>=13.0.0) - Required for icons
- `react-native-safe-area-context` (>=3.0.0) - Required for safe area handling

```sh
npm install react-native-svg react-native-safe-area-context
```

## Usage

### Basic Usage

```jsx
import { WhatsApp } from '@joshuarileydev/whatsappui';
import { SafeAreaProvider } from 'react-native-safe-area-context';

export default function App() {
  return (
    <SafeAreaProvider>
      <WhatsApp
        onChatPress={(chat) => console.log('Chat pressed:', chat.name)}
        onSearchChange={(text) => console.log('Search:', text)}
        onTabPress={(tab) => console.log('Tab pressed:', tab)}
      />
    </SafeAreaProvider>
  );
}
```

### Advanced Usage with Custom Props

```jsx
import { WhatsApp } from '@joshuarileydev/whatsappui';
import { useState } from 'react';

export default function App() {
  const [searchText, setSearchText] = useState('');
  const [filteredChats, setFilteredChats] = useState([]);

  const customChats = [
    {
      id: '1',
      name: 'John Doe',
      message: 'Hey, how are you?',
      time: '12:30',
      avatarColor: '#FF6B9D',
      avatarInitials: 'JD',
      hasNotification: true,
      notificationCount: 2,
    },
    // ... more chats
  ];

  const handleSearchChange = (text) => {
    setSearchText(text);
    const filtered = customChats.filter((chat) =>
      chat.name.toLowerCase().includes(text.toLowerCase())
    );
    setFilteredChats(filtered);
  };

  return (
    <WhatsApp
      searchText={searchText}
      onSearchChange={handleSearchChange}
      defaultChats={searchText ? filteredChats : customChats}
      showNoResults={searchText.length > 0 && filteredChats.length === 0}
      onChatPress={(chat) => {
        // Navigate to chat details
        console.log('Opening chat with:', chat.name);
      }}
    />
  );
}
```

## API Reference

### WhatsApp Component Props

| Prop             | Type                        | Default     | Description                                                                               |
| ---------------- | --------------------------- | ----------- | ----------------------------------------------------------------------------------------- |
| `onSearchChange` | `(text: string) => void`    | `undefined` | Callback fired when search text changes                                                   |
| `onTabPress`     | `(tabName: string) => void` | `undefined` | Callback fired when tab is pressed                                                        |
| `onChatPress`    | `(chat: ChatItem) => void`  | `undefined` | Callback fired when chat item is pressed                                                  |
| `showNoResults`  | `boolean`                   | `false`     | Whether to show "No chats found" when defaultChats is empty                               |
| `searchText`     | `string`                    | `undefined` | External control of search text (controlled mode)                                         |
| `defaultChats`   | `ChatItem[]`                | `mockChats` | Array of chat items to display                                                            |
| `searchMode`     | `'filter' \| 'callback'`    | `'filter'`  | Controls search behavior: 'filter' filters chats, 'callback' only triggers onSearchChange |

### ChatItem Interface

```typescript
interface ChatItem {
  id: string;
  name: string;
  message: string;
  time: string;
  avatarColor: string;
  avatarInitials: string;
  hasUpdate?: boolean;
  hasNotification?: boolean;
  notificationCount?: number;
  isPinned?: boolean;
  isTyping?: boolean;
  messageType?: 'text' | 'reaction' | 'location' | 'voice' | 'deleted';
  hasCheckmark?: boolean;
  isMentioned?: boolean;
}
```

## Features

- **Full Screen UI**: Takes up the entire screen for an immersive experience
- **Authentic WhatsApp UI**: Pixel-perfect recreation of WhatsApp's interface
- **Flexible Search**: Built-in filtering or custom search handling via callbacks
- **Chat Navigation**: Smooth animations between chat list and individual chats
- **Gesture Navigation**: Two-finger swipe down to go back from chat view
- **Customizable Chat Data**: Pass your own chat data or use built-in mock data
- **No Results State**: Optional display of empty state when no chats match
- **TypeScript Support**: Full TypeScript definitions included
- **Tab Navigation**: Bottom tab bar with Updates, Calls, Communities, Chats, and Settings
- **Status Indicators**: Support for typing indicators, notifications, pins, and more

## Search Modes

The component supports two search modes via the `searchMode` prop:

### `'filter'` (Default)

- The component automatically filters the provided chats based on search text
- Searches through chat names and messages
- Perfect for simple use cases where you want built-in search functionality

### `'callback'`

- Only triggers the `onSearchChange` callback without filtering
- Useful when you need custom search logic (e.g., backend search, complex filters)
- You control the filtering by updating `defaultChats` based on search results

## Examples

### Built-in Search Filtering (Default)

```jsx
const [searchQuery, setSearchQuery] = useState('');

<WhatsApp
  searchText={searchQuery}
  onSearchChange={setSearchQuery}
  searchMode="filter" // Default - automatically filters chats
  defaultChats={allChats}
  showNoResults={true}
/>;
```

### Custom Search Handling

```jsx
const [searchQuery, setSearchQuery] = useState('');
const [filteredChats, setFilteredChats] = useState(allChats);

const handleSearch = (text) => {
  setSearchQuery(text);
  // Custom search logic - search backend, multiple fields, etc.
  const filtered = performCustomSearch(text, allChats);
  setFilteredChats(filtered);
};

<WhatsApp
  searchText={searchQuery}
  onSearchChange={handleSearch}
  searchMode="callback" // Only triggers callback, no automatic filtering
  defaultChats={filteredChats}
  showNoResults={searchQuery.length > 0 && filteredChats.length === 0}
/>;
```

### Empty State

```jsx
<WhatsApp defaultChats={[]} showNoResults={true} />
```

### Full Screen Usage

The component automatically takes up the full screen. To use it properly:

```jsx
import { WhatsApp } from '@joshuarileydev/whatsappui';

export default function App() {
  return (
    <WhatsApp
      onChatPress={(chat) => {
        // Handle chat selection
        // Use two-finger swipe down gesture to go back
      }}
    />
  );
}
```

## Gestures

- **Two-finger swipe down**: When viewing an individual chat, swipe down with two fingers to go back to the chat list
- **Single tap**: Tap on any chat item to open the chat view
- **Search**: Tap the search bar to start searching

### Empty State

```jsx
<WhatsApp defaultChats={[]} showNoResults={true} />
```

## Contributing

- [Development workflow](CONTRIBUTING.md#development-workflow)
- [Sending a pull request](CONTRIBUTING.md#sending-a-pull-request)
- [Code of conduct](CODE_OF_CONDUCT.md)

## License

MIT

---

Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)