{"_id":"@apps24/ng-select-pro","_rev":"5-2efb872828e26fc812892373757c0fba","name":"@apps24/ng-select-pro","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.1":{"name":"@apps24/ng-select-pro","version":"0.1.1","keywords":["angular","multiselect","dropdown","select","ng-select","ng-select-pro","angular-component","select-all","search","virtual-scroll","accessible"],"author":{"name":"Apurv Patole"},"license":"MIT","_id":"@apps24/ng-select-pro@0.1.1","maintainers":[{"name":"apps24","email":"apurvpatole2@gmail.com"}],"homepage":"https://github.com/your-org/ng-select-pro#readme","bugs":{"url":"https://github.com/your-org/ng-select-pro/issues"},"dist":{"shasum":"44fe40077b91defab2664eb1959ee18b39efa8c9","tarball":"https://registry.npmjs.org/@apps24/ng-select-pro/-/ng-select-pro-0.1.1.tgz","fileCount":29,"integrity":"sha512-eouo4+4aMZftC+YTicxq9K6zvXOSNb7ob08jfE4n+6EhXbVMJa8GmM0tRit6gDM9iHGUkCEDiN7lELdgQXv3pw==","signatures":[{"sig":"MEUCIFxKiQYszm+qaR8pnH0jkNRFgwF9KoSrtXFomgdnpQc1AiEAwz4Ux4BDd7DhR2/X7vhvBfXsApiaiU/HoDxahOGAY9o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":261916},"access":"public","module":"fesm2022/apps24-ng-select-pro.mjs","exports":{".":{"esm":"./esm2022/apps24-ng-select-pro.mjs","types":"./index.d.ts","default":"./fesm2022/apps24-ng-select-pro.mjs","esm2022":"./esm2022/apps24-ng-select-pro.mjs"},"./package.json":{"default":"./package.json"}},"gitHead":"03dc4e7bcea843fcc8b6f52d31e71fc302a5ef9d","typings":"index.d.ts","_npmUser":{"name":"apps24","email":"apurvpatole2@gmail.com"},"repository":{"url":"git+https://github.com/your-org/ng-select-pro.git","type":"git"},"_npmVersion":"10.8.2","description":"A production-ready Angular multiselect dropdown component with search, virtual scroll, keyboard navigation, and full theming support.","directories":{},"sideEffects":false,"_nodeVersion":"18.20.8","dependencies":{"tslib":"^2.6.0"},"_hasShrinkwrap":false,"peerDependencies":{"@angular/cdk":">=8.0.0","@angular/core":">=8.0.0","@angular/forms":">=8.0.0","@angular/common":">=8.0.0","@angular/animations":">=8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/ng-select-pro_0.1.1_1773816446503_0.9120130889575737","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@apps24/ng-select-pro","version":"0.1.2","description":"A production-ready Angular multiselect dropdown component with search, virtual scroll, keyboard navigation, and full theming support.","keywords":["angular","multiselect","dropdown","select","ng-select","ng-select-pro","angular-component","select-all","search","virtual-scroll","accessible"],"repository":{"type":"git","url":"git+https://github.com/your-org/ng-select-pro.git"},"license":"MIT","author":{"name":"Apurv Patole"},"access":"public","peerDependencies":{"@angular/animations":">=8.0.0","@angular/cdk":">=8.0.0","@angular/common":">=8.0.0","@angular/core":">=8.0.0","@angular/forms":">=8.0.0"},"dependencies":{"tslib":"^2.6.0"},"module":"fesm2022/apps24-ng-select-pro.mjs","typings":"index.d.ts","exports":{"./package.json":{"default":"./package.json"},".":{"types":"./index.d.ts","esm2022":"./esm2022/apps24-ng-select-pro.mjs","esm":"./esm2022/apps24-ng-select-pro.mjs","default":"./fesm2022/apps24-ng-select-pro.mjs"}},"sideEffects":false,"_id":"@apps24/ng-select-pro@0.1.2","gitHead":"65d547dd1d92dc18c5da6d08de60822406169ee1","bugs":{"url":"https://github.com/your-org/ng-select-pro/issues"},"homepage":"https://github.com/your-org/ng-select-pro#readme","_nodeVersion":"18.20.8","_npmVersion":"10.8.2","dist":{"integrity":"sha512-jxUwiT/igL2Ent7hhu+MCSFcdb/2x5P5YPtArN+zrvm/wrLNBzuV+UKYfevRLWsyi9qlVH7cgXoILtUW1rmfIA==","shasum":"0b8dd5afa36d0da8993236ce15f29e7de492db4b","tarball":"https://registry.npmjs.org/@apps24/ng-select-pro/-/ng-select-pro-0.1.2.tgz","fileCount":31,"unpackedSize":283613,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC8vaIGSemjIzDADeT2xBMnxceRgxeCi/pEeR1uOfwXMQIhAJrf5fZvkiSpTQksg2ZwCzsjDvun0ZT5yX8VO3SushEb"}]},"_npmUser":{"name":"apps24","email":"apurvpatole2@gmail.com"},"directories":{},"maintainers":[{"name":"apps24","email":"apurvpatole2@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ng-select-pro_0.1.2_1773821689144_0.24063920764629243"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-18T06:47:26.426Z","modified":"2026-03-18T08:14:49.413Z","0.2.0":"2026-03-18T06:27:16.507Z","0.1.1":"2026-03-18T06:47:26.658Z","0.1.2":"2026-03-18T08:14:49.288Z"},"bugs":{"url":"https://github.com/your-org/ng-select-pro/issues"},"author":{"name":"Apurv Patole"},"license":"MIT","homepage":"https://github.com/your-org/ng-select-pro#readme","keywords":["angular","multiselect","dropdown","select","ng-select","ng-select-pro","angular-component","select-all","search","virtual-scroll","accessible"],"repository":{"type":"git","url":"git+https://github.com/your-org/ng-select-pro.git"},"description":"A production-ready Angular multiselect dropdown component with search, virtual scroll, keyboard navigation, and full theming support.","maintainers":[{"name":"apps24","email":"apurvpatole2@gmail.com"}],"readme":"# ng-select-pro\n\n[![npm version](https://img.shields.io/npm/v/@apps24/ng-select-pro.svg)](https://www.npmjs.com/package/@apps24/ng-select-pro)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n[![Angular](https://img.shields.io/badge/Angular-8%2B-red.svg)](https://angular.io)\n[![Build Status](https://github.com/apps24/ng-select-pro/actions/workflows/ci.yml/badge.svg)](https://github.com/apps24/ng-select-pro/actions)\n\nA production-ready Angular multiselect dropdown component with search, virtual scroll, keyboard navigation, group support, and full theming.\n\n---\n\n## Features\n\n- **Multi-select and single-select** modes\n- **Search/filter** with configurable placeholder\n- **Virtual scrolling** (CDK) auto-activated for lists > 100 items\n- **Full keyboard navigation** — ArrowUp/Down, Enter, Escape, Tab\n- **ControlValueAccessor** — works with `ngModel` and `ReactiveFormsModule`\n- **Select all / Deselect all**\n- **Badge display** with overflow indicator (+N)\n- **Group headers** from `option.group`\n- **Disabled options** and disabled component state\n- **Tooltip** support via `option.tooltip`\n- **Loading spinner** state\n- **Dropdown position** — auto (smart), top, or bottom\n- **Angular animations** for smooth open/close\n- **ARIA** roles and attributes for accessibility\n- **CSS custom properties** for complete theming\n- **Tailwind CSS** integration support\n- **Angular Material** theme built-in\n- **Angular 8 – 20+** compatible (partial-Ivy compilation)\n\n---\n\n## Installation\n\n```bash\nnpm install @apps24/ng-select-pro\n```\n\n> ⚠️ **`@angular/cdk` required peer dependency**\n>\n> This library uses `@angular/cdk` for virtual scrolling. If your project does not already have `@angular/cdk` installed, install it first at the **same major version as your Angular** to avoid peer dependency conflicts:\n>\n> ```bash\n> npm install @angular/cdk@16   # for Angular 16\n> npm install @angular/cdk@17   # for Angular 17\n> npm install @angular/cdk@18   # for Angular 18\n> npm install @angular/cdk@19   # for Angular 19\n> npm install @angular/cdk@20   # for Angular 20\n> ```\n>\n> Not sure which version you have? Run `ng version` in your project directory.\n\n---\n\n## Quick Start\n\n### Step 1 — Import the module\n\n**Module-based app (Angular 8–16):**\n```typescript\n// app.module.ts\nimport { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { BrowserAnimationsModule } from '@angular/platform-browser/animations';\nimport { MultiSelectModule } from '@apps24/ng-select-pro';\n\n@NgModule({\n  imports: [\n    BrowserAnimationsModule,  // required for dropdown animation\n    FormsModule,\n    MultiSelectModule\n  ]\n})\nexport class AppModule {}\n```\n\n**Standalone app (Angular 14+):**\n```typescript\n// main.ts\nimport { bootstrapApplication } from '@angular/platform-browser';\nimport { provideAnimations } from '@angular/platform-browser/animations';\nimport { importProvidersFrom } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MultiSelectModule } from '@apps24/ng-select-pro';\n\nbootstrapApplication(AppComponent, {\n  providers: [\n    provideAnimations(),\n    importProvidersFrom(FormsModule, MultiSelectModule)\n  ]\n});\n```\n\n### Step 2 — Use in your component\n\n```typescript\n// app.component.ts\nimport { Component } from '@angular/core';\nimport { IMultiSelectOption } from '@apps24/ng-select-pro';\n\n@Component({\n  selector: 'app-root',\n  templateUrl: './app.component.html'\n})\nexport class AppComponent {\n  selected: IMultiSelectOption[] = [];\n\n  options: IMultiSelectOption[] = [\n    { id: 1, label: 'Angular' },\n    { id: 2, label: 'React' },\n    { id: 3, label: 'Vue' }\n  ];\n}\n```\n\n```html\n<!-- app.component.html -->\n<ng-multiselect\n  [(ngModel)]=\"selected\"\n  [options]=\"options\"\n></ng-multiselect>\n\n<p>Selected: {{ selected | json }}</p>\n```\n\n---\n\n## Complete Real-World Demo\n\nA complete example showing multi-select, single-select, grouped options, reactive forms, max selection, disabled items, and event handling — all in one component.\n\n### Component TypeScript\n\n```typescript\n// user-form.component.ts\nimport { Component, OnInit } from '@angular/core';\nimport { FormBuilder, FormGroup, Validators } from '@angular/forms';\nimport { IMultiSelectOption, IMultiSelectConfig } from '@apps24/ng-select-pro';\n\n@Component({\n  selector: 'app-user-form',\n  templateUrl: './user-form.component.html',\n  styleUrls: ['./user-form.component.scss']\n})\nexport class UserFormComponent implements OnInit {\n\n  form!: FormGroup;\n\n  // ── Skills multi-select ──────────────────────────────────────────────────\n  skillOptions: IMultiSelectOption[] = [\n    { id: 'angular',     label: 'Angular',     group: 'Frontend' },\n    { id: 'react',       label: 'React',       group: 'Frontend' },\n    { id: 'vue',         label: 'Vue.js',      group: 'Frontend' },\n    { id: 'nodejs',      label: 'Node.js',     group: 'Backend'  },\n    { id: 'python',      label: 'Python',      group: 'Backend'  },\n    { id: 'go',          label: 'Go',          group: 'Backend'  },\n    { id: 'postgres',    label: 'PostgreSQL',  group: 'Database' },\n    { id: 'mongo',       label: 'MongoDB',     group: 'Database' },\n    { id: 'redis',       label: 'Redis',       group: 'Database' },\n    { id: 'docker',      label: 'Docker',      group: 'DevOps'   },\n    { id: 'k8s',         label: 'Kubernetes',  group: 'DevOps'   },\n  ];\n\n  skillConfig: Partial<IMultiSelectConfig> = {\n    placeholder: 'Select your skills',\n    searchPlaceholder: 'Search skills...',\n    maxSelect: 5,\n    maxDisplayed: 3,\n    showSelectAll: false,\n    showClearAll: true\n  };\n\n  // ── Country single-select ────────────────────────────────────────────────\n  countryOptions: IMultiSelectOption[] = [\n    { id: 'us', label: 'United States', group: 'Americas' },\n    { id: 'ca', label: 'Canada',        group: 'Americas' },\n    { id: 'gb', label: 'United Kingdom',group: 'Europe'   },\n    { id: 'de', label: 'Germany',       group: 'Europe'   },\n    { id: 'fr', label: 'France',        group: 'Europe'   },\n    { id: 'jp', label: 'Japan',         group: 'Asia'     },\n    { id: 'in', label: 'India',         group: 'Asia'     },\n  ];\n\n  countryConfig: Partial<IMultiSelectConfig> = {\n    mode: 'single',\n    placeholder: 'Select country',\n    closeOnSelect: true,\n    showSelectAll: false,\n    showClearAll: true\n  };\n\n  // ── Role select (disabled items) ─────────────────────────────────────────\n  roleOptions: IMultiSelectOption[] = [\n    { id: 'dev',     label: 'Developer'                                    },\n    { id: 'lead',    label: 'Tech Lead'                                    },\n    { id: 'mgr',     label: 'Engineering Manager'                          },\n    { id: 'arch',    label: 'Architect'                                    },\n    { id: 'cto',     label: 'CTO',     disabled: true, tooltip: 'Contact sales' },\n    { id: 'vp',      label: 'VP Eng',  disabled: true, tooltip: 'Contact sales' },\n  ];\n\n  roleConfig: Partial<IMultiSelectConfig> = {\n    mode: 'single',\n    placeholder: 'Select your role',\n    closeOnSelect: true,\n    showSelectAll: false\n  };\n\n  // ── Event log ─────────────────────────────────────────────────────────────\n  events: string[] = [];\n\n  constructor(private fb: FormBuilder) {}\n\n  ngOnInit(): void {\n    this.form = this.fb.group({\n      name:    ['', Validators.required],\n      skills:  [[], Validators.required],\n      country: [null, Validators.required],\n      role:    [null, Validators.required]\n    });\n  }\n\n  onSkillsChange(selected: IMultiSelectOption[]): void {\n    this.events.unshift(`Skills changed → ${selected.map(s => s.label).join(', ') || 'none'}`);\n  }\n\n  onCountryChange(selected: IMultiSelectOption[]): void {\n    this.events.unshift(`Country changed → ${selected[0]?.label || 'none'}`);\n  }\n\n  onSubmit(): void {\n    if (this.form.valid) {\n      console.log('Form value:', this.form.value);\n      this.events.unshift('Form submitted ✓');\n    }\n  }\n}\n```\n\n### Component Template\n\n```html\n<!-- user-form.component.html -->\n<form [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\" class=\"form\">\n\n  <!-- Name field -->\n  <div class=\"field\">\n    <label>Full Name</label>\n    <input formControlName=\"name\" type=\"text\" placeholder=\"John Doe\" />\n  </div>\n\n  <!-- Skills — multi-select, max 5, grouped, with search -->\n  <div class=\"field\">\n    <label>Skills <small>(max 5)</small></label>\n    <ng-multiselect\n      formControlName=\"skills\"\n      [options]=\"skillOptions\"\n      [config]=\"skillConfig\"\n      (selectionChange)=\"onSkillsChange($event)\"\n    ></ng-multiselect>\n    <small *ngIf=\"form.get('skills')?.invalid && form.get('skills')?.touched\">\n      Please select at least one skill.\n    </small>\n  </div>\n\n  <!-- Country — single-select with groups -->\n  <div class=\"field\">\n    <label>Country</label>\n    <ng-multiselect\n      formControlName=\"country\"\n      [options]=\"countryOptions\"\n      [config]=\"countryConfig\"\n      (selectionChange)=\"onCountryChange($event)\"\n    ></ng-multiselect>\n  </div>\n\n  <!-- Role — single-select with some disabled options -->\n  <div class=\"field\">\n    <label>Role</label>\n    <ng-multiselect\n      formControlName=\"role\"\n      [options]=\"roleOptions\"\n      [config]=\"roleConfig\"\n    ></ng-multiselect>\n  </div>\n\n  <button type=\"submit\" [disabled]=\"form.invalid\">Submit</button>\n\n</form>\n\n<!-- Event log -->\n<div class=\"event-log\" *ngIf=\"events.length\">\n  <h4>Events</h4>\n  <p *ngFor=\"let e of events\">{{ e }}</p>\n</div>\n```\n\n### Component Styles\n\n```scss\n/* user-form.component.scss */\n.form {\n  max-width: 480px;\n  display: flex;\n  flex-direction: column;\n  gap: 20px;\n}\n\n.field {\n  display: flex;\n  flex-direction: column;\n  gap: 6px;\n\n  label {\n    font-weight: 600;\n    font-size: 14px;\n    color: #374151;\n  }\n\n  small {\n    color: #ef4444;\n    font-size: 12px;\n  }\n\n  input {\n    padding: 8px 12px;\n    border: 1px solid #d1d5db;\n    border-radius: 8px;\n    font-size: 14px;\n    outline: none;\n\n    &:focus { border-color: #3b82f6; }\n  }\n}\n\nbutton[type=\"submit\"] {\n  padding: 10px 24px;\n  background: #3b82f6;\n  color: white;\n  border: none;\n  border-radius: 8px;\n  font-size: 14px;\n  cursor: pointer;\n\n  &:disabled { opacity: 0.5; cursor: not-allowed; }\n  &:hover:not(:disabled) { background: #2563eb; }\n}\n\n.event-log {\n  margin-top: 24px;\n  padding: 12px;\n  background: #f8fafc;\n  border-radius: 8px;\n  font-size: 13px;\n  color: #475569;\n}\n```\n\n### Module Registration\n\n```typescript\n// user-form.module.ts  (or add to AppModule)\nimport { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { BrowserAnimationsModule } from '@angular/platform-browser/animations';\nimport { MultiSelectModule } from '@apps24/ng-select-pro';\nimport { UserFormComponent } from './user-form.component';\n\n@NgModule({\n  declarations: [UserFormComponent],\n  imports: [\n    CommonModule,\n    ReactiveFormsModule,\n    BrowserAnimationsModule,\n    MultiSelectModule\n  ],\n  exports: [UserFormComponent]\n})\nexport class UserFormModule {}\n```\n\n---\n\n## More Usage Examples\n\n### ngModel (template-driven form)\n\n```typescript\nselectedFruits: IMultiSelectOption[] = [];\nfruits: IMultiSelectOption[] = [\n  { id: 1, label: 'Apple' },\n  { id: 2, label: 'Banana' },\n  { id: 3, label: 'Cherry' }\n];\n```\n\n```html\n<ng-multiselect [(ngModel)]=\"selectedFruits\" [options]=\"fruits\"></ng-multiselect>\n<p>You selected: {{ selectedFruits.map(o => o.label).join(', ') }}</p>\n```\n\n---\n\n### Single select mode\n\n```html\n<ng-multiselect\n  [(ngModel)]=\"selectedCountry\"\n  [options]=\"countryOptions\"\n  [config]=\"{ mode: 'single', closeOnSelect: true, showSelectAll: false }\"\n></ng-multiselect>\n```\n\n---\n\n### Max selections (e.g. pick up to 3 tags)\n\n```html\n<ng-multiselect\n  [(ngModel)]=\"selectedTags\"\n  [options]=\"tagOptions\"\n  [config]=\"{ maxSelect: 3, placeholder: 'Pick up to 3 tags' }\"\n></ng-multiselect>\n```\n\n---\n\n### Loading state (async options)\n\n```typescript\nisLoading = true;\noptions: IMultiSelectOption[] = [];\n\nngOnInit() {\n  this.api.getOptions().subscribe(data => {\n    this.options = data;\n    this.isLoading = false;\n  });\n}\n```\n\n```html\n<ng-multiselect\n  [(ngModel)]=\"selected\"\n  [options]=\"options\"\n  [config]=\"{ loading: isLoading, loadingText: 'Fetching options...' }\"\n></ng-multiselect>\n```\n\n---\n\n### Custom item renderer (with HTML)\n\n```typescript\nconfig: Partial<IMultiSelectConfig> = {\n  itemRenderer: (opt) => `<strong>${opt.label}</strong> <small style=\"color:#9ca3af\">#${opt.id}</small>`\n};\n```\n\n```html\n<ng-multiselect [(ngModel)]=\"selected\" [options]=\"options\" [config]=\"config\"></ng-multiselect>\n```\n\n---\n\n### Listen to events\n\n```html\n<ng-multiselect\n  [(ngModel)]=\"selected\"\n  [options]=\"options\"\n  (selectionChange)=\"onSelectionChange($event)\"\n  (searchChange)=\"onSearch($event)\"\n  (dropdownOpen)=\"onOpen()\"\n  (dropdownClose)=\"onClose()\"\n></ng-multiselect>\n```\n\n```typescript\nonSelectionChange(selected: IMultiSelectOption[]) {\n  console.log('Selected:', selected);\n}\n\nonSearch(query: string) {\n  // Can be used to trigger remote search\n  console.log('Search query:', query);\n}\n```\n\n---\n\n## Option Interface\n\n```typescript\ninterface IMultiSelectOption {\n  id: any;           // Unique identifier\n  label: string;     // Display text\n  disabled?: boolean;// Prevent selection (greyed out)\n  group?: string;    // Group header label\n  image?: string;    // Image URL shown in option row\n  tooltip?: string;  // Native browser tooltip on hover\n  data?: any;        // Store any extra data (not rendered)\n}\n```\n\n---\n\n## Configuration Reference\n\nAll options are passed via `[config]=\"{ ... }\"`:\n\n| Option | Type | Default | Description |\n|---|---|---|---|\n| `mode` | `'multi' \\| 'single'` | `'multi'` | Selection mode |\n| `searchEnabled` | `boolean` | `true` | Show search input |\n| `searchPlaceholder` | `string` | `'Search...'` | Search input placeholder |\n| `placeholder` | `string` | `'Select options'` | Placeholder when empty |\n| `maxSelect` | `number \\| null` | `null` | Max selections (null = unlimited) |\n| `maxDisplayed` | `number` | `3` | Max badges shown before +N overflow |\n| `disabled` | `boolean` | `false` | Disable entire component |\n| `closeOnSelect` | `boolean` | `false` | Auto-close after each selection |\n| `showSelectAll` | `boolean` | `true` | Show Select All link (multi only) |\n| `showClearAll` | `boolean` | `true` | Show × clear button |\n| `labelRenderer` | `((opt) => string) \\| null` | `null` | Custom badge label function |\n| `itemRenderer` | `((opt) => string) \\| null` | `null` | Custom option HTML (supports HTML) |\n| `noResultsText` | `string` | `'No results found'` | Empty search state text |\n| `loadingText` | `string` | `'Loading...'` | Loading state text |\n| `loading` | `boolean` | `false` | Show loading spinner |\n| `autoClose` | `boolean` | `true` | Close on outside click |\n| `dropdownPosition` | `'auto' \\| 'top' \\| 'bottom'` | `'auto'` | Dropdown direction |\n| `theme` | `IMultiSelectTheme` | — | CSS class overrides per slot |\n\n### Theme object\n\n| Key | Applied to |\n|---|---|\n| `containerClass` | Trigger container div |\n| `dropdownClass` | Dropdown panel div |\n| `searchClass` | Search `<input>` |\n| `itemClass` | Each option row |\n| `selectedItemClass` | Selected option rows |\n| `disabledItemClass` | Disabled option rows |\n| `badgeClass` | Each selected badge |\n| `overflowBadgeClass` | The +N overflow badge |\n| `clearBtnClass` | Clear all × button |\n| `selectAllClass` | Select all row |\n\n---\n\n## Outputs\n\n| Output | Type | When |\n|---|---|---|\n| `selectionChange` | `EventEmitter<IMultiSelectOption[]>` | Selection changes |\n| `searchChange` | `EventEmitter<string>` | User types in search |\n| `dropdownOpen` | `EventEmitter<void>` | Dropdown opens |\n| `dropdownClose` | `EventEmitter<void>` | Dropdown closes |\n\n---\n\n## Global defaults via injection token\n\nSet defaults once for the entire app:\n\n```typescript\nimport { MULTI_SELECT_DEFAULT_CONFIG } from '@apps24/ng-select-pro';\n\n// app.module.ts\nproviders: [\n  {\n    provide: MULTI_SELECT_DEFAULT_CONFIG,\n    useValue: {\n      placeholder: 'Choose...',\n      maxDisplayed: 2,\n      showSelectAll: false\n    }\n  }\n]\n```\n\nOr use `forRoot()`:\n\n```typescript\nMultiSelectModule.forRoot({\n  placeholder: 'Choose...',\n  maxDisplayed: 2,\n  showSelectAll: false\n})\n```\n\n---\n\n## Theming\n\n### CSS Custom Properties\n\nOverride any visual value on `:root` or a parent selector:\n\n```css\n:root {\n  --ng-select-border: 1px solid #6366f1;\n  --ng-select-border-radius: 12px;\n  --ng-select-badge-bg: #eef2ff;\n  --ng-select-badge-text: #4f46e5;\n  --ng-select-item-hover-bg: #eef2ff;\n  --ng-select-item-selected-bg: #e0e7ff;\n  --ng-select-item-selected-text: #3730a3;\n  --ng-select-font-size: 13px;\n  --ng-select-max-height: 320px;\n}\n```\n\n| Variable | Default | Purpose |\n|---|---|---|\n| `--ng-select-border` | `1px solid #d1d5db` | Container border |\n| `--ng-select-border-radius` | `8px` | Corner radius |\n| `--ng-select-bg` | `#ffffff` | Container background |\n| `--ng-select-text` | `#111827` | Text color |\n| `--ng-select-placeholder` | `#9ca3af` | Placeholder color |\n| `--ng-select-dropdown-bg` | `#ffffff` | Dropdown background |\n| `--ng-select-dropdown-shadow` | subtle shadow | Dropdown elevation |\n| `--ng-select-item-hover-bg` | `#f9fafb` | Hovered option bg |\n| `--ng-select-item-selected-bg` | `#eff6ff` | Selected option bg |\n| `--ng-select-item-selected-text` | `#1d4ed8` | Selected option text |\n| `--ng-select-badge-bg` | `#dbeafe` | Badge background |\n| `--ng-select-badge-text` | `#1e40af` | Badge text |\n| `--ng-select-badge-radius` | `4px` | Badge corner radius |\n| `--ng-select-search-border` | `1px solid #e5e7eb` | Search input border |\n| `--ng-select-disabled-opacity` | `0.5` | Disabled opacity |\n| `--ng-select-font-size` | `14px` | Base font size |\n| `--ng-select-max-height` | `280px` | Dropdown max height |\n\n### Tailwind CSS\n\nSee [Tailwind Integration Guide](https://github.com/apps24/ng-select-pro/blob/main/docs/tailwind-integration.md).\n\n### Angular Material\n\nAdd `.ng-select-material` class to the host:\n\n```html\n<ng-multiselect class=\"ng-select-material\" ...></ng-multiselect>\n```\n\nSee [Angular Material Integration Guide](https://github.com/apps24/ng-select-pro/blob/main/docs/material-integration.md).\n\n---\n\n## Keyboard Navigation\n\n| Key | Action |\n|---|---|\n| `↓` ArrowDown | Open dropdown / move focus down |\n| `↑` ArrowUp | Move focus up |\n| `Enter` | Open dropdown / select focused option |\n| `Escape` | Close dropdown |\n| `Tab` | Close dropdown and move focus |\n\n---\n\n## Contributing\n\n1. Fork the repo\n2. Create a feature branch: `git checkout -b feature/my-feature`\n3. Make your changes with tests\n4. Run tests: `npm test`\n5. Run lint: `npm run lint`\n6. Submit a PR against `main`\n\n### Development Setup\n\n```bash\ngit clone https://github.com/apps24/ng-select-pro.git\ncd ng-select-pro\nnpm install\nnpm run build:lib    # Build the library\nnpm start            # Start demo app at localhost:4200\nnpm test             # Run library unit tests\n```\n\n---\n\n## License\n\nMIT © apps24\n","readmeFilename":"README.md"}