{"_id":"@atom_design/search","_rev":"2-f63f01027a1ed5d2f951684dd0c50458","name":"@atom_design/search","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@atom_design/search","version":"1.0.0","keywords":["react-native","search","filter","searchbar","autocomplete","component","ui","atom-design"],"author":{"name":"Atom Design"},"license":"MIT","_id":"@atom_design/search@1.0.0","maintainers":[{"name":"moglix","email":"devops@moglix.com"},{"name":"avi-moglix","email":"avi.gupta@moglix.com"}],"dist":{"shasum":"433d040bcd3b2b14bfee67e71ed8c635a91846f8","tarball":"https://registry.npmjs.org/@atom_design/search/-/search-1.0.0.tgz","fileCount":5,"integrity":"sha512-fPTtKnX/Gzb5ZOQ+nrJrRwZ5H7f+aUD9vhRe9gMPiIdJkKKoODa4gPIGgYkvvEO4fHW75J/tdA6h6flaggZT9A==","signatures":[{"sig":"MEYCIQDE6vu0QGm1Yw6LkhW5QITEgCzQGMEkHOmxQXwubNzLfgIhAMqFGn2Z792hyTYX7NjxKpNpvb1VYEdLU2jKeNWEto4J","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":30358},"main":"index.js","types":"index.d.ts","_npmUser":{"name":"avi-moglix","email":"avi.gupta@moglix.com"},"_npmVersion":"10.8.2","description":"A comprehensive React Native search component with filters, debouncing, and customizable results.","directories":{},"_nodeVersion":"20.19.5","_hasShrinkwrap":false,"peerDependencies":{"react":">=17.0.0","prop-types":">=15.0.0","react-native":">=0.64.0","react-native-vector-icons":">=9.0.0"},"_npmOperationalInternal":{"tmp":"tmp/search_1.0.0_1764758630629_0.630438659756613","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@atom_design/search","version":"1.0.1","description":"A comprehensive React Native search component with filters, debouncing, and customizable results.","main":"index.js","types":"index.d.ts","author":{"name":"Atom Design"},"license":"MIT","keywords":["react-native","search","filter","searchbar","autocomplete","component","ui","atom-design"],"peerDependencies":{"react":">=17.0.0","react-native":">=0.64.0","prop-types":">=15.0.0","react-native-vector-icons":">=9.0.0"},"_id":"@atom_design/search@1.0.1","_nodeVersion":"20.19.5","_npmVersion":"10.8.2","dist":{"integrity":"sha512-RoFy6rgY/uBU1eoZ6u46Y5+fDy54oFbasees/Tjvo5CdBPgNd9HH0hjW2P10HY1zVTWRigwB+FRlzkcQtOx4cg==","shasum":"296500495dc74e31bb3ec96a90ef5a7b71433cb8","tarball":"https://registry.npmjs.org/@atom_design/search/-/search-1.0.1.tgz","fileCount":5,"unpackedSize":30828,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCiGcVNBuxz8AuHm2Kywajax6Rs/6DUHgyCAH+alQHYmQIhANjMDjl34/s6zc/BHDdCg60TQRvMrqNQbXXE48qpyOpc"}]},"_npmUser":{"name":"avi-moglix","email":"avi.gupta@moglix.com"},"directories":{},"maintainers":[{"name":"moglix","email":"devops@moglix.com"},{"name":"avi-moglix","email":"avi.gupta@moglix.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/search_1.0.1_1764759055071_0.7694239749296805"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-03T10:43:50.543Z","modified":"2025-12-03T10:50:55.498Z","1.0.0":"2025-12-03T10:43:50.816Z","1.0.1":"2025-12-03T10:50:55.264Z"},"author":{"name":"Atom Design"},"license":"MIT","keywords":["react-native","search","filter","searchbar","autocomplete","component","ui","atom-design"],"description":"A comprehensive React Native search component with filters, debouncing, and customizable results.","maintainers":[{"name":"moglix","email":"devops@moglix.com"},{"name":"avi-moglix","email":"avi.gupta@moglix.com"}],"readme":"# @atom_design/search\n\nA comprehensive and flexible **Search Component** for React Native, built as part of the **Atom Design System**. Features a search bar with debouncing, filter chips, and customizable results list.\n\n---\n\n## ✨ Features\n\n- 🔍 **Search Bar** - Clean input with search icon and clear button\n- ⏱️ **Debounced Search** - Configurable delay to reduce API calls\n- 🏷️ **Filter Chips** - Multi-select filter tags with checkmarks\n- 📋 **Results List** - FlatList with custom rendering support\n- ⌨️ **Keyboard Handling** - Auto-dismiss and return key support\n- 🔄 **Loading State** - Spinner indicator during search\n- 🎨 **Fully Customizable** - Colors, styles, and components\n- ♿ **Accessible** - Screen reader support with proper roles\n- 🎯 **TypeScript Support** - Full type definitions included\n\n---\n\n## 📦 Installation\n\n```bash\nnpm install @atom_design/search\n```\n\nOr with yarn:\n\n```bash\nyarn add @atom_design/search\n```\n\n### Peer Dependencies\n\nMake sure you have the required peer dependencies installed:\n\n```bash\nnpm install react-native-vector-icons prop-types\n```\n\nFor `react-native-vector-icons` setup, follow the [installation guide](https://github.com/oblador/react-native-vector-icons#installation).\n\n---\n\n## 📥 Import\n\n```javascript\nimport Search from '@atom_design/search';\n// or\nimport { Search } from '@atom_design/search';\n```\n\n---\n\n## 🎯 Basic Usage\n\n```jsx\nimport React, { useState, useMemo } from 'react';\nimport Search from '@atom_design/search';\n\nfunction SearchExample() {\n  const [results, setResults] = useState([]);\n\n  const handleSearch = (query) => {\n    // Filter or fetch results based on query\n    const filtered = allItems.filter(item =>\n      item.label.toLowerCase().includes(query.toLowerCase())\n    );\n    setResults(filtered);\n  };\n\n  return (\n    <Search\n      placeholder=\"Search items...\"\n      onSearch={handleSearch}\n      results={results}\n      onResultPress={(item) => console.log('Selected:', item)}\n    />\n  );\n}\n```\n\n---\n\n## 📋 Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `placeholder` | `string` | `'Search...'` | Placeholder text |\n| `value` | `string` | - | Controlled input value |\n| `onSearch` | `function` | - | Debounced search callback |\n| `onChangeText` | `function` | - | Immediate text change callback |\n| `results` | `array` | `[]` | Array of result items |\n| `filters` | `array` | `[]` | Array of filter options |\n| `selectedFilters` | `array` | - | Controlled selected filters |\n| `onFilterSelect` | `function` | - | Filter change callback |\n| `onResultPress` | `function` | - | Result item press callback |\n| `renderResult` | `function` | - | Custom result renderer |\n| `loading` | `boolean` | `false` | Show loading indicator |\n| `debounceDelay` | `number` | `300` | Debounce delay in ms |\n| `showClearButton` | `boolean` | `true` | Show clear button |\n| `showSearchIcon` | `boolean` | `true` | Show search icon |\n| `emptyText` | `string` | `'No results found'` | Empty state text |\n| `emptyComponent` | `element` | - | Custom empty component |\n| `primaryColor` | `string` | `'#d9232d'` | Primary/accent color |\n| `disabled` | `boolean` | `false` | Disable the component |\n| `autoFocus` | `boolean` | `false` | Auto focus on mount |\n| `keyboardType` | `string` | `'default'` | Keyboard type |\n| `returnKeyType` | `string` | `'search'` | Return key type |\n| `onSubmitEditing` | `function` | - | Submit callback |\n| `containerStyle` | `ViewStyle` | - | Container style |\n| `searchBarStyle` | `ViewStyle` | - | Search bar style |\n| `inputStyle` | `TextStyle` | - | Input text style |\n| `filtersContainerStyle` | `ViewStyle` | - | Filters container style |\n| `resultsContainerStyle` | `ViewStyle` | - | Results list style |\n| `testID` | `string` | - | Test ID |\n\n---\n\n## 🎨 Customization Examples\n\n### With Filters\n\n```jsx\n<Search\n  placeholder=\"Search products...\"\n  onSearch={handleSearch}\n  results={results}\n  filters={['All', 'Electronics', 'Clothing', 'Home']}\n  onFilterSelect={(filters) => {\n    console.log('Active filters:', filters);\n    // Re-fetch with filters\n  }}\n/>\n```\n\n### With Loading State\n\n```jsx\nconst [loading, setLoading] = useState(false);\n\nconst handleSearch = async (query) => {\n  setLoading(true);\n  const data = await fetchFromAPI(query);\n  setResults(data);\n  setLoading(false);\n};\n\n<Search\n  onSearch={handleSearch}\n  results={results}\n  loading={loading}\n/>\n```\n\n### Custom Result Rendering\n\n```jsx\n<Search\n  onSearch={handleSearch}\n  results={results}\n  renderResult={({ item }) => (\n    <TouchableOpacity style={styles.customResult}>\n      <Image source={{ uri: item.image }} style={styles.image} />\n      <View>\n        <Text style={styles.title}>{item.title}</Text>\n        <Text style={styles.subtitle}>{item.category}</Text>\n      </View>\n      <Text style={styles.price}>${item.price}</Text>\n    </TouchableOpacity>\n  )}\n/>\n```\n\n### Controlled Mode\n\n```jsx\nconst [query, setQuery] = useState('');\nconst [filters, setFilters] = useState([]);\n\n<Search\n  value={query}\n  onChangeText={setQuery}\n  selectedFilters={filters}\n  onFilterSelect={setFilters}\n  results={results}\n/>\n```\n\n### Custom Colors\n\n```jsx\n<Search\n  onSearch={handleSearch}\n  results={results}\n  filters={['All', 'Active', 'Completed']}\n  primaryColor=\"#4CAF50\"\n/>\n```\n\n### No Debounce (Instant Search)\n\n```jsx\n<Search\n  onSearch={handleSearch}\n  results={results}\n  debounceDelay={0}\n/>\n```\n\n---\n\n## 🧪 Test Screen Example\n\n```jsx\nimport React, { useState, useMemo } from 'react';\nimport { View, Text, ScrollView, StyleSheet, SafeAreaView } from 'react-native';\nimport Search from '@atom_design/search';\n\nconst SearchTestScreen = () => {\n  const [query, setQuery] = useState('');\n  const [selectedFilters, setSelectedFilters] = useState([]);\n  const [loading, setLoading] = useState(false);\n  const [basicQuery, setBasicQuery] = useState('');\n\n  // Sample data\n  const allProducts = [\n    { id: '1', label: 'Industrial Safety Helmet', category: 'Safety' },\n    { id: '2', label: 'Work Gloves - Heavy Duty', category: 'Safety' },\n    { id: '3', label: 'Power Drill 20V', category: 'Tools' },\n    { id: '4', label: 'LED Work Light', category: 'Tools' },\n    { id: '5', label: 'Steel Toe Boots', category: 'Footwear' },\n    { id: '6', label: 'Welding Mask Auto-Darkening', category: 'Safety' },\n    { id: '7', label: 'Measuring Tape 25ft', category: 'Tools' },\n    { id: '8', label: 'Safety Goggles', category: 'Safety' },\n    { id: '9', label: 'Cordless Angle Grinder', category: 'Tools' },\n    { id: '10', label: 'Anti-Slip Work Shoes', category: 'Footwear' },\n  ];\n\n  const filters = ['All', 'Safety', 'Tools', 'Footwear'];\n\n  // Filter results for basic search\n  const basicResults = useMemo(() => {\n    if (!basicQuery) return allProducts;\n    return allProducts.filter(item =>\n      item.label.toLowerCase().includes(basicQuery.toLowerCase())\n    );\n  }, [basicQuery]);\n\n  // Filter results based on query and filters\n  const filteredResults = useMemo(() => {\n    let results = allProducts;\n\n    // Apply text search\n    if (query) {\n      results = results.filter(item =>\n        item.label.toLowerCase().includes(query.toLowerCase())\n      );\n    }\n\n    // Apply category filters\n    if (selectedFilters.length > 0 && !selectedFilters.includes('All')) {\n      results = results.filter(item =>\n        selectedFilters.includes(item.category)\n      );\n    }\n\n    return results;\n  }, [query, selectedFilters]);\n\n  // Handle search callback\n  const handleSearch = (searchQuery, activeFilters) => {\n    console.log('Search:', searchQuery, 'Filters:', activeFilters);\n  };\n\n  const handleResultPress = (item) => {\n    console.log('Selected product:', item);\n    // Navigate to product details\n  };\n\n  return (\n    <SafeAreaView style={styles.container}>\n      <ScrollView>\n        <Text style={styles.header}>Atom Design - Search</Text>\n\n        {/* Basic Search */}\n        <View style={styles.section}>\n          <Text style={styles.sectionTitle}>Basic Search</Text>\n          <Search\n            placeholder=\"Search products...\"\n            value={basicQuery}\n            onChangeText={setBasicQuery}\n            onSearch={handleSearch}\n            results={basicResults}\n            onResultPress={handleResultPress}\n          />\n          <Text style={styles.info}>\n            Showing {basicResults.length} of {allProducts.length} products\n          </Text>\n        </View>\n\n        {/* With Filters */}\n        <View style={styles.section}>\n          <Text style={styles.sectionTitle}>Search with Filters</Text>\n          <Search\n            placeholder=\"Search by name...\"\n            value={query}\n            onChangeText={setQuery}\n            onSearch={handleSearch}\n            results={filteredResults}\n            filters={filters}\n            selectedFilters={selectedFilters}\n            onFilterSelect={(newFilters) => setSelectedFilters(newFilters)}\n            onResultPress={handleResultPress}\n          />\n          <Text style={styles.info}>\n            Found {filteredResults.length} results\n            {selectedFilters.length > 0 && ` in ${selectedFilters.join(', ')}`}\n          </Text>\n        </View>\n\n        {/* Loading State */}\n        <View style={styles.section}>\n          <Text style={styles.sectionTitle}>Loading State Demo</Text>\n          <Search\n            placeholder=\"Type to search...\"\n            loading={loading}\n            onSearch={() => {\n              setLoading(true);\n              setTimeout(() => setLoading(false), 1500);\n            }}\n            results={[]}\n            debounceDelay={500}\n          />\n        </View>\n\n        {/* Custom Primary Color */}\n        <View style={styles.section}>\n          <Text style={styles.sectionTitle}>Custom Color</Text>\n          <Search\n            placeholder=\"Search...\"\n            results={filteredResults.slice(0, 3)}\n            filters={['Option A', 'Option B', 'Option C']}\n            primaryColor=\"#2196F3\"\n            onResultPress={handleResultPress}\n          />\n        </View>\n\n        {/* Disabled State */}\n        <View style={styles.section}>\n          <Text style={styles.sectionTitle}>Disabled State</Text>\n          <Search\n            placeholder=\"Search disabled...\"\n            disabled\n            results={[]}\n          />\n        </View>\n\n        {/* Custom Empty State */}\n        <View style={styles.section}>\n          <Text style={styles.sectionTitle}>Custom Empty Message</Text>\n          <Search\n            placeholder=\"Search something...\"\n            value=\"xyz123\"\n            results={[]}\n            emptyText=\"No products match your search. Try different keywords.\"\n          />\n        </View>\n      </ScrollView>\n    </SafeAreaView>\n  );\n};\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    backgroundColor: '#F5F5F5',\n  },\n  header: {\n    fontSize: 24,\n    fontWeight: 'bold',\n    textAlign: 'center',\n    marginVertical: 20,\n    color: '#1A1A1A',\n  },\n  section: {\n    backgroundColor: '#FFFFFF',\n    marginHorizontal: 16,\n    marginBottom: 16,\n    padding: 16,\n    borderRadius: 12,\n    shadowColor: '#000',\n    shadowOffset: { width: 0, height: 2 },\n    shadowOpacity: 0.1,\n    shadowRadius: 4,\n    elevation: 3,\n  },\n  sectionTitle: {\n    fontSize: 18,\n    fontWeight: '600',\n    marginBottom: 12,\n    color: '#1A1A1A',\n  },\n  info: {\n    marginTop: 8,\n    fontSize: 13,\n    color: '#666',\n    fontStyle: 'italic',\n  },\n});\n\nexport default SearchTestScreen;\n```\n\n---\n\n## 📱 Result Item Format\n\nResults should be objects with at least one of these properties:\n\n```javascript\nconst results = [\n  { id: '1', label: 'Product Name' },      // Uses 'label'\n  { id: '2', title: 'Product Title' },     // Uses 'title'\n  { id: '3', name: 'Product' },            // Uses 'name'\n];\n```\n\nFor custom rendering, use the `renderResult` prop.\n\n---\n\n## ♿ Accessibility\n\nThe Search component includes comprehensive accessibility support:\n\n- Search input uses `accessibilityRole=\"search\"`\n- Filter chips use `accessibilityRole=\"tab\"` with selection state\n- Result items use `accessibilityRole=\"button\"`\n- Clear button has `accessibilityLabel=\"Clear search\"`\n- Empty state is announced to screen readers\n\n---\n\n## 📝 TypeScript\n\nFull TypeScript definitions are included:\n\n```typescript\nimport Search, { SearchProps, SearchResultItem } from '@atom_design/search';\n\ninterface Product extends SearchResultItem {\n  price: number;\n  category: string;\n}\n\nconst MySearch: React.FC = () => {\n  const [results, setResults] = useState<Product[]>([]);\n\n  const handleSearch = (query: string, filters: string[]): void => {\n    // Fetch results\n  };\n\n  return (\n    <Search\n      onSearch={handleSearch}\n      results={results}\n      filters={['All', 'Category A']}\n    />\n  );\n};\n```\n\n---\n\n## 📄 License\n\nMIT © Atom Design\n\n---\n\n## 👤 Author\n\n**Atom Design Team**\n\nPart of the Atom Design System for React Native.\n","readmeFilename":"README.md"}