{"_id":"@atom_design/menu","name":"@atom_design/menu","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@atom_design/menu","version":"1.0.0","description":"A React Native dropdown menu component with search, radio, checkbox, and chips support. Part of the Atom Design System.","main":"index.js","types":"index.d.ts","author":{"name":"Atom Design"},"license":"MIT","keywords":["react-native","menu","dropdown","select","checkbox","radio","chips","filter","ui-component","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/menu@1.0.0","_nodeVersion":"20.19.5","_npmVersion":"10.8.2","dist":{"integrity":"sha512-r81kJQoIq0JqlKp8udJ/wV5a0l46n0R81Pm9Es5hWfkK+zA7CGW7xAJm4qPAwdyXigacVrci5wS2M34WUF9yAA==","shasum":"78e8dc46faf0c904770bbf7bc21e51625b5f601c","tarball":"https://registry.npmjs.org/@atom_design/menu/-/menu-1.0.0.tgz","fileCount":5,"unpackedSize":38566,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC7oa17nlm6iEtZmX5xjDJ1220LxyP0yhLt3Wl+kxVgWwIhAOb7yUg+QWBc/ZXIuevPPTG69XDwSXbaSu73MWj3+mUZ"}]},"_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/menu_1.0.0_1764753237755_0.48375447863959486"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-03T09:13:57.691Z","1.0.0":"2025-12-03T09:13:57.959Z","modified":"2025-12-03T09:13:58.227Z"},"maintainers":[{"name":"moglix","email":"devops@moglix.com"},{"name":"avi-moglix","email":"avi.gupta@moglix.com"}],"description":"A React Native dropdown menu component with search, radio, checkbox, and chips support. Part of the Atom Design System.","keywords":["react-native","menu","dropdown","select","checkbox","radio","chips","filter","ui-component","atom-design"],"author":{"name":"Atom Design"},"license":"MIT","readme":"# @atom_design/menu\n\nA React Native dropdown menu component with search, radio, checkbox, and chips support. Part of the Atom Design System.\n\n[![npm version](https://img.shields.io/npm/v/@atom_design/menu.svg)](https://www.npmjs.com/package/@atom_design/menu)\n[![license](https://img.shields.io/npm/l/@atom_design/menu.svg)](https://github.com/atom-design/menu/blob/main/LICENSE)\n\n## Features\n\n- 🔍 **Searchable** - Built-in search functionality\n- 🎯 **Radio Select** - Single selection with radio buttons\n- ☑️ **Checkbox** - Multi-select with \"Select All\" option\n- 🏷️ **Chips** - Visual chip tags for selections\n- 🔢 **Input Mode** - Two input fields with footer actions\n- 🎨 **Customizable** - Style all elements with custom props\n- ♿ **Accessible** - Full screen reader support\n- 💪 **TypeScript** - Full type definitions included\n\n---\n\n## 📦 Installation\n\n```bash\nnpm install @atom_design/menu\n# or\nyarn add @atom_design/menu\n```\n\n### Peer Dependencies\n\n```bash\nnpm install prop-types react-native-vector-icons\n```\n\n---\n\n## 🚀 Basic Usage\n\n```jsx\nimport React, { useState } from 'react';\nimport { View } from 'react-native';\nimport Menu from '@atom_design/menu';\n\nconst App = () => {\n  const [selected, setSelected] = useState('');\n\n  const options = [\n    { label: 'Apple', value: 'apple' },\n    { label: 'Banana', value: 'banana' },\n    { label: 'Cherry', value: 'cherry' },\n  ];\n\n  return (\n    <View style={{ flex: 1, padding: 20 }}>\n      <Menu\n        label=\"Select Fruit\"\n        type=\"searchRadio\"\n        options={options}\n        onSelect={setSelected}\n      />\n    </View>\n  );\n};\n\nexport default App;\n```\n\n---\n\n## 🧩 Menu Types\n\n### Search + Radio (Single Select)\n```jsx\n<Menu\n  label=\"Country\"\n  type=\"searchRadio\"\n  options={countries}\n  onSelect={(value) => setCountry(value)}\n/>\n```\n\n### Search + Checkbox (Multi-Select)\n```jsx\n<Menu\n  label=\"Skills\"\n  type=\"searchCheckbox\"\n  options={skills}\n  showCheckAll={true}\n  checkAllLabel=\"Select All Skills\"\n  onSelect={(values) => setSelectedSkills(values)}\n/>\n```\n\n### Search + Chips Checkbox\n```jsx\n<Menu\n  label=\"Tags\"\n  type=\"searchChipsCheckbox\"\n  options={tagOptions}\n  chips={selectedChips}\n  onSelect={(values) => setSelectedValues(values)}\n  onAddChip={(chip) => setChips([...chips, chip])}\n  onRemoveChip={(chip) => setChips(chips.filter(c => c !== chip))}\n/>\n```\n\n### Input with Footer\n```jsx\n<Menu\n  label=\"Price Range\"\n  type=\"inputFooter\"\n  inputLabels={['Min Price', 'Max Price']}\n  inputPlaceholders={['₹0', '₹10,000']}\n  applyButtonText=\"Apply Filter\"\n  cancelButtonText=\"Reset\"\n  onApply={(data) => console.log(data.input1, data.input2)}\n  onCancel={() => console.log('Cancelled')}\n/>\n```\n\n---\n\n## 📋 Props\n\n| Prop | Type | Default | Description |\n|------|------|---------|-------------|\n| `label` | `string` | - | Label above trigger |\n| `triggerText` | `string` | - | Trigger button text |\n| `type` | `string` | `'searchRadio'` | Menu type |\n| `options` | `Option[]` | `[]` | Array of options |\n| `chips` | `string[]` | `[]` | Chips for chips mode |\n| `value` | `string \\| array` | - | Controlled value |\n| `onSelect` | `function` | - | Selection callback |\n| `onAddChip` | `function` | - | Add chip callback |\n| `onRemoveChip` | `function` | - | Remove chip callback |\n| `onApply` | `function` | - | Apply callback (inputFooter) |\n| `onCancel` | `function` | - | Cancel callback |\n| `placeholder` | `string` | `'Search...'` | Search placeholder |\n| `disabled` | `boolean` | `false` | Disable menu |\n| `searchable` | `boolean` | `true` | Show search bar |\n| `showCheckAll` | `boolean` | `true` | Show \"Select All\" |\n| `checkAllLabel` | `string` | `'Select All'` | \"Select All\" text |\n| `applyButtonText` | `string` | `'Apply'` | Apply button text |\n| `cancelButtonText` | `string` | `'Cancel'` | Cancel button text |\n| `inputLabels` | `[string, string]` | `['Min Value', 'Max Value']` | Input labels |\n| `inputPlaceholders` | `[string, string]` | `['Enter min', 'Enter max']` | Input placeholders |\n| `containerStyle` | `ViewStyle` | - | Container style |\n| `triggerStyle` | `ViewStyle` | - | Trigger style |\n| `menuStyle` | `ViewStyle` | - | Menu popup style |\n| `testID` | `string` | - | Test ID |\n\n---\n\n## 📁 Option Structure\n\n```typescript\ninterface MenuOption {\n  label: string;        // Display text\n  value: string | number; // Value returned on selection\n}\n```\n\n---\n\n## 🧪 Test Screen Example\n\n```jsx\nimport React, { useState } from 'react';\nimport { SafeAreaView, ScrollView, Text, StyleSheet, View } from 'react-native';\nimport Menu from '@atom_design/menu';\n\nconst options = [\n  { label: 'Apple', value: 'apple' },\n  { label: 'Banana', value: 'banana' },\n  { label: 'Cherry', value: 'cherry' },\n  { label: 'Orange', value: 'orange' },\n  { label: 'Mango', value: 'mango' },\n];\n\nconst MenuTestScreen = () => {\n  const [radioValue, setRadioValue] = useState('');\n  const [checkboxValues, setCheckboxValues] = useState([]);\n  const [chips, setChips] = useState(['Apple', 'Banana']);\n  const [chipsValues, setChipsValues] = useState(['apple', 'banana']);\n  const [inputResult, setInputResult] = useState(null);\n\n  return (\n    <SafeAreaView style={styles.container}>\n      <ScrollView contentContainerStyle={styles.content}>\n        <Text style={styles.header}>@atom_design/menu</Text>\n\n        {/* Radio Select */}\n        <Menu\n          label=\"Single Select (Radio)\"\n          triggerText={radioValue || 'Select a fruit'}\n          type=\"searchRadio\"\n          options={options}\n          onSelect={setRadioValue}\n        />\n\n        {/* Checkbox Multi-Select */}\n        <View style={styles.spacing} />\n        <Menu\n          label=\"Multi Select (Checkbox)\"\n          triggerText={\n            checkboxValues.length > 0\n              ? `${checkboxValues.length} selected`\n              : 'Select fruits'\n          }\n          type=\"searchCheckbox\"\n          options={options}\n          showCheckAll={true}\n          onSelect={setCheckboxValues}\n        />\n\n        {/* Chips Checkbox */}\n        <View style={styles.spacing} />\n        <Menu\n          label=\"Chips Select\"\n          triggerText=\"Select with chips\"\n          type=\"searchChipsCheckbox\"\n          options={options}\n          chips={chips}\n          value={chipsValues}\n          onSelect={setChipsValues}\n          onAddChip={(chip) => {\n            if (!chips.includes(chip)) {\n              setChips([...chips, chip]);\n            }\n          }}\n          onRemoveChip={(chip) => setChips(chips.filter(c => c !== chip))}\n        />\n\n        {/* Input Footer */}\n        <View style={styles.spacing} />\n        <Menu\n          label=\"Quantity Range\"\n          triggerText={\n            inputResult\n              ? `${inputResult.input1} - ${inputResult.input2}`\n              : 'Set range'\n          }\n          type=\"inputFooter\"\n          inputLabels={['Minimum', 'Maximum']}\n          inputPlaceholders={['0', '100']}\n          applyButtonText=\"Apply\"\n          cancelButtonText=\"Cancel\"\n          onApply={setInputResult}\n          onCancel={() => setInputResult(null)}\n        />\n\n        {/* Disabled */}\n        <View style={styles.spacing} />\n        <Menu\n          label=\"Disabled Menu\"\n          triggerText=\"Cannot open\"\n          type=\"searchRadio\"\n          options={options}\n          disabled\n        />\n\n        {/* Results */}\n        <View style={styles.results}>\n          <Text style={styles.resultsTitle}>Current Values:</Text>\n          <Text>Radio: {radioValue || 'None'}</Text>\n          <Text>Checkbox: {checkboxValues.join(', ') || 'None'}</Text>\n          <Text>Chips: {chips.join(', ') || 'None'}</Text>\n          <Text>\n            Range: {inputResult ? `${inputResult.input1} - ${inputResult.input2}` : 'None'}\n          </Text>\n        </View>\n      </ScrollView>\n    </SafeAreaView>\n  );\n};\n\nconst styles = StyleSheet.create({\n  container: {\n    flex: 1,\n    backgroundColor: '#f5f5f5',\n  },\n  content: {\n    padding: 20,\n  },\n  header: {\n    fontSize: 24,\n    fontWeight: 'bold',\n    textAlign: 'center',\n    marginBottom: 24,\n    color: '#333',\n  },\n  spacing: {\n    height: 16,\n  },\n  results: {\n    marginTop: 32,\n    padding: 16,\n    backgroundColor: '#fff',\n    borderRadius: 8,\n    borderWidth: 1,\n    borderColor: '#eee',\n  },\n  resultsTitle: {\n    fontSize: 16,\n    fontWeight: '600',\n    marginBottom: 12,\n    color: '#333',\n  },\n});\n\nexport default MenuTestScreen;\n```\n\n---\n\n## 📝 TypeScript\n\nFull TypeScript support included:\n\n```tsx\nimport Menu, { MenuOption, MenuProps } from '@atom_design/menu';\n\nconst options: MenuOption[] = [\n  { label: 'Option 1', value: 'opt1' },\n  { label: 'Option 2', value: 'opt2' },\n];\n\n<Menu\n  type=\"searchCheckbox\"\n  options={options}\n  onSelect={(values) => console.log(values as string[])}\n/>\n```\n\n---\n\n## ♿ Accessibility\n\nThe component includes full accessibility support:\n\n- Proper `accessibilityRole` on all interactive elements\n- `accessibilityState` for checked/expanded states\n- Descriptive labels for screen readers\n- Keyboard navigation support\n\n---\n\n## 👤 Author\n\nAtom Design Team\n\n---\n\n## 📄 License\n\nMIT © [Atom Design](https://github.com/atom-design)\n","readmeFilename":"README.md","_rev":"1-8bfeb404b09cd89ee17a99453f5478d1"}