@tft/crispr-forms 12.2.16 → 12.2.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,14 +5,16 @@ import { BehaviorSubject, combineLatest } from 'rxjs';
5
5
  import { ENTER } from '@angular/cdk/keycodes';
6
6
  import { DEFAULT_EMPTY_OPTIONS_MESSAGE } from '../../models';
7
7
  import { AbstractAutocompleteComponent } from '../../abstracts';
8
+ const ɵ0 = (chip, option) => chip.value === option.value;
8
9
  const defaultConfig = {
9
10
  chipsSelectable: true,
10
11
  areChipsRemovable: true,
11
12
  tabToSelect: true,
12
- autoActiveFirstOption: false,
13
+ autoActiveFirstOption: true,
13
14
  imageUrlParam: 'image',
14
15
  typeDebounceTime: 500,
15
16
  allowDuplicates: false,
17
+ duplicateCompareFunction: ɵ0,
16
18
  separatorKeyCodes: [ENTER],
17
19
  emptyOptionsMessage: DEFAULT_EMPTY_OPTIONS_MESSAGE,
18
20
  };
@@ -34,7 +36,7 @@ export class AutocompleteChiplistFieldComponent extends AbstractAutocompleteComp
34
36
  return this.config.allowDuplicates
35
37
  ? options
36
38
  : options === null || options === void 0 ? void 0 : options.filter(option => {
37
- return !chips.some(chip => chip.value === option.value);
39
+ return !chips.some(chip => this.config.duplicateCompareFunction(chip, option));
38
40
  });
39
41
  }));
40
42
  }
@@ -86,7 +88,7 @@ export class AutocompleteChiplistFieldComponent extends AbstractAutocompleteComp
86
88
  AutocompleteChiplistFieldComponent.decorators = [
87
89
  { type: Component, args: [{
88
90
  selector: 'crispr-autocomplete-chiplist-field',
89
- template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n\n <mat-chip-list\n #chipList>\n <mat-chip\n class=\"refinement-chip\"\n *ngFor=\"let chip of controlValue$ | async\"\n [selectable]=\"config.chipsSelectable\"\n [removable]=\"config.areChipsRemovable\"\n (removed)=\"removeChip(chip)\">\n <span *ngIf=\"chip.imageUrl as imageUrl\" class=\"image-container\">\n <img [src]=\"imageUrl\" alt=\"\">\n </span>\n {{chip.label}}\n <mat-icon\n matChipRemove\n *ngIf=\"config.areChipsRemovable\">\n cancel\n </mat-icon>\n </mat-chip>\n\n <input\n matInput\n [formControl]=\"autocompleteInputControl\"\n [placeholder]=\"config.placeholder\"\n [matChipInputFor]=\"chipList\"\n [matAutocomplete]=\"auto\"\n (keydown.tab)=\"handleTab($event)\"\n [matChipInputSeparatorKeyCodes]=\"config.separatorKeyCodes\"\n (matChipInputTokenEnd)=\"handleTokenEnd($event)\"\n role=\"searchbox\"\n type=\"text\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n #autoInput/>\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info \">\n </crispr-info>\n\n </mat-chip-list>\n <mat-autocomplete\n #auto=\"matAutocomplete\"\n [autoActiveFirstOption]=\"this.config.autoActiveFirstOption\"\n (optionSelected)=\"handleSelect($event)\"\n [displayWith]=\"mapToLabel\">\n <ng-container *ngIf=\"remainingOptions$ | async as remainingOptions; else emptyOption\">\n <ng-container *ngIf=\"remainingOptions.length > 0; else emptyOption\">\n <mat-option\n *ngFor=\"let option of remainingOptions$ | async\"\n [value]=\"option\">\n <crispr-option [option]=\"option\"></crispr-option>\n </mat-option>\n </ng-container>\n\n </ng-container>\n <ng-template #emptyOption>\n <mat-option disabled=\"true\">\n {{config.emptyOptionsMessage}}\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n\n </mat-form-field>\n</crispr-field-container>\n",
91
+ template: "<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n\n <mat-chip-list\n #chipList>\n <mat-chip\n class=\"refinement-chip\"\n *ngFor=\"let chip of controlValue$ | async\"\n [selectable]=\"config.chipsSelectable\"\n [removable]=\"config.areChipsRemovable\"\n (removed)=\"removeChip(chip)\">\n <span *ngIf=\"chip.imageUrl as imageUrl\" class=\"image-container\">\n <img [src]=\"imageUrl\" alt=\"image of {{chip.label}}\">\n </span>\n {{chip.label}}\n <mat-icon\n matChipRemove\n *ngIf=\"config.areChipsRemovable\">\n cancel\n </mat-icon>\n </mat-chip>\n\n <input\n matInput\n [formControl]=\"autocompleteInputControl\"\n [placeholder]=\"config.placeholder\"\n [matChipInputFor]=\"chipList\"\n [matAutocomplete]=\"auto\"\n (keydown.tab)=\"handleTab($event)\"\n [matChipInputSeparatorKeyCodes]=\"config.separatorKeyCodes\"\n (matChipInputTokenEnd)=\"handleTokenEnd($event)\"\n role=\"searchbox\"\n type=\"text\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n #autoInput/>\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info \">\n </crispr-info>\n\n </mat-chip-list>\n <mat-autocomplete\n #auto=\"matAutocomplete\"\n [autoActiveFirstOption]=\"this.config.autoActiveFirstOption\"\n (optionSelected)=\"handleSelect($event)\"\n [displayWith]=\"mapToLabel\">\n <ng-container *ngIf=\"remainingOptions$ | async as remainingOptions; else emptyOption\">\n <ng-container *ngIf=\"remainingOptions.length > 0; else emptyOption\">\n <mat-option\n *ngFor=\"let option of remainingOptions$ | async\"\n [value]=\"option\">\n <crispr-option [option]=\"option\"></crispr-option>\n </mat-option>\n </ng-container>\n\n </ng-container>\n <ng-template #emptyOption>\n <mat-option disabled=\"true\">\n {{config.emptyOptionsMessage}}\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n\n </mat-form-field>\n</crispr-field-container>\n",
90
92
  changeDetection: ChangeDetectionStrategy.OnPush,
91
93
  styles: [".refinement-chip .image-container{width:26px;height:26px;border-radius:50%;overflow:hidden;margin:-2px 4px -2px -8px}.refinement-chip .image-container img{width:100%;height:100%;-o-object-fit:cover;object-fit:cover}"]
92
94
  },] }
@@ -95,4 +97,5 @@ AutocompleteChiplistFieldComponent.propDecorators = {
95
97
  chipInput: [{ type: ViewChild, args: ['autoInput', { read: MatAutocompleteTrigger },] }],
96
98
  chipInputRef: [{ type: ViewChild, args: ['autoInput',] }]
97
99
  };
100
+ export { ɵ0 };
98
101
  //# sourceMappingURL=autocomplete-chiplist-field.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"autocomplete-chiplist-field.component.js","sourceRoot":"","sources":["../../../../../../../libs/crispr-forms/src/lib/material/autocomplete-chiplist-field/autocomplete-chiplist-field.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, ChangeDetectionStrategy, ViewChild, ElementRef } from '@angular/core';\nimport { map, tap } from 'rxjs/operators';\nimport { MatAutocompleteSelectedEvent, MatAutocompleteTrigger } from '@angular/material/autocomplete';\nimport { Observable, BehaviorSubject, combineLatest } from 'rxjs';\nimport { ENTER } from '@angular/cdk/keycodes';\n\nimport { AutocompleteChiplistFieldConfig, DEFAULT_EMPTY_OPTIONS_MESSAGE, SelectOption } from '../../models';\nimport { AbstractAutocompleteComponent } from '../../abstracts';\nimport { MatChipInputEvent } from '@angular/material/chips';\n\nconst defaultConfig: Partial<AutocompleteChiplistFieldConfig> = {\n chipsSelectable: true,\n areChipsRemovable: true,\n tabToSelect: true,\n autoActiveFirstOption: false,\n imageUrlParam: 'image',\n typeDebounceTime: 500,\n allowDuplicates: false,\n separatorKeyCodes: [ENTER],\n emptyOptionsMessage: DEFAULT_EMPTY_OPTIONS_MESSAGE,\n}\n\n@Component({\n selector: 'crispr-autocomplete-chiplist-field',\n templateUrl: './autocomplete-chiplist-field.component.html',\n styleUrls: ['./autocomplete-chiplist-field.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class AutocompleteChiplistFieldComponent\n extends AbstractAutocompleteComponent<AutocompleteChiplistFieldConfig> implements OnInit {\n defaultConfig = defaultConfig;\n chips$ = new BehaviorSubject<SelectOption[]>([]);\n remainingOptions$: Observable<SelectOption[]>;\n\n controlValue$ = this.chips$.pipe(\n tap(chips => {\n this.control.setValue(chips.map(chip => chip.value))\n })\n );\n\n\n // We need use ViewChild twice on the same template ref to access as different types\n // - the MatAutocompleteTrigger is used to for selecting value on tab\n // - the ElementRef<HTMLInputElement> is used to clear the value from input element on selection\n @ViewChild('autoInput', { read: MatAutocompleteTrigger }) chipInput: MatAutocompleteTrigger;\n @ViewChild('autoInput') chipInputRef: ElementRef<HTMLInputElement>;\n\n\n ngOnInit() {\n super.ngOnInit();\n this.remainingOptions$ = combineLatest([\n this.chips$,\n this.options$\n ]).pipe(\n map(([chips, options]) => {\n return this.config.allowDuplicates\n ? options\n : options?.filter(option => {\n return !chips.some(chip => chip.value === option.value);\n })\n })\n )\n }\n\n setControlValue(value: SelectOption[]) {\n if (value) {\n this.chips$.next(value);\n }\n }\n\n // handles mat selecting\n handleSelect(event: MatAutocompleteSelectedEvent) {\n const selectedOption: SelectOption = event.option.value as SelectOption;\n this.chips$.next([...this.chips$.value, selectedOption]);\n this.chipInputRef.nativeElement.value = '';\n this.autocompleteInputControl.setValue('');\n // setTimeout needed because the panel thinks it's still open at this point\n setTimeout(() => this.chipInput.openPanel())\n }\n\n /**\n * To follow ARIA standards we want to select the active option on blur.\n * matChipInputAddOnBlur should do this but it causes buggy behaviour\n * @param event blur event that triggers the handle blur\n */\n handleTab(_event: FocusEvent) {\n if (this.chipInput.activeOption && (this.config.tabToSelect || this.config.addChipOnBlur)) {\n const chip = this.chipInput.activeOption.value;\n this.chips$.next([...this.chips$.value, chip]);\n }\n }\n\n /**\n * Handles selection via key tokens passed through separatorKeyCodes propert\n * NOTE: If TAB is used focus does not move on to next component\n * @param event\n */\n handleTokenEnd(event: MatChipInputEvent) {\n if (this.chipInput.activeOption) {\n this.chipInput.activeOption.select();\n }\n event.chipInput?.clear();\n }\n\n mapToLabel(option: SelectOption) {\n return option ? option.label : '';\n }\n\n removeChip(removedChip: SelectOption) {\n const remainingChips: SelectOption[] = this.chips$.value.filter(chip => chip !== removedChip);\n this.chips$.next(remainingChips);\n }\n}\n"]}
1
+ {"version":3,"file":"autocomplete-chiplist-field.component.js","sourceRoot":"","sources":["../../../../../../../libs/crispr-forms/src/lib/material/autocomplete-chiplist-field/autocomplete-chiplist-field.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAU,uBAAuB,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClG,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAgC,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACtG,OAAO,EAAc,eAAe,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAClE,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE9C,OAAO,EAAmC,6BAA6B,EAAgB,MAAM,cAAc,CAAC;AAC5G,OAAO,EAAE,6BAA6B,EAAE,MAAM,iBAAiB,CAAC;WAWpC,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK;AARzE,MAAM,aAAa,GAA6C;IAC9D,eAAe,EAAE,IAAI;IACrB,iBAAiB,EAAE,IAAI;IACvB,WAAW,EAAE,IAAI;IACjB,qBAAqB,EAAE,IAAI;IAC3B,aAAa,EAAE,OAAO;IACtB,gBAAgB,EAAE,GAAG;IACrB,eAAe,EAAE,KAAK;IACtB,wBAAwB,IAA+C;IACvE,iBAAiB,EAAE,CAAC,KAAK,CAAC;IAC1B,mBAAmB,EAAE,6BAA6B;CACnD,CAAA;AAQD,MAAM,OAAO,kCACX,SAAQ,6BAA8D;IAPxE;;QAQE,kBAAa,GAAG,aAAa,CAAC;QAC9B,WAAM,GAAG,IAAI,eAAe,CAAiB,EAAE,CAAC,CAAC;QAGjD,kBAAa,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAC9B,GAAG,CAAC,KAAK,CAAC,EAAE;YACV,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QACtD,CAAC,CAAC,CACH,CAAC;IA0EJ,CAAC;IAhEC,QAAQ;QACN,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjB,IAAI,CAAC,iBAAiB,GAAG,aAAa,CAAC;YACrC,IAAI,CAAC,MAAM;YACX,IAAI,CAAC,QAAQ;SACd,CAAC,CAAC,IAAI,CACL,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,EAAE;YACvB,OAAO,IAAI,CAAC,MAAM,CAAC,eAAe;gBAChC,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,CAAC,MAAM,CAAC,EAAE;oBACzB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,wBAAwB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;gBACjF,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CACH,CAAA;IACH,CAAC;IAED,eAAe,CAAC,KAAqB;QACnC,IAAI,KAAK,EAAE;YACT,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;SACzB;IACH,CAAC;IAED,wBAAwB;IACxB,YAAY,CAAC,KAAmC;QAC9C,MAAM,cAAc,GAAiB,KAAK,CAAC,MAAM,CAAC,KAAqB,CAAC;QACxE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAG,cAAc,CAAC,CAAC,CAAC;QAC1D,IAAI,CAAC,YAAY,CAAC,aAAa,CAAC,KAAK,GAAG,EAAE,CAAC;QAC3C,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAC3C,2EAA2E;QAC3E,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,CAAA;IAC9C,CAAC;IAED;;;;OAIG;IACH,SAAS,CAAC,MAAkB;QAC1B,IAAI,IAAI,CAAC,SAAS,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE;YACzF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,KAAK,CAAC;YAC/C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAG,IAAI,CAAC,CAAC,CAAC;SACjD;IACH,CAAC;IAED;;;;OAIG;IACH,cAAc,CAAC,KAAwB;;QACrC,IAAI,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE;YAC/B,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;SACtC;QACD,MAAA,KAAK,CAAC,SAAS,0CAAE,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED,UAAU,CAAC,MAAoB;QAC7B,OAAO,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IACpC,CAAC;IAED,UAAU,CAAC,WAAyB;QAClC,MAAM,cAAc,GAAmB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;QAC9F,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACnC,CAAC;;;YAzFF,SAAS,SAAC;gBACT,QAAQ,EAAE,oCAAoC;gBAC9C,8+EAA2D;gBAE3D,eAAe,EAAE,uBAAuB,CAAC,MAAM;;aAChD;;;wBAiBE,SAAS,SAAC,WAAW,EAAE,EAAE,IAAI,EAAE,sBAAsB,EAAE;2BACvD,SAAS,SAAC,WAAW","sourcesContent":["import { Component, OnInit, ChangeDetectionStrategy, ViewChild, ElementRef } from '@angular/core';\nimport { map, tap } from 'rxjs/operators';\nimport { MatAutocompleteSelectedEvent, MatAutocompleteTrigger } from '@angular/material/autocomplete';\nimport { Observable, BehaviorSubject, combineLatest } from 'rxjs';\nimport { ENTER } from '@angular/cdk/keycodes';\n\nimport { AutocompleteChiplistFieldConfig, DEFAULT_EMPTY_OPTIONS_MESSAGE, SelectOption } from '../../models';\nimport { AbstractAutocompleteComponent } from '../../abstracts';\nimport { MatChipInputEvent } from '@angular/material/chips';\n\nconst defaultConfig: Partial<AutocompleteChiplistFieldConfig> = {\n chipsSelectable: true,\n areChipsRemovable: true,\n tabToSelect: true,\n autoActiveFirstOption: true,\n imageUrlParam: 'image',\n typeDebounceTime: 500,\n allowDuplicates: false,\n duplicateCompareFunction: (chip, option) => chip.value === option.value,\n separatorKeyCodes: [ENTER],\n emptyOptionsMessage: DEFAULT_EMPTY_OPTIONS_MESSAGE,\n}\n\n@Component({\n selector: 'crispr-autocomplete-chiplist-field',\n templateUrl: './autocomplete-chiplist-field.component.html',\n styleUrls: ['./autocomplete-chiplist-field.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class AutocompleteChiplistFieldComponent\n extends AbstractAutocompleteComponent<AutocompleteChiplistFieldConfig> implements OnInit {\n defaultConfig = defaultConfig;\n chips$ = new BehaviorSubject<SelectOption[]>([]);\n remainingOptions$: Observable<SelectOption[]>;\n\n controlValue$ = this.chips$.pipe(\n tap(chips => {\n this.control.setValue(chips.map(chip => chip.value))\n })\n );\n\n\n // We need use ViewChild twice on the same template ref to access as different types\n // - the MatAutocompleteTrigger is used to for selecting value on tab\n // - the ElementRef<HTMLInputElement> is used to clear the value from input element on selection\n @ViewChild('autoInput', { read: MatAutocompleteTrigger }) chipInput: MatAutocompleteTrigger;\n @ViewChild('autoInput') chipInputRef: ElementRef<HTMLInputElement>;\n\n\n ngOnInit() {\n super.ngOnInit();\n this.remainingOptions$ = combineLatest([\n this.chips$,\n this.options$\n ]).pipe(\n map(([chips, options]) => {\n return this.config.allowDuplicates\n ? options\n : options?.filter(option => {\n return !chips.some(chip => this.config.duplicateCompareFunction(chip, option));\n });\n })\n )\n }\n\n setControlValue(value: SelectOption[]) {\n if (value) {\n this.chips$.next(value);\n }\n }\n\n // handles mat selecting\n handleSelect(event: MatAutocompleteSelectedEvent) {\n const selectedOption: SelectOption = event.option.value as SelectOption;\n this.chips$.next([...this.chips$.value, selectedOption]);\n this.chipInputRef.nativeElement.value = '';\n this.autocompleteInputControl.setValue('');\n // setTimeout needed because the panel thinks it's still open at this point\n setTimeout(() => this.chipInput.openPanel())\n }\n\n /**\n * To follow ARIA standards we want to select the active option on blur.\n * matChipInputAddOnBlur should do this but it causes buggy behaviour\n * @param event blur event that triggers the handle blur\n */\n handleTab(_event: FocusEvent) {\n if (this.chipInput.activeOption && (this.config.tabToSelect || this.config.addChipOnBlur)) {\n const chip = this.chipInput.activeOption.value;\n this.chips$.next([...this.chips$.value, chip]);\n }\n }\n\n /**\n * Handles selection via key tokens passed through separatorKeyCodes propert\n * NOTE: If TAB is used focus does not move on to next component\n * @param event\n */\n handleTokenEnd(event: MatChipInputEvent) {\n if (this.chipInput.activeOption) {\n this.chipInput.activeOption.select();\n }\n event.chipInput?.clear();\n }\n\n mapToLabel(option: SelectOption) {\n return option ? option.label : '';\n }\n\n removeChip(removedChip: SelectOption) {\n const remainingChips: SelectOption[] = this.chips$.value.filter(chip => chip !== removedChip);\n this.chips$.next(remainingChips);\n }\n}\n"]}
@@ -1 +1 @@
1
- [{"__symbolic":"module","version":4,"metadata":{"AutocompleteChiplistFieldComponent":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../../abstracts","name":"AbstractAutocompleteComponent","line":29,"character":10},"decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Component","line":22,"character":1},"arguments":[{"selector":"crispr-autocomplete-chiplist-field","changeDetection":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/core","name":"ChangeDetectionStrategy","line":26,"character":19},"member":"OnPush"},"template":"<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n\n <mat-chip-list\n #chipList>\n <mat-chip\n class=\"refinement-chip\"\n *ngFor=\"let chip of controlValue$ | async\"\n [selectable]=\"config.chipsSelectable\"\n [removable]=\"config.areChipsRemovable\"\n (removed)=\"removeChip(chip)\">\n <span *ngIf=\"chip.imageUrl as imageUrl\" class=\"image-container\">\n <img [src]=\"imageUrl\" alt=\"\">\n </span>\n {{chip.label}}\n <mat-icon\n matChipRemove\n *ngIf=\"config.areChipsRemovable\">\n cancel\n </mat-icon>\n </mat-chip>\n\n <input\n matInput\n [formControl]=\"autocompleteInputControl\"\n [placeholder]=\"config.placeholder\"\n [matChipInputFor]=\"chipList\"\n [matAutocomplete]=\"auto\"\n (keydown.tab)=\"handleTab($event)\"\n [matChipInputSeparatorKeyCodes]=\"config.separatorKeyCodes\"\n (matChipInputTokenEnd)=\"handleTokenEnd($event)\"\n role=\"searchbox\"\n type=\"text\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n #autoInput/>\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info \">\n </crispr-info>\n\n </mat-chip-list>\n <mat-autocomplete\n #auto=\"matAutocomplete\"\n [autoActiveFirstOption]=\"this.config.autoActiveFirstOption\"\n (optionSelected)=\"handleSelect($event)\"\n [displayWith]=\"mapToLabel\">\n <ng-container *ngIf=\"remainingOptions$ | async as remainingOptions; else emptyOption\">\n <ng-container *ngIf=\"remainingOptions.length > 0; else emptyOption\">\n <mat-option\n *ngFor=\"let option of remainingOptions$ | async\"\n [value]=\"option\">\n <crispr-option [option]=\"option\"></crispr-option>\n </mat-option>\n </ng-container>\n\n </ng-container>\n <ng-template #emptyOption>\n <mat-option disabled=\"true\">\n {{config.emptyOptionsMessage}}\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n\n </mat-form-field>\n</crispr-field-container>\n","styles":[".refinement-chip .image-container{width:26px;height:26px;border-radius:50%;overflow:hidden;margin:-2px 4px -2px -8px}.refinement-chip .image-container img{width:100%;height:100%;-o-object-fit:cover;object-fit:cover}"]}]}],"members":{"chipInput":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"ViewChild","line":44,"character":3},"arguments":["autoInput",{"read":{"__symbolic":"reference","module":"@angular/material/autocomplete","name":"MatAutocompleteTrigger","line":44,"character":34}}]}]}],"chipInputRef":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"ViewChild","line":45,"character":3},"arguments":["autoInput"]}]}],"ngOnInit":[{"__symbolic":"method"}],"setControlValue":[{"__symbolic":"method"}],"handleSelect":[{"__symbolic":"method"}],"handleTab":[{"__symbolic":"method"}],"handleTokenEnd":[{"__symbolic":"method"}],"mapToLabel":[{"__symbolic":"method"}],"removeChip":[{"__symbolic":"method"}]}}}}]
1
+ [{"__symbolic":"module","version":4,"metadata":{"ɵ0":{"__symbolic":"error","message":"Lambda not supported","line":18,"character":28},"AutocompleteChiplistFieldComponent":{"__symbolic":"class","extends":{"__symbolic":"reference","module":"../../abstracts","name":"AbstractAutocompleteComponent","line":30,"character":10},"decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"Component","line":23,"character":1},"arguments":[{"selector":"crispr-autocomplete-chiplist-field","changeDetection":{"__symbolic":"select","expression":{"__symbolic":"reference","module":"@angular/core","name":"ChangeDetectionStrategy","line":27,"character":19},"member":"OnPush"},"template":"<crispr-field-container\n [config]=\"config\"\n [group]=\"group\">\n\n <mat-form-field\n [color]=\"config.color\"\n [appearance]=\"config.appearance\">\n <mat-label *ngIf=\"config.label\">\n {{config.label}}\n </mat-label>\n\n <mat-chip-list\n #chipList>\n <mat-chip\n class=\"refinement-chip\"\n *ngFor=\"let chip of controlValue$ | async\"\n [selectable]=\"config.chipsSelectable\"\n [removable]=\"config.areChipsRemovable\"\n (removed)=\"removeChip(chip)\">\n <span *ngIf=\"chip.imageUrl as imageUrl\" class=\"image-container\">\n <img [src]=\"imageUrl\" alt=\"image of {{chip.label}}\">\n </span>\n {{chip.label}}\n <mat-icon\n matChipRemove\n *ngIf=\"config.areChipsRemovable\">\n cancel\n </mat-icon>\n </mat-chip>\n\n <input\n matInput\n [formControl]=\"autocompleteInputControl\"\n [placeholder]=\"config.placeholder\"\n [matChipInputFor]=\"chipList\"\n [matAutocomplete]=\"auto\"\n (keydown.tab)=\"handleTab($event)\"\n [matChipInputSeparatorKeyCodes]=\"config.separatorKeyCodes\"\n (matChipInputTokenEnd)=\"handleTokenEnd($event)\"\n role=\"searchbox\"\n type=\"text\"\n autocapitalize=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n #autoInput/>\n <span *ngIf=\"config.fieldSuffix\" matSuffix>{{config.fieldSuffix}}</span>\n <crispr-info\n *ngIf=\"config.info\"\n matSuffix\n [info]=\"config.info \">\n </crispr-info>\n\n </mat-chip-list>\n <mat-autocomplete\n #auto=\"matAutocomplete\"\n [autoActiveFirstOption]=\"this.config.autoActiveFirstOption\"\n (optionSelected)=\"handleSelect($event)\"\n [displayWith]=\"mapToLabel\">\n <ng-container *ngIf=\"remainingOptions$ | async as remainingOptions; else emptyOption\">\n <ng-container *ngIf=\"remainingOptions.length > 0; else emptyOption\">\n <mat-option\n *ngFor=\"let option of remainingOptions$ | async\"\n [value]=\"option\">\n <crispr-option [option]=\"option\"></crispr-option>\n </mat-option>\n </ng-container>\n\n </ng-container>\n <ng-template #emptyOption>\n <mat-option disabled=\"true\">\n {{config.emptyOptionsMessage}}\n </mat-option>\n </ng-template>\n </mat-autocomplete>\n\n\n </mat-form-field>\n</crispr-field-container>\n","styles":[".refinement-chip .image-container{width:26px;height:26px;border-radius:50%;overflow:hidden;margin:-2px 4px -2px -8px}.refinement-chip .image-container img{width:100%;height:100%;-o-object-fit:cover;object-fit:cover}"]}]}],"members":{"chipInput":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"ViewChild","line":45,"character":3},"arguments":["autoInput",{"read":{"__symbolic":"reference","module":"@angular/material/autocomplete","name":"MatAutocompleteTrigger","line":45,"character":34}}]}]}],"chipInputRef":[{"__symbolic":"property","decorators":[{"__symbolic":"call","expression":{"__symbolic":"reference","module":"@angular/core","name":"ViewChild","line":46,"character":3},"arguments":["autoInput"]}]}],"ngOnInit":[{"__symbolic":"method"}],"setControlValue":[{"__symbolic":"method"}],"handleSelect":[{"__symbolic":"method"}],"handleTab":[{"__symbolic":"method"}],"handleTokenEnd":[{"__symbolic":"method"}],"mapToLabel":[{"__symbolic":"method"}],"removeChip":[{"__symbolic":"method"}]}}}}]