{"id":31564240,"url":"https://github.com/anivar/react-native-omni-select","last_synced_at":"2026-04-28T21:34:54.987Z","repository":{"id":313400268,"uuid":"1050853804","full_name":"anivar/react-native-omni-select","owner":"anivar","description":"Lightweight omni-platform dropdown component for React Native — iOS, Android, and Web. By Anivar Aravind.","archived":false,"fork":false,"pushed_at":"2026-04-25T07:57:12.000Z","size":201,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-25T09:30:05.390Z","etag":null,"topics":["android","component","cross-platform","dropdown","ios","nextjs","react-native","react-native-web","select","typescript","web"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/anivar.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"anivar","custom":["https://www.buymeacoffee.com/anivar"]}},"created_at":"2025-09-05T03:43:28.000Z","updated_at":"2026-04-25T07:55:42.000Z","dependencies_parsed_at":"2025-09-05T20:44:12.853Z","dependency_job_id":"295b3914-88fc-4297-bc5d-52e3c02ed7ae","html_url":"https://github.com/anivar/react-native-omni-select","commit_stats":null,"previous_names":["anivar/react-native-omni-select"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/anivar/react-native-omni-select","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anivar%2Freact-native-omni-select","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anivar%2Freact-native-omni-select/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anivar%2Freact-native-omni-select/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anivar%2Freact-native-omni-select/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/anivar","download_url":"https://codeload.github.com/anivar/react-native-omni-select/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/anivar%2Freact-native-omni-select/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32400868,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-28T19:38:08.556Z","status":"ssl_error","status_checked_at":"2026-04-28T19:37:55.688Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","component","cross-platform","dropdown","ios","nextjs","react-native","react-native-web","select","typescript","web"],"created_at":"2025-10-05T05:03:10.053Z","updated_at":"2026-04-28T21:34:54.981Z","avatar_url":"https://github.com/anivar.png","language":"TypeScript","funding_links":["https://github.com/sponsors/anivar","https://www.buymeacoffee.com/anivar"],"categories":[],"sub_categories":[],"readme":"# react-native-omni-select\n\nA lightweight, omni-platform dropdown component for React Native that works everywhere - iOS, Android, and Web.\n\n[![npm version](https://img.shields.io/npm/v/react-native-omni-select.svg)](https://www.npmjs.com/package/react-native-omni-select)\n[![npm downloads](https://img.shields.io/npm/dm/react-native-omni-select.svg)](https://www.npmjs.com/package/react-native-omni-select)\n[![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)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Provenance](https://img.shields.io/badge/npm-provenance-success?logo=npm)](https://docs.npmjs.com/generating-provenance-statements)\n[![React Native](https://img.shields.io/badge/React%20Native-0.72%2B-61dafb?logo=react)](https://reactnative.dev/)\n[![Platform](https://img.shields.io/badge/platform-iOS%20%7C%20Android%20%7C%20Web-lightgrey)](https://github.com/anivar/react-native-omni-select)\n[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)\n[![Bundle Size](https://img.shields.io/bundlephobia/minzip/react-native-omni-select)](https://bundlephobia.com/package/react-native-omni-select)\n\n## ✨ Features\n\n- 📦 **\u003c 10KB** - Tiny bundle size\n- 🚀 **Zero dependencies** - No bloat\n- 🌍 **Omni-platform** - Works on iOS, Android, Web, and SSR\n- 📝 **TypeScript native** - Full type safety with generics\n- 🎨 **Customizable** - Style it your way\n- 🔍 **Searchable** - Built-in search/filter\n- ✅ **Single \u0026 Multi-select** - Both modes in one component\n- 🎯 **Simple API** - Just 5 essential props\n\n## 📦 Installation\n\n```bash\nnpm install react-native-omni-select\n```\n\nor with Yarn:\n\n```bash\nyarn add react-native-omni-select\n```\n\n## 🚀 Quick Start\n\n```tsx\nimport { Dropdown } from 'react-native-omni-select';\n\nconst MyComponent = () =\u003e {\n  const [value, setValue] = useState(null);\n  \n  const data = [\n    { label: 'Apple', value: 'apple' },\n    { label: 'Banana', value: 'banana' },\n    { label: 'Orange', value: 'orange' },\n  ];\n\n  return (\n    \u003cDropdown\n      data={data}\n      value={value}\n      onChange={setValue}\n      placeholder=\"Select a fruit\"\n    /\u003e\n  );\n};\n```\n\n## 📚 Examples\n\nCheck out the complete examples in the repository:\n\n- [**Basic Examples**](https://github.com/anivar/react-native-omni-select/blob/main/example/BasicExample.tsx) - Simple dropdown usage with strings and objects\n- [**Multi-Select Examples**](https://github.com/anivar/react-native-omni-select/blob/main/example/MultiSelectExample.tsx) - Multiple selection with search\n- [**Custom Type Examples**](https://github.com/anivar/react-native-omni-select/blob/main/example/CustomTypeExample.tsx) - TypeScript generics and custom rendering\n- [**Complete App Example**](https://github.com/anivar/react-native-omni-select/blob/main/example/App.tsx) - Full featured example app\n- [**Examples Documentation**](https://github.com/anivar/react-native-omni-select/tree/main/example) - How to run the examples\n\n## 📖 Complete Usage Guide\n\n### 1️⃣ Basic Usage\n\n#### Simple String Array\n```tsx\nimport { Dropdown } from 'react-native-omni-select';\n\nconst SimpleExample = () =\u003e {\n  const [selected, setSelected] = useState\u003cstring | null\u003e(null);\n  \n  return (\n    \u003cDropdown\n      data={['Small', 'Medium', 'Large', 'Extra Large']}\n      value={selected}\n      onChange={setSelected}\n      placeholder=\"Select size\"\n    /\u003e\n  );\n};\n```\n\n#### Object Array with Label/Value\n```tsx\nconst ObjectExample = () =\u003e {\n  const [selected, setSelected] = useState(null);\n  \n  const options = [\n    { label: 'JavaScript', value: 'js' },\n    { label: 'TypeScript', value: 'ts' },\n    { label: 'Python', value: 'py' },\n    { label: 'Ruby', value: 'rb' },\n  ];\n  \n  return (\n    \u003cDropdown\n      data={options}\n      value={selected}\n      onChange={setSelected}\n      placeholder=\"Select language\"\n    /\u003e\n  );\n};\n```\n\n### 2️⃣ Multi-Select Mode\n\n```tsx\nconst MultiSelectExample = () =\u003e {\n  const [selectedItems, setSelectedItems] = useState\u003cstring[]\u003e([]);\n  \n  const categories = ['Electronics', 'Clothing', 'Books', 'Sports', 'Home', 'Toys'];\n  \n  return (\n    \u003cView\u003e\n      \u003cDropdown\n        data={categories}\n        value={selectedItems}\n        onChange={setSelectedItems}\n        multiple\n        placeholder=\"Select categories\"\n      /\u003e\n      \n      {/* Display selected items */}\n      {selectedItems.length \u003e 0 \u0026\u0026 (\n        \u003cText\u003eSelected: {selectedItems.join(', ')}\u003c/Text\u003e\n      )}\n    \u003c/View\u003e\n  );\n};\n```\n\n### 3️⃣ Search/Filter Functionality\n\n```tsx\nconst SearchableExample = () =\u003e {\n  const [country, setCountry] = useState(null);\n  \n  const countries = [\n    { label: 'United States', value: 'us', code: '+1' },\n    { label: 'United Kingdom', value: 'uk', code: '+44' },\n    { label: 'Canada', value: 'ca', code: '+1' },\n    { label: 'Australia', value: 'au', code: '+61' },\n    // ... more countries\n  ];\n  \n  return (\n    \u003cDropdown\n      data={countries}\n      value={country}\n      onChange={setCountry}\n      search\n      searchPlaceholder=\"Search country...\"\n      placeholder=\"Select your country\"\n    /\u003e\n  );\n};\n```\n\n### 4️⃣ Custom Data Types with TypeScript\n\n```tsx\ninterface Product {\n  id: string;\n  name: string;\n  price: number;\n  category: string;\n  inStock: boolean;\n}\n\nconst ProductSelector = () =\u003e {\n  const [product, setProduct] = useState\u003cProduct | null\u003e(null);\n  \n  const products: Product[] = [\n    { id: '1', name: 'iPhone 15', price: 999, category: 'Electronics', inStock: true },\n    { id: '2', name: 'MacBook Pro', price: 2499, category: 'Electronics', inStock: true },\n    { id: '3', name: 'AirPods', price: 249, category: 'Audio', inStock: false },\n  ];\n  \n  return (\n    \u003cDropdown\u003cProduct\u003e\n      data={products}\n      value={product}\n      onChange={setProduct}\n      labelField=\"name\"\n      valueField=\"id\"\n      placeholder=\"Select a product\"\n      renderItem={(item, isSelected) =\u003e (\n        \u003cView style={styles.productItem}\u003e\n          \u003cText style={isSelected \u0026\u0026 styles.selected}\u003e{item.name}\u003c/Text\u003e\n          \u003cText style={styles.price}\u003e${item.price}\u003c/Text\u003e\n          {!item.inStock \u0026\u0026 \u003cText style={styles.outOfStock}\u003eOut of Stock\u003c/Text\u003e}\n        \u003c/View\u003e\n      )}\n    /\u003e\n  );\n};\n```\n\n### 5️⃣ Custom Rendering\n\n```tsx\nconst CustomRenderExample = () =\u003e {\n  const [user, setUser] = useState(null);\n  \n  const users = [\n    { id: 1, name: 'John Doe', avatar: '👨', role: 'Admin' },\n    { id: 2, name: 'Jane Smith', avatar: '👩', role: 'User' },\n    { id: 3, name: 'Bob Johnson', avatar: '🧑', role: 'Moderator' },\n  ];\n  \n  return (\n    \u003cDropdown\n      data={users}\n      value={user}\n      onChange={setUser}\n      labelField=\"name\"\n      valueField=\"id\"\n      placeholder=\"Select user\"\n      renderItem={(user, isSelected) =\u003e (\n        \u003cView style={styles.userItem}\u003e\n          \u003cText style={styles.avatar}\u003e{user.avatar}\u003c/Text\u003e\n          \u003cView style={styles.userInfo}\u003e\n            \u003cText style={[styles.userName, isSelected \u0026\u0026 styles.selected]}\u003e\n              {user.name}\n            \u003c/Text\u003e\n            \u003cText style={styles.userRole}\u003e{user.role}\u003c/Text\u003e\n          \u003c/View\u003e\n        \u003c/View\u003e\n      )}\n    /\u003e\n  );\n};\n```\n\n### 6️⃣ Platform-Specific Usage\n\n#### React Native (iOS/Android)\n```tsx\nimport { Dropdown } from 'react-native-omni-select';\n\n// Works out of the box on iOS and Android\nconst NativeExample = () =\u003e {\n  const [value, setValue] = useState(null);\n  \n  return (\n    \u003cDropdown\n      data={data}\n      value={value}\n      onChange={setValue}\n      // Automatically uses native measurement on mobile\n    /\u003e\n  );\n};\n```\n\n#### React Native Web\n```tsx\nimport { Dropdown } from 'react-native-omni-select';\n\n// Automatically detects web platform\nconst WebExample = () =\u003e {\n  const [value, setValue] = useState(null);\n  \n  return (\n    \u003cDropdown\n      data={data}\n      value={value}\n      onChange={setValue}\n      style={styles.webDropdown}\n      // Platform detection handled internally\n    /\u003e\n  );\n};\n```\n\n#### Next.js (with SSR)\n```tsx\nimport dynamic from 'next/dynamic';\n\n// SSR-safe import\nconst Dropdown = dynamic(\n  () =\u003e import('react-native-omni-select').then(mod =\u003e mod.Dropdown),\n  { \n    ssr: false,\n    loading: () =\u003e \u003cdiv\u003eLoading...\u003c/div\u003e\n  }\n);\n\nconst NextExample = () =\u003e {\n  const [value, setValue] = useState(null);\n  \n  return (\n    \u003cDropdown\n      data={data}\n      value={value}\n      onChange={setValue}\n      // Safe for server-side rendering\n    /\u003e\n  );\n};\n```\n\n### 7️⃣ Styling Examples\n\n```tsx\nconst StyledExample = () =\u003e {\n  return (\n    \u003c\u003e\n      {/* Custom trigger button style */}\n      \u003cDropdown\n        data={data}\n        value={value}\n        onChange={setValue}\n        style={{\n          backgroundColor: '#007AFF',\n          borderRadius: 25,\n          paddingHorizontal: 20,\n          borderWidth: 0,\n        }}\n      /\u003e\n      \n      {/* Custom dropdown menu style */}\n      \u003cDropdown\n        data={data}\n        value={value}\n        onChange={setValue}\n        dropdownStyle={{\n          borderRadius: 16,\n          shadowColor: '#000',\n          shadowOffset: { width: 0, height: 4 },\n          shadowOpacity: 0.2,\n          shadowRadius: 8,\n          elevation: 5,\n        }}\n      /\u003e\n      \n      {/* Custom item style */}\n      \u003cDropdown\n        data={data}\n        value={value}\n        onChange={setValue}\n        itemStyle={{\n          paddingVertical: 16,\n          paddingHorizontal: 20,\n          borderBottomWidth: 0,\n        }}\n      /\u003e\n    \u003c/\u003e\n  );\n};\n```\n\n### 8️⃣ Advanced Use Cases\n\n#### Form Integration\n```tsx\nconst FormExample = () =\u003e {\n  const [formData, setFormData] = useState({\n    name: '',\n    country: null,\n    interests: [],\n  });\n  \n  return (\n    \u003cView\u003e\n      \u003cTextInput\n        value={formData.name}\n        onChangeText={(text) =\u003e setFormData({...formData, name: text})}\n        placeholder=\"Name\"\n      /\u003e\n      \n      \u003cDropdown\n        data={countries}\n        value={formData.country}\n        onChange={(country) =\u003e setFormData({...formData, country})}\n        placeholder=\"Country\"\n      /\u003e\n      \n      \u003cDropdown\n        data={interests}\n        value={formData.interests}\n        onChange={(interests) =\u003e setFormData({...formData, interests})}\n        multiple\n        search\n        placeholder=\"Select interests\"\n      /\u003e\n      \n      \u003cButton title=\"Submit\" onPress={() =\u003e console.log(formData)} /\u003e\n    \u003c/View\u003e\n  );\n};\n```\n\n#### Dynamic Data Loading\n```tsx\nconst DynamicDataExample = () =\u003e {\n  const [data, setData] = useState([]);\n  const [loading, setLoading] = useState(true);\n  const [value, setValue] = useState(null);\n  \n  useEffect(() =\u003e {\n    // Fetch data from API\n    fetchOptions().then(options =\u003e {\n      setData(options);\n      setLoading(false);\n    });\n  }, []);\n  \n  if (loading) {\n    return \u003cActivityIndicator /\u003e;\n  }\n  \n  return (\n    \u003cDropdown\n      data={data}\n      value={value}\n      onChange={setValue}\n      placeholder=\"Select option\"\n    /\u003e\n  );\n};\n```\n\n## 🔧 API Reference\n\n### Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `data` | `T[]` | Required | Array of items to display |\n| `value` | `T \\| T[] \\| null` | `undefined` | Selected value(s) |\n| `onChange` | `(value: T \\| T[] \\| null) =\u003e void` | `undefined` | Selection change handler |\n| `placeholder` | `string` | `'Select'` | Placeholder text |\n| `multiple` | `boolean` | `false` | Enable multi-select |\n| `search` | `boolean` | `false` | Enable search/filter |\n| `searchPlaceholder` | `string` | `'Search...'` | Search input placeholder |\n| `disabled` | `boolean` | `false` | Disable the dropdown |\n| `labelField` | `keyof T \\| (item: T) =\u003e string` | `'label'` | Field/function for display text |\n| `valueField` | `keyof T \\| (item: T) =\u003e any` | `'value'` | Field/function for value |\n| `renderItem` | `(item: T, isSelected: boolean) =\u003e ReactNode` | `undefined` | Custom item renderer |\n| `style` | `ViewStyle` | `undefined` | Trigger button style |\n| `dropdownStyle` | `ViewStyle` | `undefined` | Dropdown menu style |\n| `itemStyle` | `ViewStyle` | `undefined` | Item container style |\n| `noResultsText` | `string` | `'No results'` | Empty search results text |\n\n## 💡 Tips \u0026 Best Practices\n\n1. **Use TypeScript generics** for better type safety:\n   ```tsx\n   \u003cDropdown\u003cMyDataType\u003e data={data} ... /\u003e\n   ```\n\n2. **Memoize data arrays** to prevent unnecessary re-renders:\n   ```tsx\n   const data = useMemo(() =\u003e [...], [dependency]);\n   ```\n\n3. **Handle null values** properly:\n   ```tsx\n   onChange={(value) =\u003e {\n     if (value) {\n       // Handle selection\n     }\n   }}\n   ```\n\n4. **Optimize large lists** by implementing search:\n   ```tsx\n   \u003cDropdown data={largeArray} search searchPlaceholder=\"Type to filter...\" /\u003e\n   ```\n\n## 🏗️ Project Structure\n\n```\nreact-native-omni-select/\n├── src/\n│   ├── Dropdown.tsx         # Main component (200 lines)\n│   ├── index.ts            # Exports\n│   └── types.ts            # TypeScript definitions\n├── example/                # Usage examples\n│   ├── App.tsx            # Basic example\n│   ├── NextExample.tsx    # Next.js example\n│   └── WebExample.tsx     # React Native Web example\n├── docs/                  # Additional documentation\n└── package.json\n```\n\n## 🤝 Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.\n\n## 📄 License\n\nMIT © [Anivar Aravind](https://github.com/anivar)\n\n## 🙏 Support\n\nIf you find this package useful, please ⭐ star it on [GitHub](https://github.com/anivar/react-native-omni-select)!\n\n☕ [Buy me a coffee](https://www.buymeacoffee.com/anivar)\n\n---\n\n**Why react-native-omni-select?** Simple. It works everywhere, has zero dependencies, and is under 10KB. No complexity, just a dropdown that works.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanivar%2Freact-native-omni-select","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fanivar%2Freact-native-omni-select","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fanivar%2Freact-native-omni-select/lists"}