{"version":3,"file":"ngx-searchable-select.mjs","sources":["../../../projects/ngx-searchable-select/src/lib/ngx-searchable-select.component.ts","../../../projects/ngx-searchable-select/src/public-api.ts","../../../projects/ngx-searchable-select/src/ngx-searchable-select.ts"],"sourcesContent":["import { AsyncPipe } from '@angular/common';\nimport { Component, Input, OnChanges, OnInit, Optional, Self, ViewEncapsulation } from '@angular/core';\nimport { MatError, MatFormField, MatFormFieldAppearance, MatHint, MatLabel, MatSuffix } from '@angular/material/form-field';\nimport { MatOption, MatSelect, MatSelectChange } from '@angular/material/select';\nimport { MatInput } from '@angular/material/input';\nimport { ControlValueAccessor, FormControl, NgControl, ReactiveFormsModule } from '@angular/forms';\nimport { MatIconButton } from '@angular/material/button';\nimport { MatIcon } from '@angular/material/icon';\nimport { map, startWith } from 'rxjs';\nimport { MatProgressSpinner } from '@angular/material/progress-spinner';\nimport { MatTooltip } from '@angular/material/tooltip';\n\ntype StringOrRecord = string | Record<string, any>;\n\n@Component({\n  selector: 'ngx-searchable-select',\n  standalone: true,\n  imports: [\n    MatSelect,\n    MatFormField,\n    MatInput,\n    MatIconButton,\n    MatIcon,\n    ReactiveFormsModule,\n    AsyncPipe,\n    MatProgressSpinner,\n    MatTooltip,\n    MatLabel,\n    MatOption,\n    MatHint,\n    MatError,\n    MatSuffix\n  ],\n  template: `\n    <mat-form-field class=\"search-select\" [appearance]=\"appearance\">\n      @if (!options) {\n        <mat-spinner\n          matPrefix\n          [diameter]=\"25\"\n          class=\"loading\"\n          matTooltip=\"Loading data...\"\n        ></mat-spinner>\n      }\n      <mat-label>{{ label }}</mat-label>\n      <mat-select\n        disableRipple\n        (selectionChange)=\"onSelectionChange($event)\"\n        [formControl]=\"_value\"\n        >\n        <mat-option class=\"search\">\n          <mat-form-field\n            (click)=\"$event.stopPropagation()\"\n            [appearance]=\"appearance\"\n            subscriptSizing=\"dynamic\"\n            >\n            <input\n              matInput\n              placeholder=\"Search {{ label }}...\"\n              [formControl]=\"searchText\"\n              (keydown)=\"$event.stopPropagation()\"\n              />\n            <button\n              color=\"primary\"\n              mat-icon-button\n              matSuffix\n              (click)=\"$event.stopPropagation(); searchText.reset()\"\n              matTooltip=\"Clear Search\"\n              >\n              <mat-icon>clear</mat-icon>\n            </button>\n            <mat-hint>{{(filteredOptions$ | async)?.length}} results found</mat-hint>\n          </mat-form-field>\n        </mat-option>\n        <div class=\"options-box\">\n          @for (option of filteredOptions$ | async; track option) {\n            <mat-option\n              [value]=\"option\"\n              >{{ getName(option) }}</mat-option\n              >\n            }\n            @if ((filteredOptions$ | async)?.length === 0) {\n              <span\n                class=\"no-option\"\n                >{{ nothingFoundText }}</span\n                >\n              }\n            </div>\n          </mat-select>\n          <mat-error>{{invalidControlText}}</mat-error>\n          <button mat-icon-button matSuffix color=\"primary\" (click)=\"$event.stopPropagation();value=null;\" matTooltip=\"Clear Field\">\n            <mat-icon>clear</mat-icon>\n          </button>\n        </mat-form-field>\n    `,\n  styleUrls: ['./ngx-searchable-select.component.scss'],\n  encapsulation: ViewEncapsulation.None\n})\nexport class NgxSearchableSelectComponent<T extends StringOrRecord> implements OnInit, ControlValueAccessor, OnChanges {\n\n  @Input({ required: true }) label = '';\n  @Input() appearance: MatFormFieldAppearance = 'outline';\n  @Input() options: T[] | null = null;\n  @Input() searchField: string | null = null;\n  @Input() nothingFoundText: string = 'Nothing found...';\n  @Input() invalidControlText: string = 'Invalid Field';\n\n  filter(text: string) {\n    if (this.options) {\n      const isStringArray = this.options.every((item) => typeof item === 'string');\n      if (!isStringArray) {\n        if (this.searchField) {\n          const index = this.searchField;\n          return this.options.filter(option => (<Record<string, any>>option)[index].toLowerCase().includes(text.toLowerCase()));\n        }\n        else {\n          return this.options.filter(option => {\n            const object = <Record<string, any>>option;\n            const keys = Object.keys(object);\n            for (let index = 0; index < keys.length; index++) {\n              const value = object[keys[index]];\n              if (value.toString().includes(text)) {\n                return true; // If found, include the item in the filtered array\n              }\n            }\n            return false;\n          });\n        }\n      }\n      return this.options.filter(option => (<string>option).toLowerCase().includes(text.toLowerCase()));\n    }\n    return [];\n  };\n\n  _value = new FormControl<T | null>(null, { nonNullable: false });\n  public get value(): T | null {\n    return this._value.value;\n  }\n  public set value(value: T | null) {\n    this._value.setValue(value);\n    this.onChange(value);\n    this.onTouch(value);\n  }\n\n  onChange: any = () => { }\n  onTouch: any = () => { }\n\n  searchText = new FormControl('', { nonNullable: true });\n  filteredOptions$ = this.searchText.valueChanges.pipe(\n    startWith(''),\n    map(text => this.filter(text))\n  );\n\n  constructor(@Self() @Optional() private ngControl: NgControl) {\n    this.ngControl.valueAccessor = this;\n  }\n\n  ngOnInit(): void {\n    const validators = this.ngControl.control?.validator;\n    this._value.setValidators(validators ? validators : null);\n    this._value.updateValueAndValidity();\n  }\n\n  ngOnChanges(): void {\n    // Manually trigger options update \n    // Usefull in case of asynchronous options that have network latency\n    this.searchText.reset();\n  }\n\n  writeValue(value: T | null): void {\n    this._value.setValue(value);\n  }\n\n  registerOnChange(fn: any): void {\n    this.onChange = fn;\n  }\n\n  registerOnTouched(fn: any): void {\n    this.onTouch = fn;\n  }\n\n  setDisabledState(isDisabled: boolean): void {\n    isDisabled ? this._value.disable() : this._value.enable();\n  }\n\n  onSelectionChange(event: MatSelectChange) {\n    const value = <T>event.value;\n    this.value = value;\n  }\n\n  getName(option: T) {\n    const keys = Object.keys(option);\n    return typeof (option) !== \"string\" ? this.searchField ? option[this.searchField] : option[<string>keys.find(key => typeof (option[key]) === 'string')] : option;\n  }\n\n}\n","/*\n * Public API Surface of ngx-searchable-select\n */\n\nexport * from './lib/ngx-searchable-select.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}