{"_id":"@avoraui/av-dual-list-box","_rev":"6-0057bb1d040a61cf6516e787431787eb","name":"@avoraui/av-dual-list-box","dist-tags":{"latest":"0.0.5"},"versions":{"0.0.2":{"name":"@avoraui/av-dual-list-box","version":"0.0.2","keywords":["angular","dual-list","list-box","selection"],"author":{"name":"Dileesha Ekanayake"},"license":"MIT","_id":"@avoraui/av-dual-list-box@0.0.2","maintainers":[{"name":"avoraui","email":"dileesha65@gmail.com"}],"dist":{"shasum":"4c1441b00a60175b953c57195f17ebad392ee41c","tarball":"https://registry.npmjs.org/@avoraui/av-dual-list-box/-/av-dual-list-box-0.0.2.tgz","fileCount":7,"integrity":"sha512-x7tcvMLXObStffiF6mymb01F8mkvWlUPlA6SzwaTuQnF/7GGeZJ1QO/2oBi65rcLFVf/38Xy5zsSsCVulB3WqA==","signatures":[{"sig":"MEYCIQC+6b09xE6EhpbdAg9QgvBD2uXW+86P8Ru+W1+uxYDrjgIhAMMtUwCBrclHE3NTlzup/Zi/KQ6QpXqu0R+UXyYOvueu","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":86917},"module":"fesm2022/avoraui-av-dual-list-box.mjs","exports":{".":{"types":"./index.d.ts","default":"./fesm2022/avoraui-av-dual-list-box.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"580cd1a8bbb253d89d483fab183305e9412ff78a","typings":"index.d.ts","_npmUser":{"name":"avoraui","email":"dileesha65@gmail.com"},"_npmVersion":"10.9.0","description":"A customizable Angular dual list box component for managing item selections.","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","dependencies":{"tslib":"^2.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":"^20.1.0","@angular/common":"^20.1.0"},"_npmOperationalInternal":{"tmp":"tmp/av-dual-list-box_0.0.2_1753277751851_0.3800063186164657","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@avoraui/av-dual-list-box","version":"0.0.3","keywords":["angular","dual-list","list-box","selection"],"author":{"name":"Dileesha Ekanayake"},"license":"MIT","_id":"@avoraui/av-dual-list-box@0.0.3","maintainers":[{"name":"avoraui","email":"dileesha65@gmail.com"}],"dist":{"shasum":"2c69e843922311d7923f7d52c2c4b474b8840733","tarball":"https://registry.npmjs.org/@avoraui/av-dual-list-box/-/av-dual-list-box-0.0.3.tgz","fileCount":7,"integrity":"sha512-2J/g6q0auVCU/JNumxlWdRXBSFE/eqW7HtTt8zVNJJMnzWnW1ojg9SAXZrjPTMlmTugmjkjLBs2s1Iv5CRPXVQ==","signatures":[{"sig":"MEQCIF1oGwLSFe0nFce4D9Ix8Xx3plkYIZqyPDv864cwev87AiAkaLQstnCjDUwPZTLYDfb+IjfWLZ5cyxd97Cl4iSTuPQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":139014},"module":"fesm2022/avoraui-av-dual-list-box.mjs","exports":{".":{"types":"./index.d.ts","default":"./fesm2022/avoraui-av-dual-list-box.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"580cd1a8bbb253d89d483fab183305e9412ff78a","typings":"index.d.ts","_npmUser":{"name":"avoraui","email":"dileesha65@gmail.com"},"_npmVersion":"10.9.0","description":"A customizable Angular dual list box component for managing item selections.","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","dependencies":{"tslib":"^2.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":"^20.1.0","@angular/common":"^20.1.0"},"_npmOperationalInternal":{"tmp":"tmp/av-dual-list-box_0.0.3_1753278408846_0.5446413015662959","host":"s3://npm-registry-packages-npm-production"}},"0.0.4":{"name":"@avoraui/av-dual-list-box","version":"0.0.4","keywords":["angular","dual-list","list-box","selection"],"author":{"name":"Dileesha Ekanayake"},"license":"MIT","_id":"@avoraui/av-dual-list-box@0.0.4","maintainers":[{"name":"avoraui","email":"dileesha65@gmail.com"}],"dist":{"shasum":"5b7228fdfbb5759ddf7530ed9b688feb8772b752","tarball":"https://registry.npmjs.org/@avoraui/av-dual-list-box/-/av-dual-list-box-0.0.4.tgz","fileCount":7,"integrity":"sha512-K79uY9YvU93Obv4eTjBTInlYCwkjyTTj0LCcy7DAWbKBHcdG4HEs1Vrx5cy1YIox82Lt7e7JA51ZBMlYm7wyPA==","signatures":[{"sig":"MEUCIHIxV9uFH5Ij529kyPphp5/LI1+Z8Au4MGw93SCBrLzZAiEA5uru+Ii/53bY9/Ml8qLBUY1LHkuVHlcUCtyQao9W+cs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":86968},"module":"fesm2022/avoraui-av-dual-list-box.mjs","exports":{".":{"types":"./index.d.ts","default":"./fesm2022/avoraui-av-dual-list-box.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"fa5b28e4453e891f9295a417d65fe917753f837f","typings":"index.d.ts","_npmUser":{"name":"avoraui","email":"dileesha65@gmail.com"},"_npmVersion":"10.9.0","description":"A customizable Angular dual list box component for managing item selections.","directories":{},"sideEffects":false,"_nodeVersion":"22.12.0","dependencies":{"tslib":"^2.3.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/core":"^20.1.0","@angular/common":"^20.1.0"},"_npmOperationalInternal":{"tmp":"tmp/av-dual-list-box_0.0.4_1753431843859_0.8061870738678818","host":"s3://npm-registry-packages-npm-production"}},"0.0.5":{"name":"@avoraui/av-dual-list-box","version":"0.0.5","description":"A customizable Angular dual list box component for managing item selections.","keywords":["angular","dual-list","list-box","selection"],"author":{"name":"Dileesha Ekanayake"},"license":"MIT","peerDependencies":{"@angular/common":"^20.1.0","@angular/core":"^20.1.0"},"dependencies":{"tslib":"^2.3.0"},"sideEffects":false,"publishConfig":{"access":"public"},"module":"fesm2022/avoraui-av-dual-list-box.mjs","typings":"index.d.ts","exports":{"./package.json":{"default":"./package.json"},".":{"types":"./index.d.ts","default":"./fesm2022/avoraui-av-dual-list-box.mjs"}},"_id":"@avoraui/av-dual-list-box@0.0.5","gitHead":"fa5b28e4453e891f9295a417d65fe917753f837f","_nodeVersion":"22.12.0","_npmVersion":"10.9.0","dist":{"integrity":"sha512-EXdP0cYdDDb9ihFqw0X9I5hzy66nY7Tqx+ALPmNeuwEcrC1qo/6EloYLosfI0QAXIwm0pY564EmvaDQsnmEB7Q==","shasum":"87bfe304356cca67d11364916120c49bbf82b945","tarball":"https://registry.npmjs.org/@avoraui/av-dual-list-box/-/av-dual-list-box-0.0.5.tgz","fileCount":8,"unpackedSize":133676,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDbHwdnZJRpx2AdUKZWHUVpH7HoTV/+wakOAI8Jvx/dXgIgVDqDMQA6ml/MyF+ttHHk7LPXg3FwRv8829HMhqP3GjE="}]},"_npmUser":{"name":"avoraui","email":"dileesha65@gmail.com"},"directories":{},"maintainers":[{"name":"avoraui","email":"dileesha65@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/av-dual-list-box_0.0.5_1753433130800_0.6217277871433466"},"_hasShrinkwrap":false}},"time":{"created":"2025-07-23T13:35:51.674Z","modified":"2025-07-25T08:45:31.294Z","0.0.1":"2025-07-23T13:16:32.550Z","0.0.2":"2025-07-23T13:35:52.067Z","0.0.3":"2025-07-23T13:46:49.044Z","0.0.4":"2025-07-25T08:24:04.027Z","0.0.5":"2025-07-25T08:45:31.126Z"},"author":{"name":"Dileesha Ekanayake"},"license":"MIT","keywords":["angular","dual-list","list-box","selection"],"description":"A customizable Angular dual list box component for managing item selections.","maintainers":[{"name":"avoraui","email":"dileesha65@gmail.com"}],"readme":"# AvDualListBox Component (AvoraUI)\r\n\r\nA customizable Angular dual list box component that allows users to move items between two lists with search functionality. This component implements Angular's `ControlValueAccessor` interface, making it fully compatible with reactive forms.\r\n\r\n## Features\r\n\r\n- ✅ **Dual List Support**: Move items between source and destination lists\r\n- ✅ **Search Functionality**: Filter items in both source and destination lists\r\n- ✅ **Reactive Forms Integration**: Full support for Angular reactive forms\r\n- ✅ **Material Design**: Built with Angular Material components\r\n- ✅ **Dynamic Display**: Customizable display property for list items\r\n- ✅ **Selection Management**: Supports multi-selection and bulk move operations\r\n- ✅ **Memory Management**: Maintains original lists for filtering and resets\r\n\r\n## Dependencies\r\n\r\nThis component requires the following Angular Material modules:\r\n\r\n```typescript\r\nimport { MatCard } from \"@angular/material/card\";\r\nimport { MatButton } from \"@angular/material/button\";\r\nimport { MatIcon } from '@angular/material/icon';\r\nimport { MatListOption, MatSelectionList } from \"@angular/material/list\";\r\nimport { MatFormField, MatLabel } from \"@angular/material/form-field\";\r\nimport { MatInput } from \"@angular/material/input\";\r\n```\r\n\r\n## Installation\r\n\r\n1. Ensure you have Angular Material installed in your project\r\n2. Import the component in your module or use it directly (standalone component)\r\n\r\n## Usage\r\n\r\n### Basic Usage\r\n\r\n```html\r\n<av-dual-list-box \r\n  [sourceList]=\"sourceItems\"\r\n  [displayProperty]=\"'name'\">\r\n</av-dual-list-box>\r\n```\r\n\r\n### With Reactive Forms\r\n\r\n```typescript\r\n// Component\r\nexport class MyComponent {\r\n  listForm = this.fb.group({\r\n    selectedItems: [[]]\r\n  });\r\n\r\n  sourceItems = [{ id: 1, name: 'Item 1' }, { id: 2, name: 'Item 2' }];\r\n\r\n  constructor(private fb: FormBuilder) {}\r\n}\r\n```\r\n\r\n```html\r\n<!-- Template -->\r\n<form [formGroup]=\"listForm\">\r\n  <av-dual-list-box \r\n    formControlName=\"selectedItems\"\r\n    [sourceList]=\"sourceItems\"\r\n    [displayProperty]=\"'name'\">\r\n  </av-dual-list-box>\r\n</form>\r\n```\r\n\r\n## Input Properties\r\n\r\n| Property | Type | Required | Default | Description |\r\n|----------|------|----------|---------|-------------|\r\n| `sourceList` | `T[]` | Yes | `[]` | Array of items for the source list |\r\n| `destinationObjectReference` | `string[]` | No | `[]` | Reference path for nested object properties |\r\n| `displayProperty` | `keyof T | ''` | No | Property to display for each item |\r\n\r\n## Component Behavior\r\n\r\n### Item Selection\r\n- Select items in either list using the Material selection list\r\n- Move selected items between source and destination lists with arrow buttons\r\n\r\n### Search Functionality\r\n- Filter source and destination lists using the search inputs\r\n- Dynamic filtering based on the `displayProperty`\r\n\r\n### Item Management\r\n- **Move**: Transfer selected items between lists\r\n- **Move All**: Transfer all items between lists\r\n- **Reset**: Maintains original lists for filtering purposes\r\n\r\n### Form Integration\r\nThe component outputs an array of selected items, making it easy to:\r\n- Store in databases\r\n- Send via API calls\r\n- Integrate with form validation\r\n\r\n## Data Format\r\n\r\nThe component handles data as an array of objects:\r\n\r\n**Output**: Array of selected items from the destination list\r\n**Input**: Array of items to initialize the destination list\r\n\r\n### Item Type Detection\r\nThe component uses the `displayProperty` to determine how to display items.\r\n\r\n## Error Handling\r\n\r\nThe component includes basic error handling for:\r\n- Invalid `displayProperty` (falls back to 'No Such Property')\r\n- Empty source list (displays no items)\r\n\r\n## Memory Management\r\n\r\nThe component automatically:\r\n- Maintains original lists for filtering\r\n- Updates lists dynamically without memory leaks\r\n\r\n## Styling\r\n\r\nThe component uses CSS classes that can be customized:\r\n\r\n- `.listbox-container` - Main container\r\n- `.source-list` - Source list container\r\n- `.destination-list` - Destination list container\r\n- `.button-panel` - Button panel container\r\n\r\n## Browser Compatibility\r\n\r\nThis component uses modern browser APIs:\r\n- Angular Material components\r\n- Reactive Forms API\r\n\r\nEnsure your target browsers support these features or include appropriate polyfills.\r\n\r\n## Example Implementation\r\n\r\n```typescript\r\n// app.component.ts\r\nimport { Component } from '@angular/core';\r\nimport { FormBuilder, FormGroup } from '@angular/forms';\r\n\r\n@Component({\r\n  selector: 'app-root',\r\n  template: `\r\n    <form [formGroup]=\"listForm\">\r\n      <av-dual-list-box \r\n        formControlName=\"selectedItems\"\r\n        [sourceList]=\"sourceItems\"\r\n        [displayProperty]=\"'name'\">\r\n      </av-dual-list-box>\r\n      \r\n      <button (click)=\"onSubmit()\" [disabled]=\"!listForm.valid\">\r\n        Submit\r\n      </button>\r\n    </form>\r\n  `\r\n})\r\nexport class AppComponent {\r\n  sourceItems = [\r\n    { id: 1, name: 'Item 1' },\r\n    { id: 2, name: 'Item 2' },\r\n    { id: 3, name: 'Item 3' }\r\n  ];\r\n  \r\n  listForm: FormGroup = this.fb.group({\r\n    selectedItems: [[]]\r\n  });\r\n\r\n  constructor(private fb: FormBuilder) {}\r\n\r\n  onSubmit() {\r\n    const selectedItems = this.listForm.get('selectedItems')?.value;\r\n    console.log('Selected items:', selectedItems);\r\n  }\r\n}\r\n```\r\n\r\n## Requirements\r\n\r\n- Angular 20+\r\n- Angular Material\r\n- Lodash (for `isEqual` utility)\r\n\r\n## Browser Support\r\n\r\n- Chrome/Edge 17+\r\n- Firefox 52+\r\n- Safari 10.1+\r\n\r\n## License\r\n\r\nThis project is licensed under the MIT License - see the LICENSE file for details.\r\n\r\n## Changelog\r\n\r\n### v0.0.5\r\n- Initial release\r\n- Basic dual list functionality\r\n- Search and filter support\r\n- Reactive forms integration\r\n- Material design implementation\r\n","readmeFilename":"README.md"}