An open API service indexing awesome lists of open source software.

https://github.com/anivar/react-native-omni-select

Lightweight omni-platform dropdown component for React Native — iOS, Android, and Web. By Anivar Aravind.
https://github.com/anivar/react-native-omni-select

android component cross-platform dropdown ios nextjs react-native react-native-web select typescript web

Last synced: about 2 months ago
JSON representation

Lightweight omni-platform dropdown component for React Native — iOS, Android, and Web. By Anivar Aravind.

Awesome Lists containing this project

README

          

# react-native-omni-select

A lightweight, omni-platform dropdown component for React Native that works everywhere - iOS, Android, and Web.

[![npm version](https://img.shields.io/npm/v/react-native-omni-select.svg)](https://www.npmjs.com/package/react-native-omni-select)
[![npm downloads](https://img.shields.io/npm/dm/react-native-omni-select.svg)](https://www.npmjs.com/package/react-native-omni-select)
[![CI](https://github.com/anivar/react-native-omni-select/actions/workflows/ci.yml/badge.svg)](https://github.com/anivar/react-native-omni-select/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Provenance](https://img.shields.io/badge/npm-provenance-success?logo=npm)](https://docs.npmjs.com/generating-provenance-statements)
[![React Native](https://img.shields.io/badge/React%20Native-0.72%2B-61dafb?logo=react)](https://reactnative.dev/)
[![Platform](https://img.shields.io/badge/platform-iOS%20%7C%20Android%20%7C%20Web-lightgrey)](https://github.com/anivar/react-native-omni-select)
[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
[![Bundle Size](https://img.shields.io/bundlephobia/minzip/react-native-omni-select)](https://bundlephobia.com/package/react-native-omni-select)

## ✨ Features

- 📦 **< 10KB** - Tiny bundle size
- 🚀 **Zero dependencies** - No bloat
- 🌍 **Omni-platform** - Works on iOS, Android, Web, and SSR
- 📝 **TypeScript native** - Full type safety with generics
- 🎨 **Customizable** - Style it your way
- 🔍 **Searchable** - Built-in search/filter
- ✅ **Single & Multi-select** - Both modes in one component
- 🎯 **Simple API** - Just 5 essential props

## 📦 Installation

```bash
npm install react-native-omni-select
```

or with Yarn:

```bash
yarn add react-native-omni-select
```

## 🚀 Quick Start

```tsx
import { Dropdown } from 'react-native-omni-select';

const MyComponent = () => {
const [value, setValue] = useState(null);

const data = [
{ label: 'Apple', value: 'apple' },
{ label: 'Banana', value: 'banana' },
{ label: 'Orange', value: 'orange' },
];

return (

);
};
```

## 📚 Examples

Check out the complete examples in the repository:

- [**Basic Examples**](https://github.com/anivar/react-native-omni-select/blob/main/example/BasicExample.tsx) - Simple dropdown usage with strings and objects
- [**Multi-Select Examples**](https://github.com/anivar/react-native-omni-select/blob/main/example/MultiSelectExample.tsx) - Multiple selection with search
- [**Custom Type Examples**](https://github.com/anivar/react-native-omni-select/blob/main/example/CustomTypeExample.tsx) - TypeScript generics and custom rendering
- [**Complete App Example**](https://github.com/anivar/react-native-omni-select/blob/main/example/App.tsx) - Full featured example app
- [**Examples Documentation**](https://github.com/anivar/react-native-omni-select/tree/main/example) - How to run the examples

## 📖 Complete Usage Guide

### 1️⃣ Basic Usage

#### Simple String Array
```tsx
import { Dropdown } from 'react-native-omni-select';

const SimpleExample = () => {
const [selected, setSelected] = useState(null);

return (

);
};
```

#### Object Array with Label/Value
```tsx
const ObjectExample = () => {
const [selected, setSelected] = useState(null);

const options = [
{ label: 'JavaScript', value: 'js' },
{ label: 'TypeScript', value: 'ts' },
{ label: 'Python', value: 'py' },
{ label: 'Ruby', value: 'rb' },
];

return (

);
};
```

### 2️⃣ Multi-Select Mode

```tsx
const MultiSelectExample = () => {
const [selectedItems, setSelectedItems] = useState([]);

const categories = ['Electronics', 'Clothing', 'Books', 'Sports', 'Home', 'Toys'];

return (



{/* Display selected items */}
{selectedItems.length > 0 && (
Selected: {selectedItems.join(', ')}
)}

);
};
```

### 3️⃣ Search/Filter Functionality

```tsx
const SearchableExample = () => {
const [country, setCountry] = useState(null);

const countries = [
{ label: 'United States', value: 'us', code: '+1' },
{ label: 'United Kingdom', value: 'uk', code: '+44' },
{ label: 'Canada', value: 'ca', code: '+1' },
{ label: 'Australia', value: 'au', code: '+61' },
// ... more countries
];

return (

);
};
```

### 4️⃣ Custom Data Types with TypeScript

```tsx
interface Product {
id: string;
name: string;
price: number;
category: string;
inStock: boolean;
}

const ProductSelector = () => {
const [product, setProduct] = useState(null);

const products: Product[] = [
{ id: '1', name: 'iPhone 15', price: 999, category: 'Electronics', inStock: true },
{ id: '2', name: 'MacBook Pro', price: 2499, category: 'Electronics', inStock: true },
{ id: '3', name: 'AirPods', price: 249, category: 'Audio', inStock: false },
];

return (

data={products}
value={product}
onChange={setProduct}
labelField="name"
valueField="id"
placeholder="Select a product"
renderItem={(item, isSelected) => (

{item.name}
${item.price}
{!item.inStock && Out of Stock}

)}
/>
);
};
```

### 5️⃣ Custom Rendering

```tsx
const CustomRenderExample = () => {
const [user, setUser] = useState(null);

const users = [
{ id: 1, name: 'John Doe', avatar: '👨', role: 'Admin' },
{ id: 2, name: 'Jane Smith', avatar: '👩', role: 'User' },
{ id: 3, name: 'Bob Johnson', avatar: '🧑', role: 'Moderator' },
];

return (
(

{user.avatar}


{user.name}

{user.role}


)}
/>
);
};
```

### 6️⃣ Platform-Specific Usage

#### React Native (iOS/Android)
```tsx
import { Dropdown } from 'react-native-omni-select';

// Works out of the box on iOS and Android
const NativeExample = () => {
const [value, setValue] = useState(null);

return (

);
};
```

#### React Native Web
```tsx
import { Dropdown } from 'react-native-omni-select';

// Automatically detects web platform
const WebExample = () => {
const [value, setValue] = useState(null);

return (

);
};
```

#### Next.js (with SSR)
```tsx
import dynamic from 'next/dynamic';

// SSR-safe import
const Dropdown = dynamic(
() => import('react-native-omni-select').then(mod => mod.Dropdown),
{
ssr: false,
loading: () =>

Loading...

}
);

const NextExample = () => {
const [value, setValue] = useState(null);

return (

);
};
```

### 7️⃣ Styling Examples

```tsx
const StyledExample = () => {
return (
<>
{/* Custom trigger button style */}


{/* Custom dropdown menu style */}


{/* Custom item style */}

>
);
};
```

### 8️⃣ Advanced Use Cases

#### Form Integration
```tsx
const FormExample = () => {
const [formData, setFormData] = useState({
name: '',
country: null,
interests: [],
});

return (

setFormData({...formData, name: text})}
placeholder="Name"
/>

setFormData({...formData, country})}
placeholder="Country"
/>

setFormData({...formData, interests})}
multiple
search
placeholder="Select interests"
/>

console.log(formData)} />

);
};
```

#### Dynamic Data Loading
```tsx
const DynamicDataExample = () => {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
const [value, setValue] = useState(null);

useEffect(() => {
// Fetch data from API
fetchOptions().then(options => {
setData(options);
setLoading(false);
});
}, []);

if (loading) {
return ;
}

return (

);
};
```

## 🔧 API Reference

### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `data` | `T[]` | Required | Array of items to display |
| `value` | `T \| T[] \| null` | `undefined` | Selected value(s) |
| `onChange` | `(value: T \| T[] \| null) => void` | `undefined` | Selection change handler |
| `placeholder` | `string` | `'Select'` | Placeholder text |
| `multiple` | `boolean` | `false` | Enable multi-select |
| `search` | `boolean` | `false` | Enable search/filter |
| `searchPlaceholder` | `string` | `'Search...'` | Search input placeholder |
| `disabled` | `boolean` | `false` | Disable the dropdown |
| `labelField` | `keyof T \| (item: T) => string` | `'label'` | Field/function for display text |
| `valueField` | `keyof T \| (item: T) => any` | `'value'` | Field/function for value |
| `renderItem` | `(item: T, isSelected: boolean) => ReactNode` | `undefined` | Custom item renderer |
| `style` | `ViewStyle` | `undefined` | Trigger button style |
| `dropdownStyle` | `ViewStyle` | `undefined` | Dropdown menu style |
| `itemStyle` | `ViewStyle` | `undefined` | Item container style |
| `noResultsText` | `string` | `'No results'` | Empty search results text |

## 💡 Tips & Best Practices

1. **Use TypeScript generics** for better type safety:
```tsx
data={data} ... />
```

2. **Memoize data arrays** to prevent unnecessary re-renders:
```tsx
const data = useMemo(() => [...], [dependency]);
```

3. **Handle null values** properly:
```tsx
onChange={(value) => {
if (value) {
// Handle selection
}
}}
```

4. **Optimize large lists** by implementing search:
```tsx

```

## 🏗️ Project Structure

```
react-native-omni-select/
├── src/
│ ├── Dropdown.tsx # Main component (200 lines)
│ ├── index.ts # Exports
│ └── types.ts # TypeScript definitions
├── example/ # Usage examples
│ ├── App.tsx # Basic example
│ ├── NextExample.tsx # Next.js example
│ └── WebExample.tsx # React Native Web example
├── docs/ # Additional documentation
└── package.json
```

## 🤝 Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.

## 📄 License

MIT © [Anivar Aravind](https://github.com/anivar)

## 🙏 Support

If you find this package useful, please ⭐ star it on [GitHub](https://github.com/anivar/react-native-omni-select)!

☕ [Buy me a coffee](https://www.buymeacoffee.com/anivar)

---

**Why react-native-omni-select?** Simple. It works everywhere, has zero dependencies, and is under 10KB. No complexity, just a dropdown that works.