From 16d7beed6faf060ef27aacfb0d69aa72c55c64f2 Mon Sep 17 00:00:00 2001 From: Anna Date: Thu, 23 Jan 2020 14:17:52 +0300 Subject: [PATCH 1/9] create new chips autocomplete component --- ...ps-autocomplete-story-basic.component.html | 13 + ...ps-autocomplete-story-basic.component.scss | 5 + ...hips-autocomplete-story-basic.component.ts | 28 ++ .../chips-autocomplete-story-basic.module.ts | 26 ++ .../chips-autocomplete-story-basic/index.ts | 0 .../chips-autocomplete.component.html | 41 ++ .../chips-autocomplete.component.scss | 5 + .../chips-autocomplete.component.ts | 422 ++++++++++++++++++ .../chips-autocomplete.directive.ts | 6 + .../chips-autocomplete.module.ts | 25 ++ .../chips-autocomplete.stories.mdx | 38 ++ .../ui/chips-autocomplete/filter-options.ts | 9 + .../src/lib/ui/chips-autocomplete/index.ts | 3 + tsconfig.json | 1 + tslint.json | 7 +- 15 files changed, 623 insertions(+), 6 deletions(-) create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.scss create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.ts create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.module.ts create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/index.ts create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.scss create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.directive.ts create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.module.ts create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/filter-options.ts create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/index.ts diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html new file mode 100644 index 00000000..3ca795fa --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html @@ -0,0 +1,13 @@ +
+ + Fruit + + +
diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.scss b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.scss new file mode 100644 index 00000000..10c18d25 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.scss @@ -0,0 +1,5 @@ +.es-chips-autocomplete-story-basic { + &.mat-form-field { + width: 100%; + } +} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.ts new file mode 100644 index 00000000..b39320eb --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.ts @@ -0,0 +1,28 @@ +import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; +import { FormGroup, FormBuilder } from '@angular/forms'; +import { GetFilterOptions } from '../../filter-options'; + +const OPTIONS = ['Apple', 'Lemon', 'Mango']; + +@Component({ + selector: 'es-chips-autocomplete-story-basic', + templateUrl: './chips-autocomplete-story-basic.component.html', + styleUrls: ['./chips-autocomplete-story-basic.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None +}) +export class ChipsAutocompleteBasicComponent { + public form: FormGroup; + public options: any[] = OPTIONS; + public chips: any[] = []; + + constructor(private formBuilder: FormBuilder) { + this.form = this.formBuilder.group({ + chips: '' + }); + } + + public onChangeText(text: string) { + this.options = GetFilterOptions(text, OPTIONS); + } +} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.module.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.module.ts new file mode 100644 index 00000000..c32f5cb5 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.module.ts @@ -0,0 +1,26 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { ReactiveFormsModule } from '@angular/forms'; + +import { MatFormFieldModule } from '@angular/material/form-field'; + +import { ES_CHIPS_DEFAULT_OPTIONS } from '../../chips-autocomplete.component'; +import { ESChipsAutocompleteModule } from '../../chips-autocomplete.module'; +import { ChipsAutocompleteBasicComponent } from './chips-autocomplete-story-basic.component'; + +@NgModule({ + declarations: [ChipsAutocompleteBasicComponent], + imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, ESChipsAutocompleteModule], + exports: [ChipsAutocompleteBasicComponent], + providers: [ + { + provide: ES_CHIPS_DEFAULT_OPTIONS, + useValue: { + debounceTime: 1000, + freeInput: true + } + } + ] +}) +export class ESChipsAutocompleteBasicModule {} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/index.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html new file mode 100644 index 00000000..4e56021c --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html @@ -0,0 +1,41 @@ + + + {{ chip }} + cancel + + + + + + + + {{ option }} + + + + + + diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.scss b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.scss new file mode 100644 index 00000000..b1b06764 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.scss @@ -0,0 +1,5 @@ +input { + flex: 1 0 150px; + margin: 4px; + width: 150px; +} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts new file mode 100644 index 00000000..fb50d3b3 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts @@ -0,0 +1,422 @@ +import { + Component, + ChangeDetectionStrategy, + ViewEncapsulation, + OnDestroy, + OnInit, + Input, + HostBinding, + Optional, + Self, + ChangeDetectorRef, + Output, + EventEmitter, + ViewChild, + ContentChild, + TemplateRef, + InjectionToken, + Inject +} from '@angular/core'; + +import { ControlValueAccessor, NgControl, FormGroupDirective } from '@angular/forms'; + +import { coerceBooleanProperty } from '@angular/cdk/coercion'; + +import { MatFormFieldControl } from '@angular/material/form-field'; +import { MatAutocompleteTrigger, MatAutocomplete } from '@angular/material/autocomplete'; + +import { Subject, timer } from 'rxjs'; +import { debounce } from 'rxjs/operators'; + +import { ChipsAutocompleteOptionDirective } from '../chips-autocomplete/chips-autocomplete.directive'; +import { MatChipInputEvent } from '@angular/material/chips'; + +import { ENTER, COMMA, SEMICOLON } from '@angular/cdk/keycodes'; + +export const ES_CHIPS_DEFAULT_OPTIONS = new InjectionToken( + 'ES_CHIPS_DEFAULT_OPTIONS' +); + +export interface EsAutocompleteDefaultOptions { + debounceTime?: number; + freeInput?: boolean; +} + +@Component({ + selector: 'es-chips-autocomplete', + templateUrl: './chips-autocomplete.component.html', + styleUrls: ['./chips-autocomplete.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None, + providers: [{ provide: MatFormFieldControl, useExisting: ChipsAutocompleteComponent }] +}) +export class ChipsAutocompleteComponent + implements MatFormFieldControl, ControlValueAccessor, OnDestroy, OnInit { + public separatorKeysCodes = [ENTER, COMMA, SEMICOLON]; + + /** + * If true this chip list is selectable + */ + @Input() public selectable: boolean; + + /** + * If true this chip list is removable + */ + @Input() public removable: boolean; + + /** + * Array of options + */ + @Input() public options: any[]; + + /** + * Array of chips + */ + @Input() public chips: any[]; + + /** + * Change value after a particular time span has passed + */ + @Input() + public get debounceTime(): number { + return this._debounceTime; + } + public set debounceTime(value: number) { + this._debounceTime = + value || + (this.autocompleteDefaultOptions && this.autocompleteDefaultOptions.debounceTime) || + 0; + } + + /** + * If true the user input is not bound to provided options + */ + @Input() + public get freeInput(): boolean { + return this._freeInput; + } + public set freeInput(value: boolean) { + this._freeInput = + value !== undefined + ? value + : this.autocompleteDefaultOptions && this.autocompleteDefaultOptions.freeInput + ? this.autocompleteDefaultOptions.freeInput + : false; + } + + public get value(): any { + return this._value; + } + + public set value(value: any) { + this._value = value; + this.stateChanges.next(); + } + + public get focused() { + return this._focused; + } + public set focused(focused: boolean) { + this._focused = focused; + this.stateChanges.next(); + } + + public get empty(): boolean { + return !this.value; + } + + /** + * This property is used to indicate whether the input is required + */ + @Input() + public get required() { + return this._required; + } + public set required(req) { + this._required = coerceBooleanProperty(req); + this.stateChanges.next(); + } + + /** + * This property tells the form field when it should be in the disabled state + */ + @Input() + public get disabled(): boolean { + return this._disabled; + } + public set disabled(dis: boolean) { + this._disabled = coerceBooleanProperty(dis); + this.stateChanges.next(); + } + + /** + * This property allows us to tell component what to use as a placeholder + */ + @Input() + public get placeholder(): string { + return this._placeholder; + } + + public set placeholder(plh) { + this._placeholder = plh; + this.stateChanges.next(); + } + + public get errorState(): boolean { + const control = this.ngControl; + const form = this.ngForm; + + if (control) { + return control.invalid && (control.touched || (form && form.submitted)); + } + + return false; + } + @HostBinding('class.floating') + public get shouldLabelFloat(): boolean { + return this.focused || !!this.text || this.chips.length > 0; + } + + /** + * @ignore + */ + constructor( + public changeDetector: ChangeDetectorRef, + @Optional() @Self() public ngControl: NgControl, + @Optional() + public ngForm: FormGroupDirective, + @Optional() + @Inject(ES_CHIPS_DEFAULT_OPTIONS) + private autocompleteDefaultOptions: EsAutocompleteDefaultOptions + ) { + if (this.ngControl != null) { + this.ngControl.valueAccessor = this; + } + this.debounceTime = + autocompleteDefaultOptions && autocompleteDefaultOptions.debounceTime + ? autocompleteDefaultOptions.debounceTime + : 0; + this.freeInput = + autocompleteDefaultOptions && autocompleteDefaultOptions.freeInput + ? autocompleteDefaultOptions.freeInput + : false; + + this.stateChanges.subscribe(() => { + this.changeDetector.detectChanges(); + }); + } + + private static nextId = 0; + /** + * @ignore + */ + public text = ''; + /** + * @ignore + */ + public stateChanges = new Subject(); + private text$ = new Subject(); + + /** + * @ignore + */ + @Input() public isLoading = false; + + // tslint:disable-next-line variable-name + private _debounceTime: number; + + // tslint:disable-next-line variable-name + private _freeInput: boolean; + + // tslint:disable-next-line variable-name + private _value = ''; + + // tslint:disable-next-line variable-name + private _focused = false; + + // tslint:disable-next-line variable-name + private _required = false; + + // tslint:disable-next-line variable-name + private _disabled = false; + + // tslint:disable-next-line variable-name + private _placeholder = ''; + + /** + * Event emitted when user change text in input + */ + @Output() public changeText = new EventEmitter(); + + @ViewChild('inputChild', { read: MatAutocompleteTrigger, static: true }) + private inputChild: MatAutocompleteTrigger; + @ViewChild('auto', { static: false }) matAutocomplete: MatAutocomplete; + + /** + * Template that allows add custom options + */ + @ContentChild(ChipsAutocompleteOptionDirective, { read: TemplateRef, static: false }) + public optionTemplate: any; + @HostBinding() public id = `es-autocomplete-${ChipsAutocompleteComponent.nextId++}`; + @HostBinding('attr.aria-describedby') public describedBy = ''; + + /** + * Function that maps an option control value to its display value in the trigger + */ + @Input() public displayWith = (value?: any): string | undefined => { + return value ? value : undefined; + }; + + /** + * Function that have chosen value + */ + @Input() public valueFn = (option: any): any => { + return option; + }; + + /** + * @ignore + */ + public ngOnInit() { + this.text$.pipe(debounce(() => timer(this.debounceTime))).subscribe(text => { + this.changeText.emit(text); + }); + } + + /** + * @ignore + */ + public ngOnDestroy() { + this.stateChanges.complete(); + this.changeText.complete(); + } + + /** + * @ignore + */ + public setDescribedByIds(ids: string[]) { + this.describedBy = ids.join(' '); + } + + /** + * @ignore + */ + public onContainerClick(event: MouseEvent) { + this.openPanel(event); + } + + /** + * @ignore + */ + private openPanel(event: MouseEvent) { + if (!this.focused && !this.disabled && this.inputChild) { + event.stopPropagation(); + this.inputChild.openPanel(); + (this.inputChild as any)._element.nativeElement.focus(); + this.stateChanges.next(); + } + } + + /** + * @ignore + */ + public writeValue(value: any) { + if (value !== undefined) { + this.value = value; + this.text = this.value; + this.stateChanges.next(); + } + } + + /** + * @ignore + */ + public registerOnChange(onChange: (value: any) => void) { + this.onChange = onChange; + } + + /** + * @ignore + */ + public onChange = (_: any) => {}; + + /** + * @ignore + */ + public registerOnTouched(onTouched: () => void) { + this.onTouched = onTouched; + } + + /** + * @ignore + */ + public onTouched = () => {}; + + /** + * @ignore + */ + public onInput(event: Event) { + const target = event.target as HTMLInputElement; + this.text = target.value; + this.text$.next(this.text); + this.onChange(this.text); + this.stateChanges.next(); + } + + /** + * @ignore + */ + public onFocus() { + this.focused = true; + this.stateChanges.next(); + } + + /** + * @ignore + */ + public onBlur() { + this.onTouched(); + this.focused = false; + + if (!this.freeInput) { + this.text = this.value; + } + + this.stateChanges.next(); + } + + /** + * @ignore + */ + public onSuggestionSelect(event: Event) { + this.value = event; + this.onChange(this.value); + this.stateChanges.next(); + + this.chips.push(event); + (this.inputChild as any)._element.nativeElement.value = ''; + } + + /** + * @ignore + */ + public onRemove(index: number) { + this.chips.splice(index, 1); + } + + /** + * @ignore + */ + public add(event: MatChipInputEvent) { + const input = event.input; + const value = event.value; + + if ((value || '').trim()) { + this.chips.push(value.trim()); + } + + if (input) { + input.value = ''; + } + } +} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.directive.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.directive.ts new file mode 100644 index 00000000..dab72192 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.directive.ts @@ -0,0 +1,6 @@ +import { Directive } from '@angular/core'; + +@Directive({ + selector: '[esChipsAutocompleteOption]' +}) +export class ChipsAutocompleteOptionDirective {} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.module.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.module.ts new file mode 100644 index 00000000..5ec4b425 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.module.ts @@ -0,0 +1,25 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatInputModule } from '@angular/material/input'; +import { MatSelectModule } from '@angular/material/select'; +import { MatChipsModule } from '@angular/material/chips'; +import { MatIconModule } from '@angular/material/icon'; + +import { ChipsAutocompleteOptionDirective } from './chips-autocomplete.directive'; +import { ChipsAutocompleteComponent } from './chips-autocomplete.component'; + +@NgModule({ + declarations: [ChipsAutocompleteComponent, ChipsAutocompleteOptionDirective], + imports: [ + CommonModule, + MatAutocompleteModule, + MatInputModule, + MatSelectModule, + MatChipsModule, + MatIconModule + ], + exports: [ChipsAutocompleteComponent, ChipsAutocompleteOptionDirective, MatSelectModule] +}) +export class ESChipsAutocompleteModule {} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx new file mode 100644 index 00000000..b7812ef4 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx @@ -0,0 +1,38 @@ +import { Meta, Story, Props } from '@storybook/addon-docs/blocks'; +import { Preview } from '~storybook/components'; + +import { withA11y } from '@storybook/addon-a11y'; +import { action } from '@storybook/addon-actions'; +import { withKnobs, text } from '@storybook/addon-knobs'; + +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; + +import { ESChipsAutocompleteModule } from './chips-autocomplete.module'; +import { ChipsAutocompleteComponent } from './chips-autocomplete.component'; + +import { ESChipsAutocompleteBasicModule } from './__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.module'; + + + +# ChipsAutocomplete + +This component demonstrates usage of chips autocomplete. + +## Demos + +This is a basic story: + + + + {{ + template: ``, + moduleMetadata: { + imports: [BrowserAnimationsModule, ESChipsAutocompleteBasicModule] + } + }} + + + +## API + + diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/filter-options.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/filter-options.ts new file mode 100644 index 00000000..4debd28e --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/filter-options.ts @@ -0,0 +1,9 @@ +export function GetFilterOptions(text: string, options: any): any { + const lowerText = text ? text.toLowerCase() : ''; + return options.filter(e => e.toLowerCase().includes(lowerText)); +} + +export function GetFilterOptionsByKey(text: string, options: any, key: string): any { + const lowerText = text ? text.toLowerCase() : ''; + return options.filter(e => e[key].toLowerCase().includes(lowerText)); +} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/index.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/index.ts new file mode 100644 index 00000000..158da72c --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/index.ts @@ -0,0 +1,3 @@ +export { ESChipsAutocompleteModule } from './chips-autocomplete.module'; +export { ChipsAutocompleteComponent } from './chips-autocomplete.component'; +export { GetFilterOptions, GetFilterOptionsByKey } from './filter-options'; diff --git a/tsconfig.json b/tsconfig.json index 219429bf..da59973f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,7 @@ { "compileOnSave": false, "compilerOptions": { + "emitDecoratorMetadata": true, "baseUrl": "./", "outDir": "./dist/out-tsc", "sourceMap": true, diff --git a/tslint.json b/tslint.json index b8f1eb1e..8507e22e 100644 --- a/tslint.json +++ b/tslint.json @@ -12,12 +12,7 @@ "max-classes-per-file": false, "max-line-length": [true, 140], "member-access": false, - "member-ordering": [ - true, - { - "order": ["static-field", "instance-field", "static-method", "instance-method"] - } - ], + "member-ordering": [false], "no-consecutive-blank-lines": false, "no-console": [true, "debug", "info", "time", "timeEnd", "trace"], "no-empty": false, From 6e07eb06326e41fd0c294a521a8cb34fd311f013 Mon Sep 17 00:00:00 2001 From: Anna Date: Thu, 23 Jan 2020 15:21:12 +0300 Subject: [PATCH 2/9] add custom template for options --- ...ps-autocomplete-story-basic.component.html | 4 +- ...hips-autocomplete-story-basic.component.ts | 1 + .../chips-autocomplete-story-basic/index.ts | 0 ...s-autocomplete-story-custom.component.html | 19 ++++++++ ...s-autocomplete-story-custom.component.scss | 11 +++++ ...ips-autocomplete-story-custom.component.ts | 45 +++++++++++++++++++ .../chips-autocomplete-story-custom.module.ts | 16 +++++++ .../chips-autocomplete.component.html | 1 + .../chips-autocomplete.component.ts | 5 +++ .../chips-autocomplete.stories.mdx | 16 +++++++ 10 files changed, 117 insertions(+), 1 deletion(-) delete mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/index.ts create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.html create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.scss create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.ts create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.module.ts diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html index 3ca795fa..c10d30e4 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html @@ -8,6 +8,8 @@ [chips]="chips" [removable]="true" [selectable]="true" - > + [color]="color" + > + diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.ts index b39320eb..069876fa 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.ts @@ -15,6 +15,7 @@ export class ChipsAutocompleteBasicComponent { public form: FormGroup; public options: any[] = OPTIONS; public chips: any[] = []; + public color = 'accent'; constructor(private formBuilder: FormBuilder) { this.form = this.formBuilder.group({ diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/index.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/index.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.html new file mode 100644 index 00000000..f1b08f31 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.html @@ -0,0 +1,19 @@ +
+ + Friend + + + + {{ option.name }} + + + +
diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.scss b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.scss new file mode 100644 index 00000000..cd07f6cb --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.scss @@ -0,0 +1,11 @@ +.es-chips-autocomplete-story-custom { + &__option-img { + height: 25px; + margin-right: 8px; + vertical-align: middle; + } + + &.mat-form-field { + width: 100%; + } +} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.ts new file mode 100644 index 00000000..b815ceaa --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.ts @@ -0,0 +1,45 @@ +import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; +import { FormGroup, FormBuilder } from '@angular/forms'; +import { GetFilterOptionsByKey } from '../../filter-options'; + +const OPTIONS = [ + { + name: 'Anna', + photo: 'https://joeschmoe.io/api/v1/jenni' + }, + { + name: 'Mary', + photo: 'https://joeschmoe.io/api/v1/julie' + }, + { + name: 'Elena', + photo: 'https://joeschmoe.io/api/v1/jolee' + } +]; + +@Component({ + selector: 'es-chips-autocomplete-story-custom', + templateUrl: './chips-autocomplete-story-custom.component.html', + styleUrls: ['./chips-autocomplete-story-custom.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None +}) +export class ChipsAutocompleteCustomComponent { + public form: FormGroup; + public options: any[] = OPTIONS; + public chips: any[] = []; + + constructor(private formBuilder: FormBuilder) { + this.form = this.formBuilder.group({ + chips: '' + }); + } + + public onChangeText(text: string) { + this.options = GetFilterOptionsByKey(text, OPTIONS, 'name'); + } + + public valueFn(option: any): any { + return option.name; + } +} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.module.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.module.ts new file mode 100644 index 00000000..9766ed13 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { ReactiveFormsModule } from '@angular/forms'; + +import { MatFormFieldModule } from '@angular/material/form-field'; + +import { ESChipsAutocompleteModule } from '../../chips-autocomplete.module'; +import { ChipsAutocompleteCustomComponent } from './chips-autocomplete-story-custom.component'; + +@NgModule({ + declarations: [ChipsAutocompleteCustomComponent], + imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, ESChipsAutocompleteModule], + exports: [ChipsAutocompleteCustomComponent] +}) +export class ESChipsAutocompleteCustomModule {} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html index 4e56021c..f53c3e53 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html @@ -4,6 +4,7 @@ [selectable]="selectable" [removable]="removable" (removed)="onRemove(i)" + [color]="color" > {{ chip }} cancel diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts index fb50d3b3..fbf956f3 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts @@ -74,6 +74,11 @@ export class ChipsAutocompleteComponent */ @Input() public chips: any[]; + /** + * Color of chips + */ + @Input() public color: string; + /** * Change value after a particular time span has passed */ diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx index b7812ef4..234549cf 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx @@ -11,6 +11,7 @@ import { ESChipsAutocompleteModule } from './chips-autocomplete.module'; import { ChipsAutocompleteComponent } from './chips-autocomplete.component'; import { ESChipsAutocompleteBasicModule } from './__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.module'; +import { ESChipsAutocompleteCustomModule } from './__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.module'; @@ -33,6 +34,21 @@ This is a basic story: +## Demos + +This is a custom story: + + + + {{ + template: ``, + moduleMetadata: { + imports: [BrowserAnimationsModule, ESChipsAutocompleteCustomModule] + } + }} + + + ## API From 23100970b91efe6fae08e60e8bd6160b53f589bd Mon Sep 17 00:00:00 2001 From: Anna Date: Fri, 24 Jan 2020 13:48:57 +0300 Subject: [PATCH 3/9] add custom chips component --- ...ps-autocomplete-story-basic.component.html | 1 - ...hips-autocomplete-story-basic.component.ts | 3 +- ...s-autocomplete-story-custom.component.html | 10 +- ...ips-autocomplete-story-custom.component.ts | 8 +- .../ui/chips-autocomplete/chip.directive.ts | 6 + .../chips-autocomplete.component.html | 10 +- .../chips-autocomplete.component.ts | 207 ++++++++++-------- .../chips-autocomplete.module.ts | 11 +- 8 files changed, 156 insertions(+), 100 deletions(-) create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/chip.directive.ts diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html index c10d30e4..bc75e6b4 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html @@ -5,7 +5,6 @@ formControlName="chips" (changeText)="onChangeText($event)" [options]="options" - [chips]="chips" [removable]="true" [selectable]="true" [color]="color" diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.ts index 069876fa..fa818fcc 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.ts @@ -14,12 +14,11 @@ const OPTIONS = ['Apple', 'Lemon', 'Mango']; export class ChipsAutocompleteBasicComponent { public form: FormGroup; public options: any[] = OPTIONS; - public chips: any[] = []; public color = 'accent'; constructor(private formBuilder: FormBuilder) { this.form = this.formBuilder.group({ - chips: '' + chips: [] }); } diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.html index f1b08f31..d582f059 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.html +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.html @@ -1,15 +1,21 @@
- Friend + Friends + + + {{ option.name }} + {{ option.name }} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.ts index b815ceaa..fe7c55c9 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.ts @@ -27,11 +27,11 @@ const OPTIONS = [ export class ChipsAutocompleteCustomComponent { public form: FormGroup; public options: any[] = OPTIONS; - public chips: any[] = []; + public unique = true; constructor(private formBuilder: FormBuilder) { this.form = this.formBuilder.group({ - chips: '' + chips: [] }); } @@ -40,6 +40,10 @@ export class ChipsAutocompleteCustomComponent { } public valueFn(option: any): any { + return option; + } + + public displayWith(option: any): any { return option.name; } } diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chip.directive.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/chip.directive.ts new file mode 100644 index 00000000..66d76606 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chip.directive.ts @@ -0,0 +1,6 @@ +import { Directive } from '@angular/core'; + +@Directive({ + selector: '[esChip]' +}) +export class ChipDirective {} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html index f53c3e53..47300912 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html @@ -1,14 +1,18 @@ - {{ chip }} + {{ displayWith(chip) }} + + + cancel + - + {{ option }} implements MatFormFieldControl, ControlValueAccessor, OnDestroy, OnInit { public separatorKeysCodes = [ENTER, COMMA, SEMICOLON]; + private static nextId = 0; + /** + * @ignore + */ + public text = ''; + /** + * @ignore + */ + public stateChanges = new Subject(); + private text$ = new Subject(); /** * If true this chip list is selectable @@ -67,17 +79,38 @@ export class ChipsAutocompleteComponent /** * Array of options */ - @Input() public options: any[]; + @Input() public options: T[]; /** - * Array of chips + * Color of chips */ - @Input() public chips: any[]; + @Input() public color: string; /** - * Color of chips + * If true the user can choose only unique options */ - @Input() public color: string; + @Input() public unique: false; + + // tslint:disable-next-line variable-name + private _debounceTime: number; + + // tslint:disable-next-line variable-name + private _freeInput: boolean; + + // tslint:disable-next-line variable-name + private _value: T[] = []; + + // tslint:disable-next-line variable-name + private _focused = false; + + // tslint:disable-next-line variable-name + private _required = false; + + // tslint:disable-next-line variable-name + private _disabled = false; + + // tslint:disable-next-line variable-name + private _placeholder = ''; /** * Change value after a particular time span has passed @@ -167,6 +200,63 @@ export class ChipsAutocompleteComponent this.stateChanges.next(); } + /** + * @ignore + */ + @Input() public isLoading = false; + + /** + * Function that maps an option control value to its display value in the trigger + */ + @Input() public displayWith = (option: T): string => { + return '' + option; + }; + + /** + * Function that have chosen value + */ + @Input() public valueFn = (option: any): any => { + return option; + }; + + /** + * Function that have compared values + */ + @Input() compareWith = (a: T, b: T) => a === b; + + /** + * @ignore + */ + isOptionVisible(option: T) { + if (this.unique) { + if (this.value) { + return !this.value.some(e => this.compareWith(e, option)); + } + } else { + return true; + } + } + + /** + * Event emitted when user change text in input + */ + @Output() public changeText = new EventEmitter(); + + @ViewChild('inputChild', { read: MatAutocompleteTrigger, static: true }) + private inputChild: MatAutocompleteTrigger; + @ViewChild('auto', { static: false }) matAutocomplete: MatAutocomplete; + + /** + * Template that allows add custom options + */ + @ContentChild(ChipsAutocompleteOptionDirective, { read: TemplateRef, static: false }) + public optionTemplate: any; + @ContentChild(ChipDirective, { read: TemplateRef, static: false }) + public chipTemplate: any; + + @HostBinding() public id = `es-autocomplete-${ChipsAutocompleteComponent.nextId++}`; + @HostBinding('attr.aria-describedby') public describedBy = ''; + public get errorState(): boolean { const control = this.ngControl; const form = this.ngForm; @@ -177,9 +267,11 @@ export class ChipsAutocompleteComponent return false; } + @HostBinding('class.floating') public get shouldLabelFloat(): boolean { - return this.focused || !!this.text || this.chips.length > 0; + // return this.focused || !!this.text || (this.value && this.value.length > 0); + return false; } /** @@ -211,74 +303,6 @@ export class ChipsAutocompleteComponent }); } - private static nextId = 0; - /** - * @ignore - */ - public text = ''; - /** - * @ignore - */ - public stateChanges = new Subject(); - private text$ = new Subject(); - - /** - * @ignore - */ - @Input() public isLoading = false; - - // tslint:disable-next-line variable-name - private _debounceTime: number; - - // tslint:disable-next-line variable-name - private _freeInput: boolean; - - // tslint:disable-next-line variable-name - private _value = ''; - - // tslint:disable-next-line variable-name - private _focused = false; - - // tslint:disable-next-line variable-name - private _required = false; - - // tslint:disable-next-line variable-name - private _disabled = false; - - // tslint:disable-next-line variable-name - private _placeholder = ''; - - /** - * Event emitted when user change text in input - */ - @Output() public changeText = new EventEmitter(); - - @ViewChild('inputChild', { read: MatAutocompleteTrigger, static: true }) - private inputChild: MatAutocompleteTrigger; - @ViewChild('auto', { static: false }) matAutocomplete: MatAutocomplete; - - /** - * Template that allows add custom options - */ - @ContentChild(ChipsAutocompleteOptionDirective, { read: TemplateRef, static: false }) - public optionTemplate: any; - @HostBinding() public id = `es-autocomplete-${ChipsAutocompleteComponent.nextId++}`; - @HostBinding('attr.aria-describedby') public describedBy = ''; - - /** - * Function that maps an option control value to its display value in the trigger - */ - @Input() public displayWith = (value?: any): string | undefined => { - return value ? value : undefined; - }; - - /** - * Function that have chosen value - */ - @Input() public valueFn = (option: any): any => { - return option; - }; - /** * @ignore */ @@ -326,7 +350,7 @@ export class ChipsAutocompleteComponent * @ignore */ public writeValue(value: any) { - if (value !== undefined) { + if (!!value) { this.value = value; this.text = this.value; this.stateChanges.next(); @@ -382,11 +406,6 @@ export class ChipsAutocompleteComponent public onBlur() { this.onTouched(); this.focused = false; - - if (!this.freeInput) { - this.text = this.value; - } - this.stateChanges.next(); } @@ -394,11 +413,9 @@ export class ChipsAutocompleteComponent * @ignore */ public onSuggestionSelect(event: Event) { - this.value = event; + this.value = this.value.concat(event); this.onChange(this.value); this.stateChanges.next(); - - this.chips.push(event); (this.inputChild as any)._element.nativeElement.value = ''; } @@ -406,7 +423,9 @@ export class ChipsAutocompleteComponent * @ignore */ public onRemove(index: number) { - this.chips.splice(index, 1); + this.value.splice(index, 1); + this.onChange(this.value); + this.stateChanges.next(); } /** @@ -416,10 +435,22 @@ export class ChipsAutocompleteComponent const input = event.input; const value = event.value; - if ((value || '').trim()) { - this.chips.push(value.trim()); + if (this.freeInput) { + if ((value || '').trim()) { + this.value = this.value.concat(value.trim()); + this.onChange(this.value); + this.stateChanges.next(); + } + } else { + const opt = this.options.find( + option => this.displayWith(option).toLowerCase() === value.toLowerCase() + ); + if (opt && !this.value.find(e => this.displayWith(e).toLowerCase() === value.toLowerCase())) { + this.value = this.value.concat(opt); + this.onChange(this.value); + this.stateChanges.next(); + } } - if (input) { input.value = ''; } diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.module.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.module.ts index 5ec4b425..9cdff255 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.module.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.module.ts @@ -8,10 +8,12 @@ import { MatChipsModule } from '@angular/material/chips'; import { MatIconModule } from '@angular/material/icon'; import { ChipsAutocompleteOptionDirective } from './chips-autocomplete.directive'; +import { ChipDirective } from './chip.directive'; + import { ChipsAutocompleteComponent } from './chips-autocomplete.component'; @NgModule({ - declarations: [ChipsAutocompleteComponent, ChipsAutocompleteOptionDirective], + declarations: [ChipsAutocompleteComponent, ChipsAutocompleteOptionDirective, ChipDirective], imports: [ CommonModule, MatAutocompleteModule, @@ -20,6 +22,11 @@ import { ChipsAutocompleteComponent } from './chips-autocomplete.component'; MatChipsModule, MatIconModule ], - exports: [ChipsAutocompleteComponent, ChipsAutocompleteOptionDirective, MatSelectModule] + exports: [ + ChipsAutocompleteComponent, + ChipsAutocompleteOptionDirective, + ChipDirective, + MatSelectModule + ] }) export class ESChipsAutocompleteModule {} From f75ed71d6364c06c58c753162ac7fa03801f7aa3 Mon Sep 17 00:00:00 2001 From: Anna Date: Mon, 27 Jan 2020 12:38:19 +0300 Subject: [PATCH 4/9] add checkbox component --- ...ps-autocomplete-story-basic.component.html | 2 +- ...hips-autocomplete-story-basic.component.ts | 2 +- ...autocomplete-story-checkbox.component.html | 16 ++++++++ ...autocomplete-story-checkbox.component.scss | 5 +++ ...s-autocomplete-story-checkbox.component.ts | 28 ++++++++++++++ ...hips-autocomplete-story-checkbox.module.ts | 16 ++++++++ .../chips-autocomplete.component.html | 20 +++++++--- .../chips-autocomplete.component.scss | 9 +++++ .../chips-autocomplete.component.ts | 38 +++++++++++++++++-- .../chips-autocomplete.module.ts | 4 +- .../chips-autocomplete.stories.mdx | 14 +++++++ 11 files changed, 142 insertions(+), 12 deletions(-) create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.component.html create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.component.scss create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.component.ts create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.module.ts diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html index bc75e6b4..f1f29d24 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html @@ -1,5 +1,5 @@ - + Fruit + + Countries + + + + diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.component.scss b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.component.scss new file mode 100644 index 00000000..0588f18b --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.component.scss @@ -0,0 +1,5 @@ +.es-chips-autocomplete-story-checkbox { + &.mat-form-field { + width: 100%; + } +} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.component.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.component.ts new file mode 100644 index 00000000..48c98a15 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.component.ts @@ -0,0 +1,28 @@ +import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; +import { FormGroup, FormBuilder } from '@angular/forms'; +import { GetFilterOptions } from '../../filter-options'; + +const OPTIONS = ['Russia', 'Spain', 'India']; + +@Component({ + selector: 'es-chips-autocomplete-story-checkbox', + templateUrl: './chips-autocomplete-story-checkbox.component.html', + styleUrls: ['./chips-autocomplete-story-checkbox.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None +}) +export class ChipsAutocompleteCheckboxComponent { + public form: FormGroup; + public options: string[] = OPTIONS; + public withCheckbox = true; + + constructor(private formBuilder: FormBuilder) { + this.form = this.formBuilder.group({ + chips: [] + }); + } + + public onChangeText(text: string) { + this.options = GetFilterOptions(text, OPTIONS); + } +} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.module.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.module.ts new file mode 100644 index 00000000..f8069cc7 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +import { ReactiveFormsModule } from '@angular/forms'; + +import { MatFormFieldModule } from '@angular/material/form-field'; + +import { ESChipsAutocompleteModule } from '../../chips-autocomplete.module'; +import { ChipsAutocompleteCheckboxComponent } from './chips-autocomplete-story-checkbox.component'; + +@NgModule({ + declarations: [ChipsAutocompleteCheckboxComponent], + imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, ESChipsAutocompleteModule], + exports: [ChipsAutocompleteCheckboxComponent] +}) +export class ESChipsAutocompleteCheckboxModule {} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html index 47300912..8fa0c6db 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html @@ -35,12 +35,20 @@ > - {{ option }} - - - +
+ + {{ option }} + + + +
diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.scss b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.scss index b1b06764..dfe933e7 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.scss +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.scss @@ -3,3 +3,12 @@ input { margin: 4px; width: 150px; } + +.es-chips-autocomplete { + &__option-checkbox { + &.mat-checkbox { + margin-left: 12px; + margin-right: 15px; + } + } +} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts index ce694c6e..0909a1dc 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts @@ -91,6 +91,11 @@ export class ChipsAutocompleteComponent */ @Input() public unique: false; + /** + * If true the user have options with checkboxes + */ + @Input() public withCheckbox: false; + // tslint:disable-next-line variable-name private _debounceTime: number; @@ -270,8 +275,7 @@ export class ChipsAutocompleteComponent @HostBinding('class.floating') public get shouldLabelFloat(): boolean { - // return this.focused || !!this.text || (this.value && this.value.length > 0); - return false; + return this.focused || !!this.text || (this.value && this.value.length > 0); } /** @@ -434,7 +438,6 @@ export class ChipsAutocompleteComponent public add(event: MatChipInputEvent) { const input = event.input; const value = event.value; - if (this.freeInput) { if ((value || '').trim()) { this.value = this.value.concat(value.trim()); @@ -455,4 +458,33 @@ export class ChipsAutocompleteComponent input.value = ''; } } + + /** + * @ignore + */ + public onSelect(event: MouseEvent, option: T) { + if (this.withCheckbox) { + event.stopPropagation(); + + if (this.value) { + if (!this.value.find(e => this.compareWith(e, option))) { + this.value = this.value.concat(option); + } else { + this.value.splice(this.value.indexOf(option), 1); + } + this.onChange(this.value); + this.stateChanges.next(); + } + } + } + + /** + * @ignore + */ + public isOptionChecked(option: T): boolean { + if (this.value) { + return this.value.find(e => this.compareWith(e, option)); + } + return false; + } } diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.module.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.module.ts index 9cdff255..6e2c8702 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.module.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.module.ts @@ -6,6 +6,7 @@ import { MatInputModule } from '@angular/material/input'; import { MatSelectModule } from '@angular/material/select'; import { MatChipsModule } from '@angular/material/chips'; import { MatIconModule } from '@angular/material/icon'; +import { MatCheckboxModule } from '@angular/material/checkbox'; import { ChipsAutocompleteOptionDirective } from './chips-autocomplete.directive'; import { ChipDirective } from './chip.directive'; @@ -20,7 +21,8 @@ import { ChipsAutocompleteComponent } from './chips-autocomplete.component'; MatInputModule, MatSelectModule, MatChipsModule, - MatIconModule + MatIconModule, + MatCheckboxModule ], exports: [ ChipsAutocompleteComponent, diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx index 234549cf..22585627 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx @@ -12,6 +12,7 @@ import { ChipsAutocompleteComponent } from './chips-autocomplete.component'; import { ESChipsAutocompleteBasicModule } from './__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.module'; import { ESChipsAutocompleteCustomModule } from './__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.module'; +import { ESChipsAutocompleteCheckboxModule } from './__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.module'; @@ -49,6 +50,19 @@ This is a custom story: +This is a checkbox story: + + + + {{ + template: ``, + moduleMetadata: { + imports: [BrowserAnimationsModule, ESChipsAutocompleteCheckboxModule] + } + }} + + + ## API From 0a1ca59cdbd8405b36509f4cb7c70aad962230ea Mon Sep 17 00:00:00 2001 From: Anna Date: Mon, 27 Jan 2020 12:48:19 +0300 Subject: [PATCH 5/9] Fix chips autocomplete dropdown position --- .../chips-autocomplete.component.html | 1 + .../chips-autocomplete.component.scss | 12 +++++----- .../chips-autocomplete.component.ts | 24 +++++++++++++++---- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html index 8fa0c6db..2552db9b 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html @@ -17,6 +17,7 @@ matInput #inputChild [matAutocomplete]="auto" + [matAutocompleteConnectedTo]="origin" [matChipInputFor]="chipList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes" [value]="text" diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.scss b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.scss index dfe933e7..b2a08072 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.scss +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.scss @@ -1,9 +1,3 @@ -input { - flex: 1 0 150px; - margin: 4px; - width: 150px; -} - .es-chips-autocomplete { &__option-checkbox { &.mat-checkbox { @@ -12,3 +6,9 @@ input { } } } + +input { + flex: 1 0 150px; + margin: 4px; + width: 150px; +} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts index 0909a1dc..a5143f71 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts @@ -15,15 +15,20 @@ import { ContentChild, TemplateRef, InjectionToken, - Inject + Inject, + Host } from '@angular/core'; import { ControlValueAccessor, NgControl, FormGroupDirective } from '@angular/forms'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; -import { MatFormFieldControl } from '@angular/material/form-field'; -import { MatAutocompleteTrigger, MatAutocomplete } from '@angular/material/autocomplete'; +import { MatFormFieldControl, MatFormField } from '@angular/material/form-field'; +import { + MatAutocompleteTrigger, + MatAutocomplete, + MatAutocompleteOrigin +} from '@angular/material/autocomplete'; import { Subject, timer } from 'rxjs'; import { debounce } from 'rxjs/operators'; @@ -66,6 +71,11 @@ export class ChipsAutocompleteComponent public stateChanges = new Subject(); private text$ = new Subject(); + /** + * @ignore + */ + public origin: MatAutocompleteOrigin; + /** * If true this chip list is selectable */ @@ -288,7 +298,8 @@ export class ChipsAutocompleteComponent public ngForm: FormGroupDirective, @Optional() @Inject(ES_CHIPS_DEFAULT_OPTIONS) - private autocompleteDefaultOptions: EsAutocompleteDefaultOptions + private autocompleteDefaultOptions: EsAutocompleteDefaultOptions, + @Optional() @Host() private matFormField: MatFormField ) { if (this.ngControl != null) { this.ngControl.valueAccessor = this; @@ -314,6 +325,11 @@ export class ChipsAutocompleteComponent this.text$.pipe(debounce(() => timer(this.debounceTime))).subscribe(text => { this.changeText.emit(text); }); + if (this.matFormField) { + this.origin = { + elementRef: this.matFormField.getConnectedOverlayOrigin() + }; + } } /** From 986d3b81a22071670ab3c44fe2bfcd2b236aa88b Mon Sep 17 00:00:00 2001 From: Anna Date: Mon, 27 Jan 2020 14:40:53 +0300 Subject: [PATCH 6/9] add InjectionToken to component --- ...ps-autocomplete-story-basic.component.html | 2 - .../chips-autocomplete-story-basic.module.ts | 5 +- ...autocomplete-story-checkbox.component.html | 4 - ...hips-autocomplete-story-checkbox.module.ts | 15 +++- ...s-autocomplete-story-custom.component.html | 4 - ...ips-autocomplete-story-custom.component.ts | 1 - .../chips-autocomplete-story-custom.module.ts | 15 +++- .../chips-autocomplete.component.ts | 90 +++++++++++++++---- 8 files changed, 107 insertions(+), 29 deletions(-) diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html index f1f29d24..5280ffaf 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html @@ -5,8 +5,6 @@ formControlName="chips" (changeText)="onChangeText($event)" [options]="options" - [removable]="true" - [selectable]="true" [color]="color" >
diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.module.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.module.ts index c32f5cb5..c06243cb 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.module.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.module.ts @@ -18,7 +18,10 @@ import { ChipsAutocompleteBasicComponent } from './chips-autocomplete-story-basi provide: ES_CHIPS_DEFAULT_OPTIONS, useValue: { debounceTime: 1000, - freeInput: true + freeInput: true, + unique: true, + selectable: true, + removable: true } } ] diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.component.html index 5299cfed..6d6687c9 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.component.html +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.component.html @@ -5,10 +5,6 @@ formControlName="chips" (changeText)="onChangeText($event)" [options]="options" - [removable]="true" - [selectable]="true" - [freeInput]="false" - [unique]="false" [withCheckbox]="withCheckbox" >
diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.module.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.module.ts index f8069cc7..c934fe10 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.module.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.module.ts @@ -5,12 +5,25 @@ import { ReactiveFormsModule } from '@angular/forms'; import { MatFormFieldModule } from '@angular/material/form-field'; +import { ES_CHIPS_DEFAULT_OPTIONS } from '../../chips-autocomplete.component'; import { ESChipsAutocompleteModule } from '../../chips-autocomplete.module'; import { ChipsAutocompleteCheckboxComponent } from './chips-autocomplete-story-checkbox.component'; @NgModule({ declarations: [ChipsAutocompleteCheckboxComponent], imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, ESChipsAutocompleteModule], - exports: [ChipsAutocompleteCheckboxComponent] + exports: [ChipsAutocompleteCheckboxComponent], + providers: [ + { + provide: ES_CHIPS_DEFAULT_OPTIONS, + useValue: { + debounceTime: 1000, + freeInput: false, + unique: false, + selectable: true, + removable: true + } + } + ] }) export class ESChipsAutocompleteCheckboxModule {} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.html index d582f059..d7f6d4cb 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.html +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.html @@ -5,12 +5,8 @@ formControlName="chips" (changeText)="onChangeText($event)" [options]="options" - [removable]="true" - [selectable]="true" [valueFn]="valueFn" [displayWith]="displayWith" - [freeInput]="false" - [unique]="unique" > diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.ts index fe7c55c9..bb2b5fab 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.ts @@ -27,7 +27,6 @@ const OPTIONS = [ export class ChipsAutocompleteCustomComponent { public form: FormGroup; public options: any[] = OPTIONS; - public unique = true; constructor(private formBuilder: FormBuilder) { this.form = this.formBuilder.group({ diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.module.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.module.ts index 9766ed13..2edcf3e0 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.module.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.module.ts @@ -5,12 +5,25 @@ import { ReactiveFormsModule } from '@angular/forms'; import { MatFormFieldModule } from '@angular/material/form-field'; +import { ES_CHIPS_DEFAULT_OPTIONS } from '../../chips-autocomplete.component'; import { ESChipsAutocompleteModule } from '../../chips-autocomplete.module'; import { ChipsAutocompleteCustomComponent } from './chips-autocomplete-story-custom.component'; @NgModule({ declarations: [ChipsAutocompleteCustomComponent], imports: [CommonModule, ReactiveFormsModule, MatFormFieldModule, ESChipsAutocompleteModule], - exports: [ChipsAutocompleteCustomComponent] + exports: [ChipsAutocompleteCustomComponent], + providers: [ + { + provide: ES_CHIPS_DEFAULT_OPTIONS, + useValue: { + debounceTime: 1000, + freeInput: false, + unique: true, + selectable: true, + removable: true + } + } + ] }) export class ESChipsAutocompleteCustomModule {} diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts index a5143f71..4d90a49a 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts @@ -47,6 +47,9 @@ export const ES_CHIPS_DEFAULT_OPTIONS = new InjectionToken */ public origin: MatAutocompleteOrigin; - /** - * If true this chip list is selectable - */ - @Input() public selectable: boolean; - - /** - * If true this chip list is removable - */ - @Input() public removable: boolean; - /** * Array of options */ @@ -96,11 +89,6 @@ export class ChipsAutocompleteComponent */ @Input() public color: string; - /** - * If true the user can choose only unique options - */ - @Input() public unique: false; - /** * If true the user have options with checkboxes */ @@ -112,6 +100,15 @@ export class ChipsAutocompleteComponent // tslint:disable-next-line variable-name private _freeInput: boolean; + // tslint:disable-next-line variable-name + private _unique: boolean; + + // tslint:disable-next-line variable-name + private _selectable: boolean; + + // tslint:disable-next-line variable-name + private _removable: boolean; + // tslint:disable-next-line variable-name private _value: T[] = []; @@ -157,6 +154,54 @@ export class ChipsAutocompleteComponent : false; } + /** + * If true the user can choose only unique options + */ + @Input() + public get unique(): boolean { + return this._unique; + } + public set unique(value: boolean) { + this._unique = + value !== undefined + ? value + : this.autocompleteDefaultOptions && this.autocompleteDefaultOptions.unique + ? this.autocompleteDefaultOptions.unique + : false; + } + + /** + * If true this chip list is selectable + */ + @Input() + public get selectable(): boolean { + return this._selectable; + } + public set selectable(value: boolean) { + this._selectable = + value !== undefined + ? value + : this.autocompleteDefaultOptions && this.autocompleteDefaultOptions.selectable + ? this.autocompleteDefaultOptions.selectable + : false; + } + + /** + * If true this chip list is removable + */ + @Input() + public get removable(): boolean { + return this._removable; + } + public set removable(value: boolean) { + this._removable = + value !== undefined + ? value + : this.autocompleteDefaultOptions && this.autocompleteDefaultOptions.removable + ? this.autocompleteDefaultOptions.removable + : false; + } + public get value(): any { return this._value; } @@ -313,6 +358,21 @@ export class ChipsAutocompleteComponent ? autocompleteDefaultOptions.freeInput : false; + this.unique = + autocompleteDefaultOptions && autocompleteDefaultOptions.unique + ? autocompleteDefaultOptions.unique + : false; + + this.selectable = + autocompleteDefaultOptions && autocompleteDefaultOptions.selectable + ? autocompleteDefaultOptions.selectable + : false; + + this.removable = + autocompleteDefaultOptions && autocompleteDefaultOptions.removable + ? autocompleteDefaultOptions.removable + : false; + this.stateChanges.subscribe(() => { this.changeDetector.detectChanges(); }); From 2e3a908e498c9706d9258e9d38617f7a63d33578 Mon Sep 17 00:00:00 2001 From: Anna Date: Mon, 27 Jan 2020 15:01:43 +0300 Subject: [PATCH 7/9] fix documentation --- .../chips-autocomplete.component.ts | 87 ++++++++++--------- .../chips-autocomplete.stories.mdx | 6 +- 2 files changed, 48 insertions(+), 45 deletions(-) diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts index 4d90a49a..e14e7777 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts @@ -29,6 +29,7 @@ import { MatAutocomplete, MatAutocompleteOrigin } from '@angular/material/autocomplete'; +import { MatChipInputEvent } from '@angular/material/chips'; import { Subject, timer } from 'rxjs'; import { debounce } from 'rxjs/operators'; @@ -36,8 +37,6 @@ import { debounce } from 'rxjs/operators'; import { ChipsAutocompleteOptionDirective } from '../chips-autocomplete/chips-autocomplete.directive'; import { ChipDirective } from '../chips-autocomplete/chip.directive'; -import { MatChipInputEvent } from '@angular/material/chips'; - import { ENTER, COMMA, SEMICOLON } from '@angular/cdk/keycodes'; export const ES_CHIPS_DEFAULT_OPTIONS = new InjectionToken( @@ -74,25 +73,31 @@ export class ChipsAutocompleteComponent public stateChanges = new Subject(); private text$ = new Subject(); - /** - * @ignore - */ - public origin: MatAutocompleteOrigin; + public get value(): any { + return this._value; + } - /** - * Array of options - */ - @Input() public options: T[]; + public set value(value: any) { + this._value = value; + this.stateChanges.next(); + } - /** - * Color of chips - */ - @Input() public color: string; + public get focused() { + return this._focused; + } + public set focused(focused: boolean) { + this._focused = focused; + this.stateChanges.next(); + } + + public get empty(): boolean { + return !this.value; + } /** - * If true the user have options with checkboxes + * @ignore */ - @Input() public withCheckbox: false; + public origin: MatAutocompleteOrigin; // tslint:disable-next-line variable-name private _debounceTime: number; @@ -124,6 +129,21 @@ export class ChipsAutocompleteComponent // tslint:disable-next-line variable-name private _placeholder = ''; + /** + * Array of options + */ + @Input() public options: T[]; + + /** + * Color of chips + */ + @Input() public color: string; + + /** + * If true the user have options with checkbox + */ + @Input() public withCheckbox: false; + /** * Change value after a particular time span has passed */ @@ -155,7 +175,7 @@ export class ChipsAutocompleteComponent } /** - * If true the user can choose only unique options + * If true the user can choose only unique option */ @Input() public get unique(): boolean { @@ -171,7 +191,7 @@ export class ChipsAutocompleteComponent } /** - * If true this chip list is selectable + * If true this chips list is selectable */ @Input() public get selectable(): boolean { @@ -187,7 +207,7 @@ export class ChipsAutocompleteComponent } /** - * If true this chip list is removable + * If true this chips list is removable */ @Input() public get removable(): boolean { @@ -202,27 +222,6 @@ export class ChipsAutocompleteComponent : false; } - public get value(): any { - return this._value; - } - - public set value(value: any) { - this._value = value; - this.stateChanges.next(); - } - - public get focused() { - return this._focused; - } - public set focused(focused: boolean) { - this._focused = focused; - this.stateChanges.next(); - } - - public get empty(): boolean { - return !this.value; - } - /** * This property is used to indicate whether the input is required */ @@ -282,12 +281,12 @@ export class ChipsAutocompleteComponent /** * Function that have compared values */ - @Input() compareWith = (a: T, b: T) => a === b; + @Input() public compareWith = (a: T, b: T) => a === b; /** * @ignore */ - isOptionVisible(option: T) { + public isOptionVisible(option: T): boolean { if (this.unique) { if (this.value) { return !this.value.some(e => this.compareWith(e, option)); @@ -311,6 +310,10 @@ export class ChipsAutocompleteComponent */ @ContentChild(ChipsAutocompleteOptionDirective, { read: TemplateRef, static: false }) public optionTemplate: any; + + /** + * Template that allows add custom chips + */ @ContentChild(ChipDirective, { read: TemplateRef, static: false }) public chipTemplate: any; diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx index 22585627..8dc56b6b 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx @@ -25,7 +25,7 @@ This component demonstrates usage of chips autocomplete. This is a basic story: - + {{ template: ``, moduleMetadata: { @@ -40,7 +40,7 @@ This is a basic story: This is a custom story: - + {{ template: ``, moduleMetadata: { @@ -53,7 +53,7 @@ This is a custom story: This is a checkbox story: - + {{ template: ``, moduleMetadata: { From da5dd786ac22f0f8f8842f5bde062b342d3f7bfd Mon Sep 17 00:00:00 2001 From: Anna Date: Mon, 27 Jan 2020 17:13:54 +0300 Subject: [PATCH 8/9] add tests --- ...ps-autocomplete-story-basic.component.html | 2 +- .../chips-autocomplete-story-basic.source.ts | 36 +++++++++ .../chips-autocomplete-story-basic/index.ts | 1 + ...autocomplete-story-checkbox.component.html | 2 +- ...hips-autocomplete-story-checkbox.source.ts | 36 +++++++++ .../index.ts | 1 + ...s-autocomplete-story-custom.component.html | 2 +- .../chips-autocomplete-story-custom.source.ts | 73 +++++++++++++++++++ .../chips-autocomplete-story-custom/index.ts | 1 + .../chips-autocomplete.component.html | 4 +- .../chips-autocomplete.spec.ts | 65 +++++++++++++++++ .../chips-autocomplete.stories.mdx | 11 ++- 12 files changed, 227 insertions(+), 7 deletions(-) create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.source.ts create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/index.ts create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.source.ts create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/index.ts create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.source.ts create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/index.ts create mode 100644 projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.spec.ts diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html index 5280ffaf..454fd836 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.component.html @@ -3,9 +3,9 @@ Fruit
diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.source.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.source.ts new file mode 100644 index 00000000..5819b057 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.source.ts @@ -0,0 +1,36 @@ +export const CHIPS_AUTOCOMPLETE_STORY_BASIC_SOURCE = { + html: ` +
+ + Fruit + + + +
`, + ts: ` + import { GetFilterOptions } from '@elonsoft/elonkit/autocomplete'; + const OPTIONS = ['Apple', 'Lemon', 'Mango']; + + @Component(...) + export class ChipsAutocompleteBasicComponent { + public form: FormGroup; + public options = OPTIONS; + public color = 'accent'; + + constructor(private formBuilder: FormBuilder) { + this.form = this.formBuilder.group({ + chips: [] + }); + } + + public onChangeText(text: string) { + this.options = GetFilterOptions(text, OPTIONS); + } + } + ` +}; diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/index.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/index.ts new file mode 100644 index 00000000..bc1fac50 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/index.ts @@ -0,0 +1 @@ +export { CHIPS_AUTOCOMPLETE_STORY_BASIC_SOURCE } from './chips-autocomplete-story-basic.source'; diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.component.html index 6d6687c9..07eccbee 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.component.html +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.component.html @@ -3,9 +3,9 @@ Countries diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.source.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.source.ts new file mode 100644 index 00000000..bcb6d8c6 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.source.ts @@ -0,0 +1,36 @@ +export const CHIPS_AUTOCOMPLETE_STORY_CHECKBOX_SOURCE = { + html: ` +
+ + Countries + + + +
`, + ts: ` + import { GetFilterOptions } from '@elonsoft/elonkit/autocomplete'; + const OPTIONS = ['Russia', 'Spain', 'India']; + + @Component(...) + export class ChipsAutocompleteCheckboxComponent { + public form: FormGroup; + public options = OPTIONS; + public withCheckbox = true; + + constructor(private formBuilder: FormBuilder) { + this.form = this.formBuilder.group({ + chips: [] + }); + } + + public onChangeText(text: string) { + this.options = GetFilterOptions(text, OPTIONS); + } + } + ` +}; diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/index.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/index.ts new file mode 100644 index 00000000..cf3b14c3 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/index.ts @@ -0,0 +1 @@ +export { CHIPS_AUTOCOMPLETE_STORY_CHECKBOX_SOURCE } from './chips-autocomplete-story-checkbox.source'; diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.html index d7f6d4cb..65394a89 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.html +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.component.html @@ -3,10 +3,10 @@ Friends diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.source.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.source.ts new file mode 100644 index 00000000..18e45375 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.source.ts @@ -0,0 +1,73 @@ +export const CHIPS_AUTOCOMPLETE_STORY_CUSTOM_SOURCE = { + html: ` +
+ + Friends + + + + {{ option.name }} + + + + {{ option.name }} + + + +
`, + ts: ` + import { GetFilterOptionsByKey } from '@elonsoft/elonkit/autocomplete'; + const OPTIONS = [ + { + name: 'Anna', + photo: 'https://joeschmoe.io/api/v1/jenni' + }, + { + name: 'Mary', + photo: 'https://joeschmoe.io/api/v1/julie' + }, + { + name: 'Elena', + photo: 'https://joeschmoe.io/api/v1/jolee' + } + ]; + + @Component(...) + export class ChipsAutocompleteCustomComponent { + public form: FormGroup; + public options = OPTIONS; + + constructor(private formBuilder: FormBuilder) { + this.form = this.formBuilder.group({ + chips: [] + }); + } + public onChangeText(text: string) { + this.options = GetFilterOptionsByKey(text, OPTIONS, 'name'); + } + + public valueFn(option: any): any { + return option; + } + + public displayWith(option: any): any { + return option.name; + } + } + `, + scss: ` + .es-chips-autocomplete-story-custom { + &__option-img { + height: 25px; + margin-right: 8px; + vertical-align: middle; + } + } + ` +}; diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/index.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/index.ts new file mode 100644 index 00000000..8a718f82 --- /dev/null +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/index.ts @@ -0,0 +1 @@ +export { CHIPS_AUTOCOMPLETE_STORY_CUSTOM_SOURCE } from './chips-autocomplete-story-custom.source'; diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html index 2552db9b..abf27891 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.html @@ -5,6 +5,7 @@ [removable]="removable" (removed)="onRemove(i)" [color]="color" + data-testid="mat-chip" > {{ displayWith(chip) }} @@ -26,6 +27,7 @@ (focus)="onFocus()" (blur)="onBlur()" (matChipInputTokenEnd)="add($event)" + data-testid="input" /> @@ -35,7 +37,7 @@ (optionSelected)="onSuggestionSelect($event.option.value)" > - +
{ + describe('Base', () => { + let component: RenderResult, ChipsAutocompleteComponent>; + let overlay: OverlayContainer; + let overlayElement: HTMLElement; + + beforeEach(async () => { + component = await render(ChipsAutocompleteComponent, { + imports: [ESChipsAutocompleteModule], + componentProperties: { + options: FRUITS + }, + excludeComponentDeclaration: true + }); + + inject([OverlayContainer], (oc: OverlayContainer) => { + overlay = oc; + overlayElement = oc.getContainerElement(); + })(); + }); + + afterEach(inject([OverlayContainer], (currentOverlay: OverlayContainer) => { + currentOverlay.ngOnDestroy(); + overlay.ngOnDestroy(); + })); + + it('Should display passed options', fakeAsync(async () => { + const input = component.getByTestId('input'); + + component.focusIn(input); + + const options = overlayElement.querySelectorAll('[data-testid="mat-option"]'); + expect(options).toHaveLength(3); + + // all items of FRUITS array contain in overlay + for (const fruit of FRUITS) { + expect(overlayElement.textContent).toContain(fruit); + } + })); + + it('Should display chips after chose option', fakeAsync(async () => { + const TEXT_APPLE = 'Apple'; + + const input = component.getByTestId('input'); + component.focusIn(input); + + const options = overlayElement.querySelectorAll('[data-testid="mat-option"]'); + component.click(options[0]); + + const chips = component.getAllByTestId('mat-chip'); + expect(chips).toHaveLength(1); + expect(component.getByText(TEXT_APPLE)).toBeInTheDocument(); + })); + }); +}); diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx index 8dc56b6b..eb39807d 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx @@ -11,8 +11,13 @@ import { ESChipsAutocompleteModule } from './chips-autocomplete.module'; import { ChipsAutocompleteComponent } from './chips-autocomplete.component'; import { ESChipsAutocompleteBasicModule } from './__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.module'; +import { CHIPS_AUTOCOMPLETE_STORY_BASIC_SOURCE } from './__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.source'; + import { ESChipsAutocompleteCustomModule } from './__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.module'; +import { CHIPS_AUTOCOMPLETE_STORY_CUSTOM_SOURCE } from './__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.source'; + import { ESChipsAutocompleteCheckboxModule } from './__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.module'; +import { CHIPS_AUTOCOMPLETE_STORY_CHECKBOX_SOURCE } from './__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.source'; @@ -24,7 +29,7 @@ This component demonstrates usage of chips autocomplete. This is a basic story: - + {{ template: ``, @@ -39,7 +44,7 @@ This is a basic story: This is a custom story: - + {{ template: ``, @@ -52,7 +57,7 @@ This is a custom story: This is a checkbox story: - + {{ template: ``, From 881e300704511757d98a9357b890fe8f516b0c13 Mon Sep 17 00:00:00 2001 From: Anna Date: Tue, 28 Jan 2020 10:21:01 +0300 Subject: [PATCH 9/9] add Constants part in mdx file --- .../chips-autocomplete-story-basic.source.ts | 2 +- ...hips-autocomplete-story-checkbox.source.ts | 2 +- .../chips-autocomplete-story-custom.source.ts | 2 +- .../chips-autocomplete.component.ts | 5 +++- .../chips-autocomplete.stories.mdx | 23 +++++++++++++++++++ 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.source.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.source.ts index 5819b057..0b57a478 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.source.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-basic/chips-autocomplete-story-basic.source.ts @@ -13,7 +13,7 @@ export const CHIPS_AUTOCOMPLETE_STORY_BASIC_SOURCE = { `, ts: ` - import { GetFilterOptions } from '@elonsoft/elonkit/autocomplete'; + import { GetFilterOptions } from '@elonsoft/elonkit/chips-autocomplete'; const OPTIONS = ['Apple', 'Lemon', 'Mango']; @Component(...) diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.source.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.source.ts index bcb6d8c6..d361bb98 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.source.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-checkbox/chips-autocomplete-story-checkbox.source.ts @@ -13,7 +13,7 @@ export const CHIPS_AUTOCOMPLETE_STORY_CHECKBOX_SOURCE = { `, ts: ` - import { GetFilterOptions } from '@elonsoft/elonkit/autocomplete'; + import { GetFilterOptions } from '@elonsoft/elonkit/chips-autocomplete'; const OPTIONS = ['Russia', 'Spain', 'India']; @Component(...) diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.source.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.source.ts index 18e45375..1adbd5b9 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.source.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/__stories__/chips-autocomplete-story-custom/chips-autocomplete-story-custom.source.ts @@ -22,7 +22,7 @@ export const CHIPS_AUTOCOMPLETE_STORY_CUSTOM_SOURCE = { `, ts: ` - import { GetFilterOptionsByKey } from '@elonsoft/elonkit/autocomplete'; + import { GetFilterOptionsByKey } from '@elonsoft/elonkit/chips-autocomplete'; const OPTIONS = [ { name: 'Anna', diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts index e14e7777..c8db6ed8 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.component.ts @@ -61,6 +61,9 @@ export interface EsAutocompleteDefaultOptions { }) export class ChipsAutocompleteComponent implements MatFormFieldControl, ControlValueAccessor, OnDestroy, OnInit { + /** + * The list of key codes that will trigger a chipEnd event + */ public separatorKeysCodes = [ENTER, COMMA, SEMICOLON]; private static nextId = 0; /** @@ -303,7 +306,7 @@ export class ChipsAutocompleteComponent @ViewChild('inputChild', { read: MatAutocompleteTrigger, static: true }) private inputChild: MatAutocompleteTrigger; - @ViewChild('auto', { static: false }) matAutocomplete: MatAutocomplete; + @ViewChild('auto', { static: false }) private matAutocomplete: MatAutocomplete; /** * Template that allows add custom options diff --git a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx index eb39807d..0f338526 100644 --- a/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx +++ b/projects/elonkit/src/lib/ui/chips-autocomplete/chips-autocomplete.stories.mdx @@ -71,3 +71,26 @@ This is a checkbox story: ## API + +## Constants + +Injection token to be used to override the default options for es-chips-autocomplete + +```ts +import { ES_CHIPS_DEFAULT_OPTIONS } from '@elonsoft/elonkit/chips-autocomplete'; + +@NgModule({ + providers: [ + { + provide: ES_CHIPS_DEFAULT_OPTIONS, + useValue: { + debounceTime: 1000, + freeInput: true, + unique: true, + selectable: true, + removable: true + } + } + ] +}) +```