From ddce3f82ea360a3bfbe490d93d5ce7481b6d4c8b Mon Sep 17 00:00:00 2001 From: Anna Date: Mon, 13 Jan 2020 10:16:39 +0300 Subject: [PATCH 01/31] create autocomplete component --- .../ui/autocomplete/autocomplete.component.html | 4 ++++ .../ui/autocomplete/autocomplete.component.scss | 3 +++ .../ui/autocomplete/autocomplete.component.ts | 10 ++++++++++ .../lib/ui/autocomplete/autocomplete.module.ts | 12 ++++++++++++ .../lib/ui/autocomplete/autocomplete.stories.ts | 16 ++++++++++++++++ 5 files changed, 45 insertions(+) create mode 100644 projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html create mode 100644 projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss create mode 100644 projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts create mode 100644 projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts create mode 100644 projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html new file mode 100644 index 00000000..be3f962d --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html @@ -0,0 +1,4 @@ +

+ autocomplete +

+ diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss new file mode 100644 index 00000000..fd5f066a --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss @@ -0,0 +1,3 @@ +.es-autocomplete { + color: #212aac; +} diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts new file mode 100644 index 00000000..6ee67937 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts @@ -0,0 +1,10 @@ +import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; + +@Component({ + selector: 'es-autocomplete', + templateUrl: './autocomplete.component.html', + styleUrls: ['./autocomplete.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None +}) +export class AutocompleteComponent {} diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts new file mode 100644 index 00000000..454f5c69 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core'; + +import { MatButtonModule } from '@angular/material/button'; + +import { AutocompleteComponent } from './autocomplete.component'; + +@NgModule({ + declarations: [AutocompleteComponent], + imports: [MatButtonModule], + exports: [AutocompleteComponent] +}) +export class AutocompleteModule {} diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.ts new file mode 100644 index 00000000..45a03833 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.ts @@ -0,0 +1,16 @@ +import { withKnobs, text } from '@storybook/addon-knobs'; +import { action } from '@storybook/addon-actions'; +import { withA11y } from '@storybook/addon-a11y'; + +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; + +import { AutocompleteModule } from './autocomplete.module'; + +export default { title: 'Autocomplete', decorators: [withKnobs, withA11y] }; + +export const Autocomplete = () => ({ + template: `autocomplete`, + moduleMetadata: { + imports: [AutocompleteModule, BrowserAnimationsModule] + } +}); From b2d9325f85e2575c1f20003085f24721b21d67a3 Mon Sep 17 00:00:00 2001 From: Anna Date: Mon, 13 Jan 2020 11:14:44 +0300 Subject: [PATCH 02/31] add mdx storybook documentation --- .../ui/autocomplete/autocomplete.stories.mdx | 35 +++++++++++++++++++ .../ui/autocomplete/autocomplete.stories.ts | 16 --------- 2 files changed, 35 insertions(+), 16 deletions(-) create mode 100644 projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx delete mode 100644 projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx new file mode 100644 index 00000000..bf9c53b4 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx @@ -0,0 +1,35 @@ +import { Meta, Preview, Story, Props } from '@storybook/addon-docs/blocks'; + +import { withKnobs, text } from '@storybook/addon-knobs'; +import { action } from '@storybook/addon-actions'; +import { withA11y } from '@storybook/addon-a11y'; + +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; + +import { AutocompleteModule } from './autocomplete.module'; +import { AutocompleteComponent } from './autocomplete.component'; + + + +# Autocomplete + +This component demonstrates usage of storybook. + +## Demos + +This is a basic story: + + + + {{ + template: `autocomplete`, + moduleMetadata: { + imports: [BrowserAnimationsModule, AutocompleteModule] + } + }} + + + +## API + + diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.ts deleted file mode 100644 index 45a03833..00000000 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { withKnobs, text } from '@storybook/addon-knobs'; -import { action } from '@storybook/addon-actions'; -import { withA11y } from '@storybook/addon-a11y'; - -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; - -import { AutocompleteModule } from './autocomplete.module'; - -export default { title: 'Autocomplete', decorators: [withKnobs, withA11y] }; - -export const Autocomplete = () => ({ - template: `autocomplete`, - moduleMetadata: { - imports: [AutocompleteModule, BrowserAnimationsModule] - } -}); From e8012dc528da886cc6cbc4819c1b12065f252649 Mon Sep 17 00:00:00 2001 From: Anna Date: Mon, 13 Jan 2020 13:24:43 +0300 Subject: [PATCH 03/31] add simple autocomplete element --- .../ui/autocomplete/autocomplete.component.html | 10 ++++++---- .../ui/autocomplete/autocomplete.component.scss | 4 +++- .../ui/autocomplete/autocomplete.component.ts | 16 +++++++++++++++- .../lib/ui/autocomplete/autocomplete.module.ts | 7 +++++-- .../elonkit/src/lib/ui/autocomplete/index.ts | 2 ++ 5 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 projects/elonkit/src/lib/ui/autocomplete/index.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html index be3f962d..f4dbb491 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html @@ -1,4 +1,6 @@ -

- autocomplete -

- + + + + {{ option }} + + diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss index fd5f066a..8d0ed21f 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss @@ -1,3 +1,5 @@ .es-autocomplete { - color: #212aac; + // &.mat-autocomplete-panel { + // max-height: 320px !important; + // } } diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts index 6ee67937..22f3c315 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts @@ -7,4 +7,18 @@ import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None }) -export class AutocompleteComponent {} +export class AutocompleteComponent { + text = ''; + options: string[] = ['One', 'Two', 'Three']; + + public onInput(event: Event) { + const target = event.target as HTMLInputElement; + this.text = target.value; + console.log(this.text); + } + + public displayWith(suggestion?: any): string | undefined { + console.log(suggestion); + return suggestion ? suggestion : undefined; + } +} diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts index 454f5c69..65c6fee9 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts @@ -1,12 +1,15 @@ import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; -import { MatButtonModule } from '@angular/material/button'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; import { AutocompleteComponent } from './autocomplete.component'; @NgModule({ declarations: [AutocompleteComponent], - imports: [MatButtonModule], + imports: [CommonModule, MatAutocompleteModule, MatFormFieldModule, MatInputModule], exports: [AutocompleteComponent] }) export class AutocompleteModule {} diff --git a/projects/elonkit/src/lib/ui/autocomplete/index.ts b/projects/elonkit/src/lib/ui/autocomplete/index.ts new file mode 100644 index 00000000..49f6aa0a --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/index.ts @@ -0,0 +1,2 @@ +export { AutocompleteModule } from './autocomplete.module'; +export { AutocompleteComponent } from './autocomplete.component'; From c4564ad8429d7687aceb4b2008fb443747a28328 Mon Sep 17 00:00:00 2001 From: Anna Date: Mon, 13 Jan 2020 14:06:04 +0300 Subject: [PATCH 04/31] create autocomplete form wrapper --- .../autocomplete-form.component.html | 5 +++ .../autocomplete-form.component.scss | 5 +++ .../autocomplete-form.component.ts | 19 ++++++++++ .../__stories__/autocomplete-form.module.ts | 16 +++++++++ .../__stories__/autocomplete-form.stories.mdx | 35 +++++++++++++++++++ .../autocomplete/autocomplete.component.scss | 6 +--- .../ui/autocomplete/autocomplete.module.ts | 3 +- 7 files changed, 82 insertions(+), 7 deletions(-) create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.scss create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.ts create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.module.ts create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.stories.mdx diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html new file mode 100644 index 00000000..cbe9fea9 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html @@ -0,0 +1,5 @@ +
+ + autocomplete + +
diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.scss b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.scss new file mode 100644 index 00000000..a8c91081 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.scss @@ -0,0 +1,5 @@ +.es-autocomplete-form { + // &.mat-autocomplete-panel { + // max-height: 320px !important; + // } +} diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.ts new file mode 100644 index 00000000..caf41c52 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.ts @@ -0,0 +1,19 @@ +import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; +import { FormGroup, FormBuilder } from '@angular/forms'; + +@Component({ + selector: 'es-autocomplete-form', + templateUrl: './autocomplete-form.component.html', + styleUrls: ['./autocomplete-form.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None +}) +export class AutocompleteFormComponent { + form: FormGroup; + constructor(private formBuilder: FormBuilder) { + this.form = this.formBuilder.group({ + autocomplete: [''] + }); + } + onSubmit() {} +} diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.module.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.module.ts new file mode 100644 index 00000000..ab29c2c1 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule } from '@angular/forms'; + +import { AutocompleteModule } from '../autocomplete.module'; + +import { MatFormFieldModule } from '@angular/material/form-field'; + +import { AutocompleteFormComponent } from './autocomplete-form.component'; + +@NgModule({ + declarations: [AutocompleteFormComponent], + imports: [CommonModule, ReactiveFormsModule, AutocompleteModule, MatFormFieldModule], + exports: [AutocompleteFormComponent] +}) +export class AutocompleteFormModule {} diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.stories.mdx b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.stories.mdx new file mode 100644 index 00000000..d8aecf4f --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.stories.mdx @@ -0,0 +1,35 @@ +import { Meta, Preview, Story, Props } from '@storybook/addon-docs/blocks'; + +import { withKnobs, text } from '@storybook/addon-knobs'; +import { action } from '@storybook/addon-actions'; +import { withA11y } from '@storybook/addon-a11y'; + +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; + +import { AutocompleteFormModule } from './autocomplete-form.module'; +import { AutocompleteFormComponent } from './autocomplete-form.component'; + + + +# Autocomplete + +This component demonstrates usage of storybook. + +## Demos + +This is a basic story: + + + + {{ + template: ``, + moduleMetadata: { + imports: [BrowserAnimationsModule, AutocompleteFormModule] + } + }} + + + +## API + + diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss index 8d0ed21f..8b137891 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss @@ -1,5 +1 @@ -.es-autocomplete { - // &.mat-autocomplete-panel { - // max-height: 320px !important; - // } -} + diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts index 65c6fee9..e456223e 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts @@ -2,14 +2,13 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatInputModule } from '@angular/material/input'; import { AutocompleteComponent } from './autocomplete.component'; @NgModule({ declarations: [AutocompleteComponent], - imports: [CommonModule, MatAutocompleteModule, MatFormFieldModule, MatInputModule], + imports: [CommonModule, MatAutocompleteModule, MatInputModule], exports: [AutocompleteComponent] }) export class AutocompleteModule {} From 7719622648c4c54c2fc0c77b425353d895e70260 Mon Sep 17 00:00:00 2001 From: Anna Date: Mon, 13 Jan 2020 18:29:06 +0300 Subject: [PATCH 05/31] create custom value accessor --- .../autocomplete-form.component.html | 4 +- .../autocomplete-form.component.scss | 6 +- .../autocomplete-form.component.ts | 8 +- .../__stories__/autocomplete-form.module.ts | 12 +- .../autocomplete/autocomplete.component.html | 16 +- .../autocomplete/autocomplete.component.scss | 1 - .../ui/autocomplete/autocomplete.component.ts | 175 +++++++++++++++++- 7 files changed, 206 insertions(+), 16 deletions(-) diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html index cbe9fea9..8ab96f3d 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html @@ -1,5 +1,7 @@
- + + Введите сообщение autocomplete + diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.scss b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.scss index a8c91081..2d89bece 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.scss +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.scss @@ -1,5 +1,5 @@ .es-autocomplete-form { - // &.mat-autocomplete-panel { - // max-height: 320px !important; - // } + &.mat-form-field { + width: 100%; + } } diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.ts index caf41c52..7b445985 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.ts @@ -10,10 +10,16 @@ import { FormGroup, FormBuilder } from '@angular/forms'; }) export class AutocompleteFormComponent { form: FormGroup; + constructor(private formBuilder: FormBuilder) { this.form = this.formBuilder.group({ autocomplete: [''] }); } - onSubmit() {} + + onSubmit() { + if (this.form.valid) { + console.log(this.form.value); + } + } } diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.module.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.module.ts index ab29c2c1..5532c5b2 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.module.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.module.ts @@ -6,11 +6,21 @@ import { AutocompleteModule } from '../autocomplete.module'; import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; +import { MatInputModule } from '@angular/material/input'; + import { AutocompleteFormComponent } from './autocomplete-form.component'; @NgModule({ declarations: [AutocompleteFormComponent], - imports: [CommonModule, ReactiveFormsModule, AutocompleteModule, MatFormFieldModule], + imports: [ + CommonModule, + MatAutocompleteModule, + MatInputModule, + ReactiveFormsModule, + AutocompleteModule, + MatFormFieldModule + ], exports: [AutocompleteFormComponent] }) export class AutocompleteFormModule {} diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html index f4dbb491..e34f8219 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html @@ -1,5 +1,17 @@ - - + + {{ option }} diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss index 8b137891..e69de29b 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss @@ -1 +0,0 @@ - diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts index 22f3c315..54368102 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts @@ -1,24 +1,185 @@ -import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; +import { + Component, + ChangeDetectionStrategy, + ViewEncapsulation, + OnDestroy, + HostBinding, + Optional, + Self, + Input +} from '@angular/core'; +import { MatFormFieldControl } from '@angular/material/form-field'; +import { Subject } from 'rxjs'; +import { NgControl, ControlValueAccessor, FormGroupDirective } from '@angular/forms'; +import { coerceBooleanProperty } from '@angular/cdk/coercion'; @Component({ selector: 'es-autocomplete', templateUrl: './autocomplete.component.html', styleUrls: ['./autocomplete.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, - encapsulation: ViewEncapsulation.None + encapsulation: ViewEncapsulation.None, + providers: [{ provide: MatFormFieldControl, useExisting: AutocompleteComponent }] }) -export class AutocompleteComponent { - text = ''; - options: string[] = ['One', 'Two', 'Three']; +export class AutocompleteComponent + implements MatFormFieldControl, ControlValueAccessor, OnDestroy { + public get value(): any { + return this._value; + } + + public set value(value: any) { + this._value = value; + this.stateChanges.next(); + } + + constructor( + @Optional() @Self() public ngControl: NgControl, + @Optional() + public ngForm: FormGroupDirective + ) { + if (this.ngControl != null) { + this.ngControl.valueAccessor = this; + } + } + static nextId = 0; + // tslint:disable-next-line variable-name + private _disabled = false; + // tslint:disable-next-line variable-name + private _required = false; + // tslint:disable-next-line variable-name + private _focused = false; + // tslint:disable-next-line variable-name + private _placeholder = ''; + + public get focused() { + return this._focused; + } + public set focused(focused: boolean) { + this._focused = focused; + this.stateChanges.next(); + } + + public get empty(): boolean { + return !this.value; + } + + public text = ''; + public options: string[] = ['One', 'Two', 'Three']; + + // tslint:disable-next-line variable-name + private _value = ''; + + public stateChanges = new Subject(); + + @HostBinding() public id = `es-autocomplete-${AutocompleteComponent.nextId++}`; + @HostBinding('class.floating') + public get shouldLabelFloat() { + return this.focused || !!this.text; + } + + @Input() + public get required() { + return this._required; + } + public set required(req) { + this._required = coerceBooleanProperty(req); + this.stateChanges.next(); + } + + @Input() + public get disabled(): boolean { + return this._disabled; + } + public set disabled(dis: boolean) { + this._disabled = coerceBooleanProperty(dis); + this.stateChanges.next(); + } + + @Input() + public get placeholder() { + return this._placeholder; + } + + public set placeholder(plh) { + this._placeholder = plh; + this.stateChanges.next(); + } + + public get errorState() { + const control = this.ngControl; + const form = this.ngForm; + + if (control) { + return control.invalid && (control.touched || (form && form.submitted)); + } + + return false; + } + + @HostBinding('attr.aria-describedby') public describedBy = ''; + + public setDescribedByIds(ids: string[]) { + this.describedBy = ids.join(' '); + } + + public onContainerClick(event: MouseEvent) { + this.openPanel(); + } + + public openPanel() { + // console.log('openPanel'); + } + + public ngOnDestroy() { + this.stateChanges.complete(); + } + + public writeValue(value: any) { + if (value !== undefined) { + this.value = value; + this.text = this.value; + this.stateChanges.next(); + } + } + + public registerOnChange(onChange: (value: any) => void) { + this.onChange = onChange; + } + + onChange = (_: any) => {}; + + public registerOnTouched(onTouched: () => void) { + this.onTouched = onTouched; + } + + onTouched = () => {}; public onInput(event: Event) { const target = event.target as HTMLInputElement; this.text = target.value; - console.log(this.text); + this.onChange(this.text); + this.stateChanges.next(); + } + + onFocus() { + this.focused = true; + this.stateChanges.next(); + } + + onBlur() { + this.text = this.value; + this.onTouched(); + this.focused = false; + this.stateChanges.next(); } public displayWith(suggestion?: any): string | undefined { - console.log(suggestion); return suggestion ? suggestion : undefined; } + + public onSuggestionSelect(event: Event) { + this.value = event; + this.onChange(this.value); + this.stateChanges.next(); + } } From ec446cd97460ce5e746a7846cc53ed89caf09e6e Mon Sep 17 00:00:00 2001 From: Anna Date: Tue, 14 Jan 2020 10:41:28 +0300 Subject: [PATCH 06/31] wrapper story file united with autocomplete story file --- .../__stories__/autocomplete-form.stories.mdx | 35 ------------------- .../ui/autocomplete/autocomplete.stories.mdx | 10 +++--- 2 files changed, 5 insertions(+), 40 deletions(-) delete mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.stories.mdx diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.stories.mdx b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.stories.mdx deleted file mode 100644 index d8aecf4f..00000000 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.stories.mdx +++ /dev/null @@ -1,35 +0,0 @@ -import { Meta, Preview, Story, Props } from '@storybook/addon-docs/blocks'; - -import { withKnobs, text } from '@storybook/addon-knobs'; -import { action } from '@storybook/addon-actions'; -import { withA11y } from '@storybook/addon-a11y'; - -import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; - -import { AutocompleteFormModule } from './autocomplete-form.module'; -import { AutocompleteFormComponent } from './autocomplete-form.component'; - - - -# Autocomplete - -This component demonstrates usage of storybook. - -## Demos - -This is a basic story: - - - - {{ - template: ``, - moduleMetadata: { - imports: [BrowserAnimationsModule, AutocompleteFormModule] - } - }} - - - -## API - - diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx index bf9c53b4..ce59c36d 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx @@ -6,8 +6,8 @@ import { withA11y } from '@storybook/addon-a11y'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { AutocompleteModule } from './autocomplete.module'; -import { AutocompleteComponent } from './autocomplete.component'; +import { AutocompleteFormModule } from './__stories__/autocomplete-form.module'; +import { AutocompleteFormComponent } from './__stories__/autocomplete-form.component'; @@ -22,9 +22,9 @@ This is a basic story: {{ - template: `autocomplete`, + template: ``, moduleMetadata: { - imports: [BrowserAnimationsModule, AutocompleteModule] + imports: [BrowserAnimationsModule, AutocompleteFormModule] } }} @@ -32,4 +32,4 @@ This is a basic story: ## API - + From 2c7b82a4e868e0b678b01570359670ef36911760 Mon Sep 17 00:00:00 2001 From: Anna Date: Tue, 14 Jan 2020 13:30:14 +0300 Subject: [PATCH 07/31] add inputs and outputs to component --- .../autocomplete-form.component.html | 10 ++- .../autocomplete-form.component.ts | 20 +++++- .../__stories__/autocomplete-form.module.ts | 9 +-- .../autocomplete/autocomplete.component.html | 1 + .../ui/autocomplete/autocomplete.component.ts | 72 +++++++++++++------ .../ui/autocomplete/autocomplete.stories.mdx | 3 +- 6 files changed, 80 insertions(+), 35 deletions(-) diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html index 8ab96f3d..59c8d025 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html @@ -1,7 +1,11 @@
- + Введите сообщение - autocomplete + autocomplete - diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.ts index 7b445985..5503b536 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.ts @@ -9,7 +9,13 @@ import { FormGroup, FormBuilder } from '@angular/forms'; encapsulation: ViewEncapsulation.None }) export class AutocompleteFormComponent { - form: FormGroup; + public form: FormGroup; + public options: string[] = ['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven']; + public text: string; + + /** + * Event emitted when user change value in input. + */ constructor(private formBuilder: FormBuilder) { this.form = this.formBuilder.group({ @@ -17,9 +23,19 @@ export class AutocompleteFormComponent { }); } + /** + * @ignore + */ onSubmit() { if (this.form.valid) { - console.log(this.form.value); + console.log('text from autocomplete component - ', this.text); } } + + /** + * @ignore + */ + onChangeText(text: string) { + this.text = text; + } } diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.module.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.module.ts index 5532c5b2..360a1f24 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.module.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.module.ts @@ -5,9 +5,7 @@ import { ReactiveFormsModule } from '@angular/forms'; import { AutocompleteModule } from '../autocomplete.module'; import { MatFormFieldModule } from '@angular/material/form-field'; - -import { MatAutocompleteModule } from '@angular/material/autocomplete'; -import { MatInputModule } from '@angular/material/input'; +import { MatButtonModule } from '@angular/material/button'; import { AutocompleteFormComponent } from './autocomplete-form.component'; @@ -15,11 +13,10 @@ import { AutocompleteFormComponent } from './autocomplete-form.component'; declarations: [AutocompleteFormComponent], imports: [ CommonModule, - MatAutocompleteModule, - MatInputModule, ReactiveFormsModule, AutocompleteModule, - MatFormFieldModule + MatFormFieldModule, + MatButtonModule ], exports: [AutocompleteFormComponent] }) diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html index e34f8219..303d1fe4 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html @@ -1,5 +1,6 @@ , ControlValueAccessor, OnDestroy { + implements MatFormFieldControl, ControlValueAccessor, OnDestroy, OnInit { public get value(): any { return this._value; } @@ -41,16 +47,6 @@ export class AutocompleteComponent this.ngControl.valueAccessor = this; } } - static nextId = 0; - // tslint:disable-next-line variable-name - private _disabled = false; - // tslint:disable-next-line variable-name - private _required = false; - // tslint:disable-next-line variable-name - private _focused = false; - // tslint:disable-next-line variable-name - private _placeholder = ''; - public get focused() { return this._focused; } @@ -62,16 +58,6 @@ export class AutocompleteComponent public get empty(): boolean { return !this.value; } - - public text = ''; - public options: string[] = ['One', 'Two', 'Three']; - - // tslint:disable-next-line variable-name - private _value = ''; - - public stateChanges = new Subject(); - - @HostBinding() public id = `es-autocomplete-${AutocompleteComponent.nextId++}`; @HostBinding('class.floating') public get shouldLabelFloat() { return this.focused || !!this.text; @@ -115,8 +101,39 @@ export class AutocompleteComponent return false; } + static nextId = 0; + + @ViewChild('inputChild', { read: MatAutocompleteTrigger, static: true }) + private inputChild: MatAutocompleteTrigger; + + @Output() changeText = new EventEmitter(); + + @Input() public options: string[]; + + @HostBinding() public id = `es-autocomplete-${AutocompleteComponent.nextId++}`; @HostBinding('attr.aria-describedby') public describedBy = ''; + public text = ''; + private text$ = new Subject(); + // tslint:disable-next-line variable-name + private _disabled = false; + // tslint:disable-next-line variable-name + private _required = false; + // tslint:disable-next-line variable-name + private _focused = false; + // tslint:disable-next-line variable-name + private _placeholder = ''; + + // tslint:disable-next-line variable-name + private _value = ''; + + public stateChanges = new Subject(); + + ngOnInit() { + this.text$.pipe(debounceTime(500)).subscribe(text => { + this.changeText.emit(text); + }); + } public setDescribedByIds(ids: string[]) { this.describedBy = ids.join(' '); @@ -127,11 +144,19 @@ export class AutocompleteComponent } public openPanel() { - // console.log('openPanel'); + setTimeout(() => { + if (!this.focused && !this.disabled) { + this.focused = true; + // NOTE: workaround to focus when clicked around input + (this.inputChild as any)._element.nativeElement.focus(); + } + }, 0); + this.stateChanges.next(); } public ngOnDestroy() { this.stateChanges.complete(); + this.changeText.complete(); } public writeValue(value: any) { @@ -158,6 +183,7 @@ export class AutocompleteComponent const target = event.target as HTMLInputElement; this.text = target.value; this.onChange(this.text); + this.text$.next(this.text); this.stateChanges.next(); } diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx index ce59c36d..214cde0b 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx @@ -8,6 +8,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { AutocompleteFormModule } from './__stories__/autocomplete-form.module'; import { AutocompleteFormComponent } from './__stories__/autocomplete-form.component'; +import { AutocompleteComponent } from './autocomplete.component'; @@ -32,4 +33,4 @@ This is a basic story: ## API - + From dd79d31d13395ff3088eebcb70ce13b4f594556a Mon Sep 17 00:00:00 2001 From: Anna Date: Tue, 14 Jan 2020 14:30:11 +0300 Subject: [PATCH 08/31] add filter options method --- .../autocomplete-form.component.html | 5 ++-- .../autocomplete-form.component.ts | 29 ++++++------------- .../ui/autocomplete/autocomplete.component.ts | 5 ++-- .../src/lib/ui/autocomplete/filter-options.ts | 4 +++ .../elonkit/src/lib/ui/autocomplete/index.ts | 1 + 5 files changed, 20 insertions(+), 24 deletions(-) create mode 100644 projects/elonkit/src/lib/ui/autocomplete/filter-options.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html index 59c8d025..589caecd 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html @@ -1,11 +1,12 @@ -
+ Введите сообщение autocomplete +
diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.ts index 5503b536..c558d4d8 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.ts @@ -1,5 +1,9 @@ import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; import { FormGroup, FormBuilder } from '@angular/forms'; +import { GetFilterOptions } from '../filter-options'; + +const OPTIONS = ['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven']; +const DEBOUNCE = 500; @Component({ selector: 'es-autocomplete-form', @@ -10,12 +14,8 @@ import { FormGroup, FormBuilder } from '@angular/forms'; }) export class AutocompleteFormComponent { public form: FormGroup; - public options: string[] = ['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven']; - public text: string; - - /** - * Event emitted when user change value in input. - */ + public options: string[] = OPTIONS; + public debounceTime: number = DEBOUNCE; constructor(private formBuilder: FormBuilder) { this.form = this.formBuilder.group({ @@ -23,19 +23,8 @@ export class AutocompleteFormComponent { }); } - /** - * @ignore - */ - onSubmit() { - if (this.form.valid) { - console.log('text from autocomplete component - ', this.text); - } - } - - /** - * @ignore - */ - onChangeText(text: string) { - this.text = text; + public onChangeText(text: string) { + this.options = OPTIONS; + this.options = GetFilterOptions(text, this.options); } } diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts index 2d853432..49abc862 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts @@ -109,6 +109,7 @@ export class AutocompleteComponent @Output() changeText = new EventEmitter(); @Input() public options: string[]; + @Input() public debounceTime: number; @HostBinding() public id = `es-autocomplete-${AutocompleteComponent.nextId++}`; @@ -130,7 +131,7 @@ export class AutocompleteComponent public stateChanges = new Subject(); ngOnInit() { - this.text$.pipe(debounceTime(500)).subscribe(text => { + this.text$.pipe(debounceTime(this.debounceTime)).subscribe(text => { this.changeText.emit(text); }); } @@ -182,8 +183,8 @@ export class AutocompleteComponent public onInput(event: Event) { const target = event.target as HTMLInputElement; this.text = target.value; - this.onChange(this.text); this.text$.next(this.text); + this.onChange(this.text); this.stateChanges.next(); } diff --git a/projects/elonkit/src/lib/ui/autocomplete/filter-options.ts b/projects/elonkit/src/lib/ui/autocomplete/filter-options.ts new file mode 100644 index 00000000..997b6dd5 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/filter-options.ts @@ -0,0 +1,4 @@ +export function GetFilterOptions(text: string, options: any): any { + const lowerText = text.toLowerCase(); + return options.filter(e => e.toLowerCase().includes(lowerText)); +} diff --git a/projects/elonkit/src/lib/ui/autocomplete/index.ts b/projects/elonkit/src/lib/ui/autocomplete/index.ts index 49f6aa0a..4e5c4d94 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/index.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/index.ts @@ -1,2 +1,3 @@ export { AutocompleteModule } from './autocomplete.module'; export { AutocompleteComponent } from './autocomplete.component'; +export { GetFilterOptions } from './filter-options'; From 1ebf0eee88d3718efec0bbd3e66dfc23f17eaabb Mon Sep 17 00:00:00 2001 From: Anna Date: Tue, 14 Jan 2020 14:54:42 +0300 Subject: [PATCH 09/31] create two new folders for forms --- ...autocomplete-story-default.component.html} | 2 +- ...autocomplete-story-default.component.scss} | 2 +- .../autocomplete-story-default.component.ts} | 10 +++---- .../autocomplete-story-default.module.ts} | 10 +++---- .../autocomplete-story-service.component.html | 12 ++++++++ .../autocomplete-story-service.component.scss | 5 ++++ .../autocomplete-story-service.component.ts | 30 +++++++++++++++++++ .../autocomplete-story-service.module.ts | 23 ++++++++++++++ .../ui/autocomplete/autocomplete.stories.mdx | 25 +++++++++++++--- 9 files changed, 103 insertions(+), 16 deletions(-) rename projects/elonkit/src/lib/ui/autocomplete/__stories__/{autocomplete-form.component.html => autocomplete-story-default/autocomplete-story-default.component.html} (79%) rename projects/elonkit/src/lib/ui/autocomplete/__stories__/{autocomplete-form.component.scss => autocomplete-story-default/autocomplete-story-default.component.scss} (57%) rename projects/elonkit/src/lib/ui/autocomplete/__stories__/{autocomplete-form.component.ts => autocomplete-story-default/autocomplete-story-default.component.ts} (72%) rename projects/elonkit/src/lib/ui/autocomplete/__stories__/{autocomplete-form.module.ts => autocomplete-story-default/autocomplete-story-default.module.ts} (58%) create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.scss create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.module.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html similarity index 79% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html rename to projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html index 589caecd..5547acc1 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-form.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html @@ -1,5 +1,5 @@
- + Введите сообщение + + Введите сообщение + + + + diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.scss b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.scss new file mode 100644 index 00000000..8dec1387 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.scss @@ -0,0 +1,5 @@ +.es-autocomplete-story-service { + &.mat-form-field { + width: 100%; + } +} diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts new file mode 100644 index 00000000..5cb0d815 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts @@ -0,0 +1,30 @@ +import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; +import { FormGroup, FormBuilder } from '@angular/forms'; +import { GetFilterOptions } from '../../filter-options'; + +const OPTIONS = ['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven']; +const DEBOUNCE = 500; + +@Component({ + selector: 'es-autocomplete-story-service', + templateUrl: './autocomplete-story-service.component.html', + styleUrls: ['./autocomplete-story-service.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None +}) +export class AutocompleteStoryServiceComponent { + public form: FormGroup; + public options: string[] = OPTIONS; + public debounceTime: number = DEBOUNCE; + + constructor(private formBuilder: FormBuilder) { + this.form = this.formBuilder.group({ + autocomplete: [''] + }); + } + + public onChangeText(text: string) { + this.options = OPTIONS; + this.options = GetFilterOptions(text, this.options); + } +} diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.module.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.module.ts new file mode 100644 index 00000000..41b61e6c --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.module.ts @@ -0,0 +1,23 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule } from '@angular/forms'; + +import { AutocompleteModule } from '../../autocomplete.module'; + +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatButtonModule } from '@angular/material/button'; + +import { AutocompleteStoryServiceComponent } from './autocomplete-story-service.component'; + +@NgModule({ + declarations: [AutocompleteStoryServiceComponent], + imports: [ + CommonModule, + ReactiveFormsModule, + AutocompleteModule, + MatFormFieldModule, + MatButtonModule + ], + exports: [AutocompleteStoryServiceComponent] +}) +export class AutocompleteStoryServiceModule {} diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx index 214cde0b..8a2cfd5e 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx @@ -6,10 +6,14 @@ import { withA11y } from '@storybook/addon-a11y'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; -import { AutocompleteFormModule } from './__stories__/autocomplete-form.module'; -import { AutocompleteFormComponent } from './__stories__/autocomplete-form.component'; import { AutocompleteComponent } from './autocomplete.component'; +import { AutocompleteStoryDefaultModule } from './__stories__/autocomplete-story-default/autocomplete-story-default.module'; +import { AutocompleteStoryDefaultComponent } from './__stories__/autocomplete-story-default/autocomplete-story-default.component'; + +import { AutocompleteStoryServiceModule } from './__stories__/autocomplete-story-service/autocomplete-story-service.module'; +import { AutocompleteStoryServiceComponent } from './__stories__/autocomplete-story-service/autocomplete-story-service.component'; + # Autocomplete @@ -23,9 +27,22 @@ This is a basic story: {{ - template: ``, + template: ``, + moduleMetadata: { + imports: [BrowserAnimationsModule, AutocompleteStoryDefaultModule] + } + }} + + + +This is a story with service: + + + + {{ + template: ``, moduleMetadata: { - imports: [BrowserAnimationsModule, AutocompleteFormModule] + imports: [BrowserAnimationsModule, AutocompleteStoryServiceModule] } }} From 96629e8c64ab9b70ca9c5212601f1b6b3aaa9ff3 Mon Sep 17 00:00:00 2001 From: Anna Date: Tue, 14 Jan 2020 16:14:53 +0300 Subject: [PATCH 10/31] add autocomplete service and loader --- .../autocomplete-story-service.component.html | 1 + .../autocomplete-story-service.component.ts | 34 +++++++++++++++---- .../autocomplete-story-service.module.ts | 5 ++- .../autocomplete.service.ts | 15 ++++++++ .../autocomplete/autocomplete.component.html | 9 +++-- .../ui/autocomplete/autocomplete.component.ts | 1 + .../ui/autocomplete/autocomplete.module.ts | 3 +- 7 files changed, 58 insertions(+), 10 deletions(-) create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html index 9a85eca5..cc84cc62 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html @@ -4,6 +4,7 @@ diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts index 5cb0d815..65f527b9 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts @@ -1,8 +1,14 @@ -import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; +import { + Component, + ChangeDetectionStrategy, + ViewEncapsulation, + OnInit, + ChangeDetectorRef +} from '@angular/core'; import { FormGroup, FormBuilder } from '@angular/forms'; import { GetFilterOptions } from '../../filter-options'; +import { AutocompleteService } from '../autocomplete-story-service/autocomplete.service'; -const OPTIONS = ['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven']; const DEBOUNCE = 500; @Component({ @@ -12,19 +18,35 @@ const DEBOUNCE = 500; changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None }) -export class AutocompleteStoryServiceComponent { +export class AutocompleteStoryServiceComponent implements OnInit { public form: FormGroup; - public options: string[] = OPTIONS; + public options: string[]; + public isLoading = false; + public optionsFromService: string[]; public debounceTime: number = DEBOUNCE; - constructor(private formBuilder: FormBuilder) { + constructor( + private formBuilder: FormBuilder, + private autocompleteService: AutocompleteService, + private changeDetector: ChangeDetectorRef + ) { this.form = this.formBuilder.group({ autocomplete: [''] }); } + public ngOnInit() { + this.isLoading = true; + this.autocompleteService.getOptions().subscribe(options => { + this.optionsFromService = options.OPTIONS; + this.options = this.optionsFromService; + this.isLoading = false; + this.changeDetector.detectChanges(); + }); + } + public onChangeText(text: string) { - this.options = OPTIONS; + this.options = this.optionsFromService; this.options = GetFilterOptions(text, this.options); } } diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.module.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.module.ts index 41b61e6c..d3d44bc2 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.module.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.module.ts @@ -7,6 +7,8 @@ import { AutocompleteModule } from '../../autocomplete.module'; import { MatFormFieldModule } from '@angular/material/form-field'; import { MatButtonModule } from '@angular/material/button'; +import { AutocompleteService } from '../autocomplete-story-service/autocomplete.service'; + import { AutocompleteStoryServiceComponent } from './autocomplete-story-service.component'; @NgModule({ @@ -18,6 +20,7 @@ import { AutocompleteStoryServiceComponent } from './autocomplete-story-service. MatFormFieldModule, MatButtonModule ], - exports: [AutocompleteStoryServiceComponent] + exports: [AutocompleteStoryServiceComponent], + providers: [AutocompleteService] }) export class AutocompleteStoryServiceModule {} diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts new file mode 100644 index 00000000..8cf3b332 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts @@ -0,0 +1,15 @@ +import { Injectable } from '@angular/core'; +import { delay } from 'rxjs/operators'; + +import { of } from 'rxjs'; + +const OPTIONS = ['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven']; + +@Injectable() +export class AutocompleteService { + public getOptions() { + return of({ + OPTIONS + }).pipe(delay(3000)); + } +} diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html index 303d1fe4..fb4232a6 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html @@ -13,7 +13,12 @@ [displayWith]="displayWith" (optionSelected)="onSuggestionSelect($event.option.value)" > - - {{ option }} + + + {{ option }} + + + +
diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts index 49abc862..c6cdc033 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts @@ -109,6 +109,7 @@ export class AutocompleteComponent @Output() changeText = new EventEmitter(); @Input() public options: string[]; + @Input() public isLoading: boolean; @Input() public debounceTime: number; @HostBinding() public id = `es-autocomplete-${AutocompleteComponent.nextId++}`; diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts index e456223e..bdf0121b 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts @@ -3,12 +3,13 @@ import { CommonModule } from '@angular/common'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatInputModule } from '@angular/material/input'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { AutocompleteComponent } from './autocomplete.component'; @NgModule({ declarations: [AutocompleteComponent], - imports: [CommonModule, MatAutocompleteModule, MatInputModule], + imports: [CommonModule, MatAutocompleteModule, MatInputModule, MatProgressSpinnerModule], exports: [AutocompleteComponent] }) export class AutocompleteModule {} From 3f7bc42e40515af3431241c3b6bccedb3ab18d68 Mon Sep 17 00:00:00 2001 From: Anna Date: Tue, 14 Jan 2020 17:07:51 +0300 Subject: [PATCH 11/31] fix getOptions method --- .../autocomplete-story-default.component.ts | 3 +-- .../autocomplete-story-service.component.ts | 12 +++++++----- .../autocomplete.service.ts | 9 ++++++--- .../src/lib/ui/autocomplete/filter-options.ts | 2 +- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts index 45a0fb61..cf4bbdf7 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts @@ -24,7 +24,6 @@ export class AutocompleteStoryDefaultComponent { } public onChangeText(text: string) { - this.options = OPTIONS; - this.options = GetFilterOptions(text, this.options); + this.options = GetFilterOptions(text, OPTIONS); } } diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts index 65f527b9..61a91788 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts @@ -6,7 +6,6 @@ import { ChangeDetectorRef } from '@angular/core'; import { FormGroup, FormBuilder } from '@angular/forms'; -import { GetFilterOptions } from '../../filter-options'; import { AutocompleteService } from '../autocomplete-story-service/autocomplete.service'; const DEBOUNCE = 500; @@ -38,15 +37,18 @@ export class AutocompleteStoryServiceComponent implements OnInit { public ngOnInit() { this.isLoading = true; this.autocompleteService.getOptions().subscribe(options => { - this.optionsFromService = options.OPTIONS; - this.options = this.optionsFromService; + this.options = options.options; this.isLoading = false; this.changeDetector.detectChanges(); }); } public onChangeText(text: string) { - this.options = this.optionsFromService; - this.options = GetFilterOptions(text, this.options); + this.isLoading = true; + this.autocompleteService.getOptions(text).subscribe(options => { + this.options = options.options; + this.isLoading = false; + this.changeDetector.detectChanges(); + }); } } diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts index 8cf3b332..bd84e149 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts @@ -1,15 +1,18 @@ import { Injectable } from '@angular/core'; -import { delay } from 'rxjs/operators'; +import { delay } from 'rxjs/operators'; import { of } from 'rxjs'; +import { GetFilterOptions } from '../../filter-options'; + const OPTIONS = ['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven']; @Injectable() export class AutocompleteService { - public getOptions() { + public getOptions(text?: string) { + const options = GetFilterOptions(text, OPTIONS); return of({ - OPTIONS + options }).pipe(delay(3000)); } } diff --git a/projects/elonkit/src/lib/ui/autocomplete/filter-options.ts b/projects/elonkit/src/lib/ui/autocomplete/filter-options.ts index 997b6dd5..df13cc21 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/filter-options.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/filter-options.ts @@ -1,4 +1,4 @@ export function GetFilterOptions(text: string, options: any): any { - const lowerText = text.toLowerCase(); + const lowerText = text ? text.toLowerCase() : ''; return options.filter(e => e.toLowerCase().includes(lowerText)); } From 5245583127f8a6163c2731e6b46b51697c81cf90 Mon Sep 17 00:00:00 2001 From: Anna Date: Wed, 15 Jan 2020 12:08:53 +0300 Subject: [PATCH 12/31] add new custom form component --- .../autocomplete-story-custom.component.html | 12 ++++++ .../autocomplete-story-custom.component.scss | 5 +++ .../autocomplete-story-custom.component.ts | 42 +++++++++++++++++++ .../autocomplete-story-custom.module.ts | 23 ++++++++++ .../autocomplete-story-default.component.ts | 5 ++- .../autocomplete-story-service.component.html | 3 ++ .../autocomplete-story-service.component.ts | 11 +++-- .../autocomplete.service.ts | 2 +- .../autocomplete/autocomplete.component.html | 17 +++++++- .../ui/autocomplete/autocomplete.component.ts | 2 +- .../ui/autocomplete/autocomplete.stories.mdx | 20 ++++++++- .../src/lib/ui/autocomplete/filter-options.ts | 5 +++ .../elonkit/src/lib/ui/autocomplete/index.ts | 2 +- 13 files changed, 135 insertions(+), 14 deletions(-) create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.scss create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html new file mode 100644 index 00000000..ccc41fa6 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html @@ -0,0 +1,12 @@ +
+ + Введите сообщение + + + +
diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.scss b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.scss new file mode 100644 index 00000000..36bdc9cb --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.scss @@ -0,0 +1,5 @@ +.es-autocomplete-story-custom { + &.mat-form-field { + width: 100%; + } +} diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts new file mode 100644 index 00000000..c166be72 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts @@ -0,0 +1,42 @@ +import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; +import { FormGroup, FormBuilder } from '@angular/forms'; +import { GetFilterOptions, GetFilterOptionsByKey } from '../../filter-options'; + +const OPTIONS = [ + { + id: 1, + name: 'Anna' + }, + { + id: 2, + name: 'Mary' + }, + { + id: 3, + name: 'Elena' + } +]; +const DEBOUNCE = 500; + +@Component({ + selector: 'es-autocomplete-story-custom', + templateUrl: './autocomplete-story-custom.component.html', + styleUrls: ['./autocomplete-story-custom.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None +}) +export class AutocompleteStoryCustomComponent { + public form: FormGroup; + public options: any[] = OPTIONS; + public debounceTime: number = DEBOUNCE; + + constructor(private formBuilder: FormBuilder) { + this.form = this.formBuilder.group({ + autocomplete: [''] + }); + } + + public onChangeText(text: string) { + this.options = GetFilterOptionsByKey(text, OPTIONS, 'name'); + } +} diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts new file mode 100644 index 00000000..1c1047f1 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts @@ -0,0 +1,23 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule } from '@angular/forms'; + +import { AutocompleteModule } from '../../autocomplete.module'; + +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatButtonModule } from '@angular/material/button'; + +import { AutocompleteStoryCustomComponent } from './autocomplete-story-custom.component'; + +@NgModule({ + declarations: [AutocompleteStoryCustomComponent], + imports: [ + CommonModule, + ReactiveFormsModule, + AutocompleteModule, + MatFormFieldModule, + MatButtonModule + ], + exports: [AutocompleteStoryCustomComponent] +}) +export class AutocompleteStoryCustomModule {} diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts index cf4bbdf7..7b22f565 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts @@ -2,7 +2,8 @@ import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/ import { FormGroup, FormBuilder } from '@angular/forms'; import { GetFilterOptions } from '../../filter-options'; -const OPTIONS = ['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven']; +const OPTIONS = ['One', 'Two', 'Three', 'Four', 'Five']; + const DEBOUNCE = 500; @Component({ @@ -14,7 +15,7 @@ const DEBOUNCE = 500; }) export class AutocompleteStoryDefaultComponent { public form: FormGroup; - public options: string[] = OPTIONS; + public options: any[] = OPTIONS; public debounceTime: number = DEBOUNCE; constructor(private formBuilder: FormBuilder) { diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html index cc84cc62..70b5a020 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html @@ -8,6 +8,9 @@ [debounceTime]="debounceTime" (changeText)="onChangeText($event)" > + + {{ option.name }} +
diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts index 61a91788..4fc5347d 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts @@ -35,15 +35,14 @@ export class AutocompleteStoryServiceComponent implements OnInit { } public ngOnInit() { - this.isLoading = true; - this.autocompleteService.getOptions().subscribe(options => { - this.options = options.options; - this.isLoading = false; - this.changeDetector.detectChanges(); - }); + this.loadingOptions(); } public onChangeText(text: string) { + this.loadingOptions(text); + } + + public loadingOptions(text?: string) { this.isLoading = true; this.autocompleteService.getOptions(text).subscribe(options => { this.options = options.options; diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts index bd84e149..5a5359fa 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts @@ -5,7 +5,7 @@ import { of } from 'rxjs'; import { GetFilterOptions } from '../../filter-options'; -const OPTIONS = ['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven']; +const OPTIONS = ['One', 'Two', 'Three', 'Four', 'Five']; @Injectable() export class AutocompleteService { diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html index fb4232a6..b0830e71 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html @@ -8,7 +8,7 @@ (focus)="onFocus()" (blur)="onBlur()" /> - +--> + + + + + {{ option.name }} + + + + + diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts index c6cdc033..dc7b7108 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts @@ -108,7 +108,7 @@ export class AutocompleteComponent @Output() changeText = new EventEmitter(); - @Input() public options: string[]; + @Input() public options: any[]; @Input() public isLoading: boolean; @Input() public debounceTime: number; diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx index 8a2cfd5e..9449e693 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx @@ -14,6 +14,9 @@ import { AutocompleteStoryDefaultComponent } from './__stories__/autocomplete-st import { AutocompleteStoryServiceModule } from './__stories__/autocomplete-story-service/autocomplete-story-service.module'; import { AutocompleteStoryServiceComponent } from './__stories__/autocomplete-story-service/autocomplete-story-service.component'; +import { AutocompleteStoryCustomModule } from './__stories__/autocomplete-story-custom/autocomplete-story-custom.module'; +import { AutocompleteStoryCustomComponent } from './__stories__/autocomplete-story-custom/autocomplete-story-custom.component'; + # Autocomplete @@ -25,7 +28,7 @@ This component demonstrates usage of storybook. This is a basic story: - + {{ template: ``, moduleMetadata: { @@ -38,7 +41,7 @@ This is a basic story: This is a story with service: - + {{ template: ``, moduleMetadata: { @@ -48,6 +51,19 @@ This is a story with service: +This is a story with custom options: + + + + {{ + template: ``, + moduleMetadata: { + imports: [BrowserAnimationsModule, AutocompleteStoryCustomModule] + } + }} + + + ## API diff --git a/projects/elonkit/src/lib/ui/autocomplete/filter-options.ts b/projects/elonkit/src/lib/ui/autocomplete/filter-options.ts index df13cc21..4debd28e 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/filter-options.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/filter-options.ts @@ -2,3 +2,8 @@ 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/autocomplete/index.ts b/projects/elonkit/src/lib/ui/autocomplete/index.ts index 4e5c4d94..fda910de 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/index.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/index.ts @@ -1,3 +1,3 @@ export { AutocompleteModule } from './autocomplete.module'; export { AutocompleteComponent } from './autocomplete.component'; -export { GetFilterOptions } from './filter-options'; +export { GetFilterOptions, GetFilterOptionsByKey } from './filter-options'; From 1557438b5fb7598c37ed19b22de3a7a7b2ce7955 Mon Sep 17 00:00:00 2001 From: Anna Date: Thu, 16 Jan 2020 10:06:01 +0300 Subject: [PATCH 13/31] create custom options --- .../autocomplete-story-custom.component.html | 25 ++++++- .../autocomplete-story-custom.component.ts | 2 +- .../autocomplete-story-service.component.html | 3 - .../autocomplete-option.directive.ts | 6 ++ .../autocomplete/autocomplete.component.html | 38 +++++++++- .../ui/autocomplete/autocomplete.component.ts | 74 ++++++++++++++----- .../ui/autocomplete/autocomplete.module.ts | 7 +- 7 files changed, 129 insertions(+), 26 deletions(-) create mode 100644 projects/elonkit/src/lib/ui/autocomplete/autocomplete-option.directive.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html index ccc41fa6..0ad3d7f8 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html @@ -1,4 +1,4 @@ -
+ + + + + Введите сообщение + + + {{option.name}} + + + +
diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts index c166be72..3620ed2b 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts @@ -16,7 +16,7 @@ const OPTIONS = [ name: 'Elena' } ]; -const DEBOUNCE = 500; +const DEBOUNCE = 0; @Component({ selector: 'es-autocomplete-story-custom', diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html index 70b5a020..cc84cc62 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html @@ -8,9 +8,6 @@ [debounceTime]="debounceTime" (changeText)="onChangeText($event)" > - - {{ option.name }} - diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete-option.directive.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete-option.directive.ts new file mode 100644 index 00000000..5a9a6a42 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete-option.directive.ts @@ -0,0 +1,6 @@ +import { Directive } from '@angular/core'; + +@Directive({ + selector: '[esAutocompleteOption]' +}) +export class AutocompleteOptionDirective {} diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html index b0830e71..759dfac5 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html @@ -23,7 +23,7 @@ --> - +--> + + + + + + + + + + + + + + diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts index dc7b7108..55d3d94a 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts @@ -10,14 +10,26 @@ import { EventEmitter, Output, OnInit, - ViewChild + ViewChild, + ContentChild, + TemplateRef, + ContentChildren, + QueryList, + AfterContentInit, + ViewChildren } from '@angular/core'; -import { MatFormFieldControl } from '@angular/material/form-field'; -import { Subject } from 'rxjs'; + import { NgControl, ControlValueAccessor, FormGroupDirective } from '@angular/forms'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; + +import { Subject } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; -import { MatAutocompleteTrigger } from '@angular/material/autocomplete'; + +import { MatFormFieldControl } from '@angular/material/form-field'; +import { MatAutocomplete, MatAutocompleteTrigger } from '@angular/material/autocomplete'; + +import { AutocompleteOptionDirective } from '../autocomplete/autocomplete-option.directive'; +import { MatOption } from '@angular/material/core'; @Component({ selector: 'es-autocomplete', @@ -28,7 +40,12 @@ import { MatAutocompleteTrigger } from '@angular/material/autocomplete'; providers: [{ provide: MatFormFieldControl, useExisting: AutocompleteComponent }] }) export class AutocompleteComponent - implements MatFormFieldControl, ControlValueAccessor, OnDestroy, OnInit { + implements + MatFormFieldControl, + ControlValueAccessor, + OnDestroy, + OnInit, + AfterContentInit { public get value(): any { return this._value; } @@ -38,15 +55,6 @@ export class AutocompleteComponent this.stateChanges.next(); } - constructor( - @Optional() @Self() public ngControl: NgControl, - @Optional() - public ngForm: FormGroupDirective - ) { - if (this.ngControl != null) { - this.ngControl.valueAccessor = this; - } - } public get focused() { return this._focused; } @@ -101,13 +109,19 @@ export class AutocompleteComponent return false; } + + @ContentChildren(MatOption) set contentOption(value: QueryList) { + console.log(value); + } static nextId = 0; - @ViewChild('inputChild', { read: MatAutocompleteTrigger, static: true }) - private inputChild: MatAutocompleteTrigger; + @ContentChild(AutocompleteOptionDirective, { read: TemplateRef, static: false }) optionTemplate; - @Output() changeText = new EventEmitter(); + // @ViewChildren(MatOption) contentOption: QueryList; + + @ViewChild(MatAutocomplete, { static: false }) autocomplete: MatAutocomplete; + @Output() changeText = new EventEmitter(); @Input() public options: any[]; @Input() public isLoading: boolean; @Input() public debounceTime: number; @@ -116,6 +130,12 @@ export class AutocompleteComponent @HostBinding('attr.aria-describedby') public describedBy = ''; public text = ''; + + public stateChanges = new Subject(); + public kek = ''; + + @ViewChild('inputChild', { read: MatAutocompleteTrigger, static: true }) + private inputChild: MatAutocompleteTrigger; private text$ = new Subject(); // tslint:disable-next-line variable-name private _disabled = false; @@ -129,7 +149,15 @@ export class AutocompleteComponent // tslint:disable-next-line variable-name private _value = ''; - public stateChanges = new Subject(); + constructor( + @Optional() @Self() public ngControl: NgControl, + @Optional() + public ngForm: FormGroupDirective + ) { + if (this.ngControl != null) { + this.ngControl.valueAccessor = this; + } + } ngOnInit() { this.text$.pipe(debounceTime(this.debounceTime)).subscribe(text => { @@ -137,6 +165,16 @@ export class AutocompleteComponent }); } + ngAfterContentInit() { + // console.log(this.contentOption); + // console.log(this.contentOption.length); + // this.contentOption.changes.subscribe(option => { + // this.autocomplete.options = option; + // // this.autocomplete.options.notifyOnChanges(); + // console.log(option); + // }); + } + public setDescribedByIds(ids: string[]) { this.describedBy = ids.join(' '); } diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts index bdf0121b..11862bfd 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts @@ -4,12 +4,15 @@ import { CommonModule } from '@angular/common'; import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatInputModule } from '@angular/material/input'; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatSelectModule } from '@angular/material/select'; + +import { AutocompleteOptionDirective } from './autocomplete-option.directive'; import { AutocompleteComponent } from './autocomplete.component'; @NgModule({ - declarations: [AutocompleteComponent], + declarations: [AutocompleteComponent, AutocompleteOptionDirective], imports: [CommonModule, MatAutocompleteModule, MatInputModule, MatProgressSpinnerModule], - exports: [AutocompleteComponent] + exports: [AutocompleteComponent, AutocompleteOptionDirective, MatSelectModule] }) export class AutocompleteModule {} From 85e9dee0713d9916b1596b28044c10e11d13f164 Mon Sep 17 00:00:00 2001 From: Anna Date: Thu, 16 Jan 2020 11:12:17 +0300 Subject: [PATCH 14/31] fix custom options and add default options --- .../autocomplete-story-custom.component.html | 26 +-- .../autocomplete-story-custom.component.ts | 6 +- .../autocomplete/autocomplete.component.html | 58 +------ .../ui/autocomplete/autocomplete.component.ts | 151 ++++++++---------- .../ui/autocomplete/autocomplete.module.ts | 1 - 5 files changed, 80 insertions(+), 162 deletions(-) diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html index 0ad3d7f8..f5b1371c 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html @@ -1,35 +1,17 @@ - - -
- - Введите сообщение - - - {{option.name}} - - - -
diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts index 3620ed2b..acda02f1 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts @@ -1,6 +1,6 @@ import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; import { FormGroup, FormBuilder } from '@angular/forms'; -import { GetFilterOptions, GetFilterOptionsByKey } from '../../filter-options'; +import { GetFilterOptionsByKey } from '../../filter-options'; const OPTIONS = [ { @@ -39,4 +39,8 @@ export class AutocompleteStoryCustomComponent { 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/autocomplete/autocomplete.component.html b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html index 759dfac5..9c0c64ae 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html @@ -8,53 +8,6 @@ (focus)="onFocus()" (blur)="onBlur()" /> - - - - - - - - + + {{ option }} + + + diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts index 55d3d94a..daa5ff6d 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts @@ -12,11 +12,7 @@ import { OnInit, ViewChild, ContentChild, - TemplateRef, - ContentChildren, - QueryList, - AfterContentInit, - ViewChildren + TemplateRef } from '@angular/core'; import { NgControl, ControlValueAccessor, FormGroupDirective } from '@angular/forms'; @@ -26,10 +22,9 @@ import { Subject } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; import { MatFormFieldControl } from '@angular/material/form-field'; -import { MatAutocomplete, MatAutocompleteTrigger } from '@angular/material/autocomplete'; +import { MatAutocompleteTrigger } from '@angular/material/autocomplete'; import { AutocompleteOptionDirective } from '../autocomplete/autocomplete-option.directive'; -import { MatOption } from '@angular/material/core'; @Component({ selector: 'es-autocomplete', @@ -40,12 +35,52 @@ import { MatOption } from '@angular/material/core'; providers: [{ provide: MatFormFieldControl, useExisting: AutocompleteComponent }] }) export class AutocompleteComponent - implements - MatFormFieldControl, - ControlValueAccessor, - OnDestroy, - OnInit, - AfterContentInit { + implements MatFormFieldControl, ControlValueAccessor, OnDestroy, OnInit { + public text = ''; + public stateChanges = new Subject(); + private inputChild: MatAutocompleteTrigger; + private text$ = new Subject(); + + @Input() public options: any[]; + @Input() public isLoading: boolean; + @Input() public debounceTime: number; + @Input() public displayWith = (value?: any): string | undefined => { + return value ? value : undefined; + }; + @Input() public valueFn = (option: any): any => { + return option; + }; + + @Output() changeText = new EventEmitter(); + + @ViewChild('inputChild', { read: MatAutocompleteTrigger, static: true }) + @ContentChild(AutocompleteOptionDirective, { read: TemplateRef, static: false }) + optionTemplate; + + constructor( + @Optional() @Self() public ngControl: NgControl, + @Optional() + public ngForm: FormGroupDirective + ) { + if (this.ngControl != null) { + this.ngControl.valueAccessor = this; + } + } + + ngOnInit() { + this.text$.pipe(debounceTime(this.debounceTime)).subscribe(text => { + this.changeText.emit(text); + }); + } + + public ngOnDestroy() { + this.stateChanges.complete(); + this.changeText.complete(); + } + + // tslint:disable-next-line variable-name + private _value = ''; + public get value(): any { return this._value; } @@ -55,6 +90,9 @@ export class AutocompleteComponent this.stateChanges.next(); } + // tslint:disable-next-line variable-name + private _focused = false; + public get focused() { return this._focused; } @@ -66,11 +104,18 @@ export class AutocompleteComponent public get empty(): boolean { return !this.value; } + + static nextId = 0; + @HostBinding() public id = `es-autocomplete-${AutocompleteComponent.nextId++}`; + @HostBinding('attr.aria-describedby') public describedBy = ''; @HostBinding('class.floating') public get shouldLabelFloat() { return this.focused || !!this.text; } + // tslint:disable-next-line variable-name + private _required = false; + @Input() public get required() { return this._required; @@ -80,6 +125,9 @@ export class AutocompleteComponent this.stateChanges.next(); } + // tslint:disable-next-line variable-name + private _disabled = false; + @Input() public get disabled(): boolean { return this._disabled; @@ -89,6 +137,9 @@ export class AutocompleteComponent this.stateChanges.next(); } + // tslint:disable-next-line variable-name + private _placeholder = ''; + @Input() public get placeholder() { return this._placeholder; @@ -110,71 +161,6 @@ export class AutocompleteComponent return false; } - @ContentChildren(MatOption) set contentOption(value: QueryList) { - console.log(value); - } - static nextId = 0; - - @ContentChild(AutocompleteOptionDirective, { read: TemplateRef, static: false }) optionTemplate; - - // @ViewChildren(MatOption) contentOption: QueryList; - - @ViewChild(MatAutocomplete, { static: false }) autocomplete: MatAutocomplete; - - @Output() changeText = new EventEmitter(); - @Input() public options: any[]; - @Input() public isLoading: boolean; - @Input() public debounceTime: number; - - @HostBinding() public id = `es-autocomplete-${AutocompleteComponent.nextId++}`; - - @HostBinding('attr.aria-describedby') public describedBy = ''; - public text = ''; - - public stateChanges = new Subject(); - public kek = ''; - - @ViewChild('inputChild', { read: MatAutocompleteTrigger, static: true }) - private inputChild: MatAutocompleteTrigger; - private text$ = new Subject(); - // tslint:disable-next-line variable-name - private _disabled = false; - // tslint:disable-next-line variable-name - private _required = false; - // tslint:disable-next-line variable-name - private _focused = false; - // tslint:disable-next-line variable-name - private _placeholder = ''; - - // tslint:disable-next-line variable-name - private _value = ''; - - constructor( - @Optional() @Self() public ngControl: NgControl, - @Optional() - public ngForm: FormGroupDirective - ) { - if (this.ngControl != null) { - this.ngControl.valueAccessor = this; - } - } - - ngOnInit() { - this.text$.pipe(debounceTime(this.debounceTime)).subscribe(text => { - this.changeText.emit(text); - }); - } - - ngAfterContentInit() { - // console.log(this.contentOption); - // console.log(this.contentOption.length); - // this.contentOption.changes.subscribe(option => { - // this.autocomplete.options = option; - // // this.autocomplete.options.notifyOnChanges(); - // console.log(option); - // }); - } - public setDescribedByIds(ids: string[]) { this.describedBy = ids.join(' '); } @@ -194,11 +180,6 @@ export class AutocompleteComponent this.stateChanges.next(); } - public ngOnDestroy() { - this.stateChanges.complete(); - this.changeText.complete(); - } - public writeValue(value: any) { if (value !== undefined) { this.value = value; @@ -239,10 +220,6 @@ export class AutocompleteComponent this.stateChanges.next(); } - public displayWith(suggestion?: any): string | undefined { - return suggestion ? suggestion : undefined; - } - public onSuggestionSelect(event: Event) { this.value = event; this.onChange(this.value); diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts index 11862bfd..88e416da 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts @@ -7,7 +7,6 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSelectModule } from '@angular/material/select'; import { AutocompleteOptionDirective } from './autocomplete-option.directive'; - import { AutocompleteComponent } from './autocomplete.component'; @NgModule({ From 60f8a67c7ec7b7315f3c7beca7f864c3ceedc8b0 Mon Sep 17 00:00:00 2001 From: Anna Date: Thu, 16 Jan 2020 11:33:02 +0300 Subject: [PATCH 15/31] add field foto to custom form --- .../autocomplete-story-custom.component.html | 1 + .../autocomplete-story-custom.component.scss | 6 ++++++ .../autocomplete-story-custom.component.ts | 9 ++++++--- .../src/lib/ui/autocomplete/autocomplete.component.ts | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html index f5b1371c..124c3421 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html @@ -9,6 +9,7 @@ (changeText)="onChangeText($event)" > + {{ option.name }} {{ option.id }} diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.scss b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.scss index 36bdc9cb..6e410178 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.scss +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.scss @@ -1,4 +1,10 @@ .es-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/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts index acda02f1..3c4e381f 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts @@ -5,15 +5,18 @@ import { GetFilterOptionsByKey } from '../../filter-options'; const OPTIONS = [ { id: 1, - name: 'Anna' + name: 'Anna', + foto: 'https://joeschmoe.io/api/v1/jenni' }, { id: 2, - name: 'Mary' + name: 'Mary', + foto: 'https://joeschmoe.io/api/v1/julie' }, { id: 3, - name: 'Elena' + name: 'Elena', + foto: 'https://joeschmoe.io/api/v1/jolee' } ]; const DEBOUNCE = 0; diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts index daa5ff6d..0a3b6d97 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts @@ -214,9 +214,9 @@ export class AutocompleteComponent } onBlur() { - this.text = this.value; this.onTouched(); this.focused = false; + this.changeText.emit(this.text); this.stateChanges.next(); } From 8f1717a24cf7bed66ad08193be7853c9eff90026 Mon Sep 17 00:00:00 2001 From: Anna Date: Thu, 16 Jan 2020 13:05:08 +0300 Subject: [PATCH 16/31] add subject to service form component --- .../autocomplete-story-service.component.ts | 33 +++++++++++++++---- .../autocomplete.service.ts | 4 +-- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts index 4fc5347d..b77b86c0 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts @@ -3,11 +3,17 @@ import { ChangeDetectionStrategy, ViewEncapsulation, OnInit, - ChangeDetectorRef + ChangeDetectorRef, + OnDestroy } from '@angular/core'; import { FormGroup, FormBuilder } from '@angular/forms'; import { AutocompleteService } from '../autocomplete-story-service/autocomplete.service'; +import { BehaviorSubject } from 'rxjs'; +import { switchMap } from 'rxjs/operators'; + +import { untilComponentDestroyed } from '@w11k/ngx-componentdestroyed'; + const DEBOUNCE = 500; @Component({ @@ -17,7 +23,9 @@ const DEBOUNCE = 500; changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None }) -export class AutocompleteStoryServiceComponent implements OnInit { +export class AutocompleteStoryServiceComponent implements OnInit, OnDestroy { + text$ = new BehaviorSubject(''); + public form: FormGroup; public options: string[]; public isLoading = false; @@ -32,22 +40,33 @@ export class AutocompleteStoryServiceComponent implements OnInit { this.form = this.formBuilder.group({ autocomplete: [''] }); + + this.text$ + .pipe( + untilComponentDestroyed(this), + switchMap(text => this.autocompleteService.getOptions(text)) + ) + .subscribe(options => { + this.options = options.options; + this.isLoading = false; + this.changeDetector.detectChanges(); + }); } public ngOnInit() { this.loadingOptions(); } + public ngOnDestroy() { + // + } + public onChangeText(text: string) { this.loadingOptions(text); } public loadingOptions(text?: string) { this.isLoading = true; - this.autocompleteService.getOptions(text).subscribe(options => { - this.options = options.options; - this.isLoading = false; - this.changeDetector.detectChanges(); - }); + this.text$.next(text); } } diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts index 5a5359fa..95710315 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@angular/core'; import { delay } from 'rxjs/operators'; -import { of } from 'rxjs'; +import { of, Observable } from 'rxjs'; import { GetFilterOptions } from '../../filter-options'; @@ -9,7 +9,7 @@ const OPTIONS = ['One', 'Two', 'Three', 'Four', 'Five']; @Injectable() export class AutocompleteService { - public getOptions(text?: string) { + public getOptions(text?: string): Observable { const options = GetFilterOptions(text, OPTIONS); return of({ options From 8a4ece960d3cc36a74eb9ff431e38ab44f4608e4 Mon Sep 17 00:00:00 2001 From: Anna Date: Thu, 16 Jan 2020 14:04:48 +0300 Subject: [PATCH 17/31] add unsubscribe without external package --- .../autocomplete-story-custom.component.html | 1 + .../autocomplete-story-service.component.ts | 31 +++++++------------ .../ui/autocomplete/autocomplete.component.ts | 8 ++++- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html index 124c3421..73587ed9 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html @@ -5,6 +5,7 @@ formControlName="autocomplete" [options]="options" [debounceTime]="debounceTime" + [isCustomSelection]="true" [valueFn]="valueFn" (changeText)="onChangeText($event)" > diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts index b77b86c0..6d878d04 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts @@ -2,17 +2,14 @@ import { Component, ChangeDetectionStrategy, ViewEncapsulation, - OnInit, ChangeDetectorRef, OnDestroy } from '@angular/core'; import { FormGroup, FormBuilder } from '@angular/forms'; import { AutocompleteService } from '../autocomplete-story-service/autocomplete.service'; -import { BehaviorSubject } from 'rxjs'; -import { switchMap } from 'rxjs/operators'; - -import { untilComponentDestroyed } from '@w11k/ngx-componentdestroyed'; +import { BehaviorSubject, Subscription } from 'rxjs'; +import { switchMap, tap } from 'rxjs/operators'; const DEBOUNCE = 500; @@ -23,14 +20,14 @@ const DEBOUNCE = 500; changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None }) -export class AutocompleteStoryServiceComponent implements OnInit, OnDestroy { +export class AutocompleteStoryServiceComponent implements OnDestroy { text$ = new BehaviorSubject(''); public form: FormGroup; public options: string[]; public isLoading = false; - public optionsFromService: string[]; public debounceTime: number = DEBOUNCE; + private subscription: Subscription | null = null; constructor( private formBuilder: FormBuilder, @@ -41,9 +38,11 @@ export class AutocompleteStoryServiceComponent implements OnInit, OnDestroy { autocomplete: [''] }); - this.text$ + this.subscription = this.text$ .pipe( - untilComponentDestroyed(this), + tap(() => { + this.isLoading = true; + }), switchMap(text => this.autocompleteService.getOptions(text)) ) .subscribe(options => { @@ -53,20 +52,14 @@ export class AutocompleteStoryServiceComponent implements OnInit, OnDestroy { }); } - public ngOnInit() { - this.loadingOptions(); - } - public ngOnDestroy() { - // + if (this.subscription) { + this.subscription.unsubscribe(); + this.subscription = null; + } } public onChangeText(text: string) { - this.loadingOptions(text); - } - - public loadingOptions(text?: string) { - this.isLoading = true; this.text$.next(text); } } diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts index 0a3b6d97..9f22f057 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts @@ -43,6 +43,7 @@ export class AutocompleteComponent @Input() public options: any[]; @Input() public isLoading: boolean; + @Input() public isCustomSelection = false; @Input() public debounceTime: number; @Input() public displayWith = (value?: any): string | undefined => { return value ? value : undefined; @@ -216,7 +217,12 @@ export class AutocompleteComponent onBlur() { this.onTouched(); this.focused = false; - this.changeText.emit(this.text); + + if (!this.isCustomSelection) { + this.text = this.value; + } + + // this.changeText.emit(this.text); this.stateChanges.next(); } From a0965f3b9c8a053f21de7d2da34c52211fb714c1 Mon Sep 17 00:00:00 2001 From: Anna Date: Thu, 16 Jan 2020 15:52:48 +0300 Subject: [PATCH 18/31] add InjectionToken to provide --- .../autocomplete-story-custom.component.html | 2 +- .../autocomplete-story-custom.component.ts | 18 ++++++++++++++---- .../autocomplete-story-custom.module.ts | 13 ++++++++++++- .../ui/autocomplete/autocomplete.component.ts | 12 +++++++++++- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html index 73587ed9..f51d247b 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html @@ -5,7 +5,7 @@ formControlName="autocomplete" [options]="options" [debounceTime]="debounceTime" - [isCustomSelection]="true" + [isCustomSelection]="isCustomSelection" [valueFn]="valueFn" (changeText)="onChangeText($event)" > diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts index 3c4e381f..57ade285 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts @@ -1,6 +1,10 @@ -import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; +import { Component, ChangeDetectionStrategy, ViewEncapsulation, Inject } from '@angular/core'; import { FormGroup, FormBuilder } from '@angular/forms'; import { GetFilterOptionsByKey } from '../../filter-options'; +import { + ES_AUTOCOMPLETE_DEFAULT_OPTIONS, + EsAutocompleteDefaultOptions +} from '../../autocomplete.component'; const OPTIONS = [ { @@ -19,7 +23,6 @@ const OPTIONS = [ foto: 'https://joeschmoe.io/api/v1/jolee' } ]; -const DEBOUNCE = 0; @Component({ selector: 'es-autocomplete-story-custom', @@ -31,12 +34,19 @@ const DEBOUNCE = 0; export class AutocompleteStoryCustomComponent { public form: FormGroup; public options: any[] = OPTIONS; - public debounceTime: number = DEBOUNCE; + public debounceTime: number; + public isCustomSelection = false; - constructor(private formBuilder: FormBuilder) { + constructor( + private formBuilder: FormBuilder, + @Inject(ES_AUTOCOMPLETE_DEFAULT_OPTIONS) + private autocompleteDefaultOptions: EsAutocompleteDefaultOptions + ) { this.form = this.formBuilder.group({ autocomplete: [''] }); + this.debounceTime = autocompleteDefaultOptions.debounceTime; + this.isCustomSelection = autocompleteDefaultOptions.isCustomSelection; } public onChangeText(text: string) { diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts index 1c1047f1..c6c928d3 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts @@ -4,6 +4,8 @@ import { ReactiveFormsModule } from '@angular/forms'; import { AutocompleteModule } from '../../autocomplete.module'; +import { ES_AUTOCOMPLETE_DEFAULT_OPTIONS } from '../../autocomplete.component'; + import { MatFormFieldModule } from '@angular/material/form-field'; import { MatButtonModule } from '@angular/material/button'; @@ -18,6 +20,15 @@ import { AutocompleteStoryCustomComponent } from './autocomplete-story-custom.co MatFormFieldModule, MatButtonModule ], - exports: [AutocompleteStoryCustomComponent] + exports: [AutocompleteStoryCustomComponent], + providers: [ + { + provide: ES_AUTOCOMPLETE_DEFAULT_OPTIONS, + useValue: { + debounceTime: 2000, + isCustomSelection: true + } + } + ] }) export class AutocompleteStoryCustomModule {} diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts index 9f22f057..f2d8a2c5 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts @@ -12,7 +12,8 @@ import { OnInit, ViewChild, ContentChild, - TemplateRef + TemplateRef, + InjectionToken } from '@angular/core'; import { NgControl, ControlValueAccessor, FormGroupDirective } from '@angular/forms'; @@ -26,6 +27,15 @@ import { MatAutocompleteTrigger } from '@angular/material/autocomplete'; import { AutocompleteOptionDirective } from '../autocomplete/autocomplete-option.directive'; +export const ES_AUTOCOMPLETE_DEFAULT_OPTIONS = new InjectionToken( + 'ES_AUTOCOMPLETE_DEFAULT_OPTIONS' +); + +export interface EsAutocompleteDefaultOptions { + debounceTime?: number; + isCustomSelection?: boolean; +} + @Component({ selector: 'es-autocomplete', templateUrl: './autocomplete.component.html', From a6079e0185e395536e1003358211c14a13e8d161 Mon Sep 17 00:00:00 2001 From: Anna Date: Thu, 16 Jan 2020 16:54:52 +0300 Subject: [PATCH 19/31] transfer Inject logic to autocomplete component --- .../autocomplete-story-custom.component.html | 2 - .../autocomplete-story-custom.component.ts | 14 +----- .../autocomplete-story-custom.module.ts | 2 +- .../ui/autocomplete/autocomplete.component.ts | 48 +++++++++++++++++-- 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html index f51d247b..0b6f376a 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html @@ -4,8 +4,6 @@ diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts index 57ade285..018f8e76 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts @@ -1,10 +1,6 @@ import { Component, ChangeDetectionStrategy, ViewEncapsulation, Inject } from '@angular/core'; import { FormGroup, FormBuilder } from '@angular/forms'; import { GetFilterOptionsByKey } from '../../filter-options'; -import { - ES_AUTOCOMPLETE_DEFAULT_OPTIONS, - EsAutocompleteDefaultOptions -} from '../../autocomplete.component'; const OPTIONS = [ { @@ -34,19 +30,11 @@ const OPTIONS = [ export class AutocompleteStoryCustomComponent { public form: FormGroup; public options: any[] = OPTIONS; - public debounceTime: number; - public isCustomSelection = false; - constructor( - private formBuilder: FormBuilder, - @Inject(ES_AUTOCOMPLETE_DEFAULT_OPTIONS) - private autocompleteDefaultOptions: EsAutocompleteDefaultOptions - ) { + constructor(private formBuilder: FormBuilder) { this.form = this.formBuilder.group({ autocomplete: [''] }); - this.debounceTime = autocompleteDefaultOptions.debounceTime; - this.isCustomSelection = autocompleteDefaultOptions.isCustomSelection; } public onChangeText(text: string) { diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts index c6c928d3..6ec804f5 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts @@ -25,7 +25,7 @@ import { AutocompleteStoryCustomComponent } from './autocomplete-story-custom.co { provide: ES_AUTOCOMPLETE_DEFAULT_OPTIONS, useValue: { - debounceTime: 2000, + debounceTime: 1000, isCustomSelection: true } } diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts index f2d8a2c5..cd5e9bdf 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts @@ -13,7 +13,8 @@ import { ViewChild, ContentChild, TemplateRef, - InjectionToken + InjectionToken, + Inject } from '@angular/core'; import { NgControl, ControlValueAccessor, FormGroupDirective } from '@angular/forms'; @@ -53,8 +54,6 @@ export class AutocompleteComponent @Input() public options: any[]; @Input() public isLoading: boolean; - @Input() public isCustomSelection = false; - @Input() public debounceTime: number; @Input() public displayWith = (value?: any): string | undefined => { return value ? value : undefined; }; @@ -71,11 +70,22 @@ export class AutocompleteComponent constructor( @Optional() @Self() public ngControl: NgControl, @Optional() - public ngForm: FormGroupDirective + public ngForm: FormGroupDirective, + @Optional() + @Inject(ES_AUTOCOMPLETE_DEFAULT_OPTIONS) + private autocompleteDefaultOptions: EsAutocompleteDefaultOptions ) { if (this.ngControl != null) { this.ngControl.valueAccessor = this; } + this.debounceTime = + autocompleteDefaultOptions && autocompleteDefaultOptions.debounceTime + ? autocompleteDefaultOptions.debounceTime + : 0; + this.isCustomSelection = + autocompleteDefaultOptions && autocompleteDefaultOptions.isCustomSelection + ? autocompleteDefaultOptions.isCustomSelection + : false; } ngOnInit() { @@ -89,6 +99,36 @@ export class AutocompleteComponent this.changeText.complete(); } + // tslint:disable-next-line variable-name + _debounceTime: number; + + @Input() + get debounceTime(): number { + return this._debounceTime; + } + set debounceTime(value: number) { + this._debounceTime = + value || + (this.autocompleteDefaultOptions && this.autocompleteDefaultOptions.debounceTime) || + 0; + } + + // tslint:disable-next-line variable-name + _isCustomSelection: boolean; + + @Input() + get isCustomSelection(): boolean { + return this._isCustomSelection; + } + set isCustomSelection(value: boolean) { + this._isCustomSelection = + value !== undefined + ? value + : this.autocompleteDefaultOptions && this.autocompleteDefaultOptions.isCustomSelection + ? this.autocompleteDefaultOptions.isCustomSelection + : false; + } + // tslint:disable-next-line variable-name private _value = ''; From 608b89de7043d5b7d296e59a8b7ff7cc0985b11d Mon Sep 17 00:00:00 2001 From: Anna Date: Fri, 17 Jan 2020 10:18:36 +0300 Subject: [PATCH 20/31] fix underfined inputChild bag --- .../elonkit/src/lib/ui/autocomplete/autocomplete.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts index cd5e9bdf..47d53096 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts @@ -222,7 +222,7 @@ export class AutocompleteComponent public openPanel() { setTimeout(() => { - if (!this.focused && !this.disabled) { + if (!this.focused && !this.disabled && this.inputChild) { this.focused = true; // NOTE: workaround to focus when clicked around input (this.inputChild as any)._element.nativeElement.focus(); From 66ef8290b1f30f041c8cdc8becde86bd0c6dc3f5 Mon Sep 17 00:00:00 2001 From: Anna Date: Fri, 17 Jan 2020 10:36:43 +0300 Subject: [PATCH 21/31] add modifiers and change debaunce and delay time --- .../autocomplete-story-default.component.html | 2 +- .../autocomplete-story-default.component.ts | 5 +-- .../autocomplete-story-service.component.html | 2 +- .../autocomplete-story-service.component.ts | 3 -- .../autocomplete.service.ts | 4 +-- .../ui/autocomplete/autocomplete.component.ts | 34 +++++++++---------- .../ui/autocomplete/autocomplete.stories.mdx | 6 ++-- 7 files changed, 25 insertions(+), 31 deletions(-) diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html index 5547acc1..4bea5453 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html @@ -4,7 +4,7 @@ diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts index 7b22f565..c0e244e1 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts @@ -2,9 +2,7 @@ import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/ import { FormGroup, FormBuilder } from '@angular/forms'; import { GetFilterOptions } from '../../filter-options'; -const OPTIONS = ['One', 'Two', 'Three', 'Four', 'Five']; - -const DEBOUNCE = 500; +const OPTIONS = ['One', 'Two', 'Three']; @Component({ selector: 'es-autocomplete-story-default', @@ -16,7 +14,6 @@ const DEBOUNCE = 500; export class AutocompleteStoryDefaultComponent { public form: FormGroup; public options: any[] = OPTIONS; - public debounceTime: number = DEBOUNCE; constructor(private formBuilder: FormBuilder) { this.form = this.formBuilder.group({ diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html index cc84cc62..2ad960ad 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html @@ -5,7 +5,7 @@ formControlName="autocomplete" [options]="options" [isLoading]="isLoading" - [debounceTime]="debounceTime" + [debounceTime]="500" (changeText)="onChangeText($event)" > diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts index 6d878d04..52499e41 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts @@ -11,8 +11,6 @@ import { AutocompleteService } from '../autocomplete-story-service/autocomplete. import { BehaviorSubject, Subscription } from 'rxjs'; import { switchMap, tap } from 'rxjs/operators'; -const DEBOUNCE = 500; - @Component({ selector: 'es-autocomplete-story-service', templateUrl: './autocomplete-story-service.component.html', @@ -26,7 +24,6 @@ export class AutocompleteStoryServiceComponent implements OnDestroy { public form: FormGroup; public options: string[]; public isLoading = false; - public debounceTime: number = DEBOUNCE; private subscription: Subscription | null = null; constructor( diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts index 95710315..32e8a54d 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts @@ -5,7 +5,7 @@ import { of, Observable } from 'rxjs'; import { GetFilterOptions } from '../../filter-options'; -const OPTIONS = ['One', 'Two', 'Three', 'Four', 'Five']; +const OPTIONS = ['One', 'Two', 'Three']; @Injectable() export class AutocompleteService { @@ -13,6 +13,6 @@ export class AutocompleteService { const options = GetFilterOptions(text, OPTIONS); return of({ options - }).pipe(delay(3000)); + }).pipe(delay(1000)); } } diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts index 47d53096..35761f6c 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts @@ -61,11 +61,11 @@ export class AutocompleteComponent return option; }; - @Output() changeText = new EventEmitter(); + @Output() public changeText = new EventEmitter(); @ViewChild('inputChild', { read: MatAutocompleteTrigger, static: true }) @ContentChild(AutocompleteOptionDirective, { read: TemplateRef, static: false }) - optionTemplate; + public optionTemplate: any; constructor( @Optional() @Self() public ngControl: NgControl, @@ -88,7 +88,7 @@ export class AutocompleteComponent : false; } - ngOnInit() { + public ngOnInit() { this.text$.pipe(debounceTime(this.debounceTime)).subscribe(text => { this.changeText.emit(text); }); @@ -100,13 +100,13 @@ export class AutocompleteComponent } // tslint:disable-next-line variable-name - _debounceTime: number; + private _debounceTime: number; @Input() - get debounceTime(): number { + public get debounceTime(): number { return this._debounceTime; } - set debounceTime(value: number) { + public set debounceTime(value: number) { this._debounceTime = value || (this.autocompleteDefaultOptions && this.autocompleteDefaultOptions.debounceTime) || @@ -114,13 +114,13 @@ export class AutocompleteComponent } // tslint:disable-next-line variable-name - _isCustomSelection: boolean; + private _isCustomSelection: boolean; @Input() - get isCustomSelection(): boolean { + public get isCustomSelection(): boolean { return this._isCustomSelection; } - set isCustomSelection(value: boolean) { + public set isCustomSelection(value: boolean) { this._isCustomSelection = value !== undefined ? value @@ -156,11 +156,11 @@ export class AutocompleteComponent return !this.value; } - static nextId = 0; + private static nextId = 0; @HostBinding() public id = `es-autocomplete-${AutocompleteComponent.nextId++}`; @HostBinding('attr.aria-describedby') public describedBy = ''; @HostBinding('class.floating') - public get shouldLabelFloat() { + public get shouldLabelFloat(): boolean { return this.focused || !!this.text; } @@ -192,7 +192,7 @@ export class AutocompleteComponent private _placeholder = ''; @Input() - public get placeholder() { + public get placeholder(): string { return this._placeholder; } @@ -201,7 +201,7 @@ export class AutocompleteComponent this.stateChanges.next(); } - public get errorState() { + public get errorState(): boolean { const control = this.ngControl; const form = this.ngForm; @@ -243,13 +243,13 @@ export class AutocompleteComponent this.onChange = onChange; } - onChange = (_: any) => {}; + public onChange = (_: any) => {}; public registerOnTouched(onTouched: () => void) { this.onTouched = onTouched; } - onTouched = () => {}; + public onTouched = () => {}; public onInput(event: Event) { const target = event.target as HTMLInputElement; @@ -259,12 +259,12 @@ export class AutocompleteComponent this.stateChanges.next(); } - onFocus() { + public onFocus() { this.focused = true; this.stateChanges.next(); } - onBlur() { + public onBlur() { this.onTouched(); this.focused = false; diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx index 9449e693..09b56a80 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx @@ -28,7 +28,7 @@ This component demonstrates usage of storybook. This is a basic story: - + {{ template: ``, moduleMetadata: { @@ -41,7 +41,7 @@ This is a basic story: This is a story with service: - + {{ template: ``, moduleMetadata: { @@ -54,7 +54,7 @@ This is a story with service: This is a story with custom options: - + {{ template: ``, moduleMetadata: { From 0e94898324213b8b08c2b5de06c0178d26bce5cc Mon Sep 17 00:00:00 2001 From: Anna Date: Fri, 17 Jan 2020 14:27:20 +0300 Subject: [PATCH 22/31] fix documentation --- .../autocomplete-story-custom.module.ts | 2 +- .../autocomplete-story-default.component.html | 3 +- .../autocomplete-story-default.component.ts | 4 +- .../ui/autocomplete/autocomplete.component.ts | 122 +++++++++++++++--- .../ui/autocomplete/autocomplete.stories.mdx | 8 +- 5 files changed, 117 insertions(+), 22 deletions(-) diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts index 6ec804f5..6250fe43 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts @@ -26,7 +26,7 @@ import { AutocompleteStoryCustomComponent } from './autocomplete-story-custom.co provide: ES_AUTOCOMPLETE_DEFAULT_OPTIONS, useValue: { debounceTime: 1000, - isCustomSelection: true + freeInput: true } } ] diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html index 4bea5453..f7e73e31 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html @@ -4,7 +4,8 @@ diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts index c0e244e1..5c3bd3ca 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts @@ -1,4 +1,4 @@ -import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; +import { Component, ChangeDetectionStrategy, ViewEncapsulation, Input } from '@angular/core'; import { FormGroup, FormBuilder } from '@angular/forms'; import { GetFilterOptions } from '../../filter-options'; @@ -14,6 +14,8 @@ const OPTIONS = ['One', 'Two', 'Three']; export class AutocompleteStoryDefaultComponent { public form: FormGroup; public options: any[] = OPTIONS; + @Input() public debounceTime: number; + @Input() public freeInput: boolean; constructor(private formBuilder: FormBuilder) { this.form = this.formBuilder.group({ diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts index 35761f6c..e250c04c 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts @@ -20,8 +20,8 @@ import { import { NgControl, ControlValueAccessor, FormGroupDirective } from '@angular/forms'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; -import { Subject } from 'rxjs'; -import { debounceTime } from 'rxjs/operators'; +import { Subject, timer } from 'rxjs'; +import { debounce } from 'rxjs/operators'; import { MatFormFieldControl } from '@angular/material/form-field'; import { MatAutocompleteTrigger } from '@angular/material/autocomplete'; @@ -34,7 +34,7 @@ export const ES_AUTOCOMPLETE_DEFAULT_OPTIONS = new InjectionToken, ControlValueAccessor, OnDestroy, OnInit { + /** + * @ignore + */ public text = ''; + /** + * @ignore + */ public stateChanges = new Subject(); - private inputChild: MatAutocompleteTrigger; private text$ = new Subject(); + /** + * Array of options + */ @Input() public options: any[]; - @Input() public isLoading: boolean; + + /** + * @ignore + */ + @Input() public isLoading = false; + + /** + * 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; }; + /** + * Event emitted when user change text in input + */ @Output() public changeText = new EventEmitter(); @ViewChild('inputChild', { read: MatAutocompleteTrigger, static: true }) + private inputChild: MatAutocompleteTrigger; + + /** + * Template that allows add custom options + */ @ContentChild(AutocompleteOptionDirective, { read: TemplateRef, static: false }) public optionTemplate: any; + /** + * @ignore + */ constructor( @Optional() @Self() public ngControl: NgControl, @Optional() @@ -82,18 +113,24 @@ export class AutocompleteComponent autocompleteDefaultOptions && autocompleteDefaultOptions.debounceTime ? autocompleteDefaultOptions.debounceTime : 0; - this.isCustomSelection = - autocompleteDefaultOptions && autocompleteDefaultOptions.isCustomSelection - ? autocompleteDefaultOptions.isCustomSelection + this.freeInput = + autocompleteDefaultOptions && autocompleteDefaultOptions.freeInput + ? autocompleteDefaultOptions.freeInput : false; } + /** + * @ignore + */ public ngOnInit() { - this.text$.pipe(debounceTime(this.debounceTime)).subscribe(text => { + this.text$.pipe(debounce(() => timer(this.debounceTime))).subscribe(text => { this.changeText.emit(text); }); } + /** + * @ignore + */ public ngOnDestroy() { this.stateChanges.complete(); this.changeText.complete(); @@ -102,6 +139,9 @@ export class AutocompleteComponent // tslint:disable-next-line variable-name private _debounceTime: number; + /** + * Change value after a particular time span has passed + */ @Input() public get debounceTime(): number { return this._debounceTime; @@ -114,18 +154,21 @@ export class AutocompleteComponent } // tslint:disable-next-line variable-name - private _isCustomSelection: boolean; + private _freeInput: boolean; + /** + * If true the user input is not bound to provided options + */ @Input() - public get isCustomSelection(): boolean { - return this._isCustomSelection; + public get freeInput(): boolean { + return this._freeInput; } - public set isCustomSelection(value: boolean) { - this._isCustomSelection = + public set freeInput(value: boolean) { + this._freeInput = value !== undefined ? value - : this.autocompleteDefaultOptions && this.autocompleteDefaultOptions.isCustomSelection - ? this.autocompleteDefaultOptions.isCustomSelection + : this.autocompleteDefaultOptions && this.autocompleteDefaultOptions.freeInput + ? this.autocompleteDefaultOptions.freeInput : false; } @@ -167,6 +210,9 @@ export class AutocompleteComponent // tslint:disable-next-line variable-name private _required = false; + /** + * This property is used to indicate whether the input is required + */ @Input() public get required() { return this._required; @@ -179,6 +225,9 @@ export class AutocompleteComponent // tslint:disable-next-line variable-name private _disabled = false; + /** + * This property tells the form field when it should be in the disabled state + */ @Input() public get disabled(): boolean { return this._disabled; @@ -191,6 +240,9 @@ export class AutocompleteComponent // tslint:disable-next-line variable-name private _placeholder = ''; + /** + * This property allows us to tell component what to use as a placeholder + */ @Input() public get placeholder(): string { return this._placeholder; @@ -212,14 +264,23 @@ export class AutocompleteComponent return false; } + /** + * @ignore + */ public setDescribedByIds(ids: string[]) { this.describedBy = ids.join(' '); } + /** + * @ignore + */ public onContainerClick(event: MouseEvent) { this.openPanel(); } + /** + * @ignore + */ public openPanel() { setTimeout(() => { if (!this.focused && !this.disabled && this.inputChild) { @@ -231,6 +292,9 @@ export class AutocompleteComponent this.stateChanges.next(); } + /** + * @ignore + */ public writeValue(value: any) { if (value !== undefined) { this.value = value; @@ -239,18 +303,33 @@ export class AutocompleteComponent } } + /** + * @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; @@ -259,16 +338,22 @@ export class AutocompleteComponent this.stateChanges.next(); } + /** + * @ignore + */ public onFocus() { this.focused = true; this.stateChanges.next(); } + /** + * @ignore + */ public onBlur() { this.onTouched(); this.focused = false; - if (!this.isCustomSelection) { + if (!this.freeInput) { this.text = this.value; } @@ -276,6 +361,9 @@ export class AutocompleteComponent this.stateChanges.next(); } + /** + * @ignore + */ public onSuggestionSelect(event: Event) { this.value = event; this.onChange(this.value); diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx index 09b56a80..7f963ff4 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx @@ -1,6 +1,6 @@ import { Meta, Preview, Story, Props } from '@storybook/addon-docs/blocks'; -import { withKnobs, text } from '@storybook/addon-knobs'; +import { withKnobs, text, number, boolean } from '@storybook/addon-knobs'; import { action } from '@storybook/addon-actions'; import { withA11y } from '@storybook/addon-a11y'; @@ -30,9 +30,13 @@ This is a basic story: {{ - template: ``, + component: AutocompleteStoryDefaultComponent, moduleMetadata: { imports: [BrowserAnimationsModule, AutocompleteStoryDefaultModule] + }, + props: { + debounceTime: number('debounceTime', 500), + freeInput: boolean('freeInput', false) } }} From 45e9ffc0065472f92fb6729457d255a2fcec76b7 Mon Sep 17 00:00:00 2001 From: Anna Date: Fri, 17 Jan 2020 18:07:55 +0300 Subject: [PATCH 23/31] write documentation and examples for autocomplete --- .../autocomplete-story-custom.component.html | 2 +- .../autocomplete-story-custom.component.ts | 4 +- .../autocomplete-story-custom.source.ts | 69 +++++++++++++++++++ .../autocomplete-story-custom/index.ts | 1 + .../autocomplete-story-default.component.html | 2 +- .../autocomplete-story-default.component.ts | 2 +- .../autocomplete-story-default.source.ts | 37 ++++++++++ .../autocomplete-story-default/index.ts | 1 + .../autocomplete-story-service.component.html | 2 +- .../autocomplete-story-service.component.ts | 4 +- .../autocomplete-story-service.source.ts | 53 ++++++++++++++ .../autocomplete-story-service/index.ts | 1 + .../ui/autocomplete/autocomplete.stories.mdx | 40 ++++++++--- 13 files changed, 202 insertions(+), 16 deletions(-) create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.source.ts create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/index.ts create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.source.ts create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/index.ts create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.source.ts create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/index.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html index 0b6f376a..2ffc6e0b 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html @@ -1,6 +1,6 @@
- Введите сообщение + enter text + + enter text + + + + {{ option.name }} + {{ option.id }} + + + + `, + ts: ` + import { GetFilterOptionsByKey } from '@elonsoft/elonkit/autocomplete'; + + const OPTIONS = [ + { + id: 1, + name: 'Anna', + foto: 'https://joeschmoe.io/api/v1/jenni' + }, + { + id: 2, + name: 'Mary', + foto: 'https://joeschmoe.io/api/v1/julie' + }, + { + id: 3, + name: 'Elena', + foto: 'https://joeschmoe.io/api/v1/jolee' + } + ]; + + @Component(...) + export class AutocompleteStoryCustomComponent { + public form: FormGroup; + public options = OPTIONS; + + constructor(private formBuilder: FormBuilder) { + this.form = this.formBuilder.group({ + autocomplete: '' + }); + } + + public onChangeText(text: string) { + this.options = GetFilterOptionsByKey(text, OPTIONS, 'name'); + } + + public valueFn(option: any): any { + return option.name; + } + } + `, + scss: ` + .es-autocomplete-story-custom { + &__option-img { + height: 25px; + margin-right: 8px; + vertical-align: middle; + } + } + ` +}; diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/index.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/index.ts new file mode 100644 index 00000000..0e04b910 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/index.ts @@ -0,0 +1 @@ +export { AUTOCOMPLETE_STORY_CUSTOM_SOURCE } from './autocomplete-story-custom.source'; diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html index f7e73e31..eadcbccf 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html @@ -1,6 +1,6 @@
- Введите сообщение + enter text + + enter text + + + + `, + ts: ` + import { GetFilterOptions } from '@elonsoft/elonkit/autocomplete'; + + const OPTIONS = ['One', 'Two', 'Three']; + + @Component(...) + export class AutocompleteStoryDefaultComponent { + public form: FormGroup; + public options = OPTIONS; + + constructor(private formBuilder: FormBuilder) { + this.form = this.formBuilder.group({ + autocomplete: '' + }); + } + + public onChangeText(text: string) { + this.options = GetFilterOptions(text, OPTIONS); + } + } + ` +}; diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/index.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/index.ts new file mode 100644 index 00000000..5587652b --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/index.ts @@ -0,0 +1 @@ +export { AUTOCOMPLETE_STORY_DEFAULT_SOURCE } from './autocomplete-story-default.source'; diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html index 2ad960ad..b8e4380d 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html @@ -1,6 +1,6 @@
- Введите сообщение + enter text (''); + private text$ = new BehaviorSubject(''); public form: FormGroup; public options: string[]; @@ -32,7 +32,7 @@ export class AutocompleteStoryServiceComponent implements OnDestroy { private changeDetector: ChangeDetectorRef ) { this.form = this.formBuilder.group({ - autocomplete: [''] + autocomplete: '' }); this.subscription = this.text$ diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.source.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.source.ts new file mode 100644 index 00000000..e5d90916 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.source.ts @@ -0,0 +1,53 @@ +export const AUTOCOMPLETE_STORY_SERVICE_SOURCE = { + html: ` + + + enter text + + + + `, + ts: ` + import { AutocompleteService } from '../autocomplete-story-service/autocomplete.service'; + import { BehaviorSubject } from 'rxjs'; + import { switchMap, tap } from 'rxjs/operators'; + + @Component(...) + export class AutocompleteStoryDefaultComponent { + private text$ = new BehaviorSubject(''); + public form: FormGroup; + public options = string[]; + public isLoading = false; + + constructor( + private formBuilder: FormBuilder, + private autocompleteService: AutocompleteService, + private changeDetector: ChangeDetectorRef + ) { + this.form = this.formBuilder.group({ + autocomplete: '' + }); + this.text$.pipe( + tap(() => { + this.isLoading = true; + }), + switchMap(text => this.autocompleteService.getOptions(text)) + ) + .subscribe(options => { + this.options = options.options; + this.isLoading = false; + this.changeDetector.detectChanges(); + }); + + public onChangeText(text: string) { + this.text$.next(text); + } + } + ` +}; diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/index.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/index.ts new file mode 100644 index 00000000..a022296f --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/index.ts @@ -0,0 +1 @@ +export { AUTOCOMPLETE_STORY_SERVICE_SOURCE } from './autocomplete-story-service.source'; diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx index 7f963ff4..8db5ade5 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx @@ -1,4 +1,5 @@ -import { Meta, Preview, Story, Props } from '@storybook/addon-docs/blocks'; +import { Meta, Story, Props } from '@storybook/addon-docs/blocks'; +import { Preview } from '~storybook/components'; import { withKnobs, text, number, boolean } from '@storybook/addon-knobs'; import { action } from '@storybook/addon-actions'; @@ -10,14 +11,17 @@ import { AutocompleteComponent } from './autocomplete.component'; import { AutocompleteStoryDefaultModule } from './__stories__/autocomplete-story-default/autocomplete-story-default.module'; import { AutocompleteStoryDefaultComponent } from './__stories__/autocomplete-story-default/autocomplete-story-default.component'; +import { AUTOCOMPLETE_STORY_DEFAULT_SOURCE } from './__stories__/autocomplete-story-default/autocomplete-story-default.source'; import { AutocompleteStoryServiceModule } from './__stories__/autocomplete-story-service/autocomplete-story-service.module'; import { AutocompleteStoryServiceComponent } from './__stories__/autocomplete-story-service/autocomplete-story-service.component'; +import { AUTOCOMPLETE_STORY_SERVICE_SOURCE } from './__stories__/autocomplete-story-service/autocomplete-story-service.source'; import { AutocompleteStoryCustomModule } from './__stories__/autocomplete-story-custom/autocomplete-story-custom.module'; import { AutocompleteStoryCustomComponent } from './__stories__/autocomplete-story-custom/autocomplete-story-custom.component'; +import { AUTOCOMPLETE_STORY_CUSTOM_SOURCE } from './__stories__/autocomplete-story-custom/autocomplete-story-custom.source'; - + # Autocomplete @@ -27,8 +31,8 @@ This component demonstrates usage of storybook. This is a basic story: - - + + {{ component: AutocompleteStoryDefaultComponent, moduleMetadata: { @@ -44,8 +48,8 @@ This is a basic story: This is a story with service: - - + + {{ template: ``, moduleMetadata: { @@ -57,8 +61,8 @@ This is a story with service: This is a story with custom options: - - + + {{ template: ``, moduleMetadata: { @@ -71,3 +75,23 @@ This is a story with custom options: ## API + +## Constants + +Injection token to be used to override the default options for es-autocomplete + +```ts +import { ES_AUTOCOMPLETE_DEFAULT_OPTIONS } from '@elonsoft/elonkit/autocomplete'; + +@NgModule({ + providers: [ + { + provide: ES_AUTOCOMPLETE_DEFAULT_OPTIONS, + useValue: { + debounceTime: 1000, + freeInput: true + } + } + ] +}) +``` From cebae5312933a229b6d46c5c685985f2bf31b62a Mon Sep 17 00:00:00 2001 From: Anna Date: Mon, 20 Jan 2020 12:02:03 +0300 Subject: [PATCH 24/31] add ngModel component --- .../autocomplete-story-custom.component.html | 4 +- .../autocomplete-story-custom.component.ts | 6 +- .../autocomplete-story-custom.source.ts | 10 +- .../autocomplete-story-default.component.html | 2 +- .../autocomplete-story-default.component.ts | 2 +- .../autocomplete-story-default.source.ts | 4 +- ...autocomplete-story-ng-model.component.html | 10 ++ ...autocomplete-story-ng-model.component.scss | 5 + .../autocomplete-story-ng-model.component.ts | 20 +++ .../autocomplete-story-ng-model.module.ts | 17 +++ .../autocomplete-story-ng-model.source.ts | 28 ++++ .../autocomplete-story-ng-model/index.ts | 1 + .../autocomplete-story-service.component.html | 2 +- .../autocomplete-story-service.source.ts | 2 +- .../autocomplete.service.ts | 2 +- .../ui/autocomplete/autocomplete.component.ts | 132 +++++++++--------- .../ui/autocomplete/autocomplete.stories.mdx | 19 ++- 17 files changed, 185 insertions(+), 81 deletions(-) create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.html create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.scss create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.ts create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.module.ts create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.source.ts create mode 100644 projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/index.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html index 2ffc6e0b..28629f72 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html @@ -1,6 +1,6 @@
- enter text + Friend - + {{ option.name }} {{ option.id }} diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts index c45533bf..c4751fd2 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts @@ -6,17 +6,17 @@ const OPTIONS = [ { id: 1, name: 'Anna', - foto: 'https://joeschmoe.io/api/v1/jenni' + photo: 'https://joeschmoe.io/api/v1/jenni' }, { id: 2, name: 'Mary', - foto: 'https://joeschmoe.io/api/v1/julie' + photo: 'https://joeschmoe.io/api/v1/julie' }, { id: 3, name: 'Elena', - foto: 'https://joeschmoe.io/api/v1/jolee' + photo: 'https://joeschmoe.io/api/v1/jolee' } ]; diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.source.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.source.ts index 390b605d..0d0db64e 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.source.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.source.ts @@ -2,14 +2,14 @@ export const AUTOCOMPLETE_STORY_CUSTOM_SOURCE = { html: ` - enter text + Friend - + {{ option.name }} {{ option.id }} @@ -23,17 +23,17 @@ export const AUTOCOMPLETE_STORY_CUSTOM_SOURCE = { { id: 1, name: 'Anna', - foto: 'https://joeschmoe.io/api/v1/jenni' + photo: 'https://joeschmoe.io/api/v1/jenni' }, { id: 2, name: 'Mary', - foto: 'https://joeschmoe.io/api/v1/julie' + photo: 'https://joeschmoe.io/api/v1/julie' }, { id: 3, name: 'Elena', - foto: 'https://joeschmoe.io/api/v1/jolee' + photo: 'https://joeschmoe.io/api/v1/jolee' } ]; diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html index eadcbccf..50064a1c 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html @@ -1,6 +1,6 @@ - enter text + Fruit - enter text + Fruit + Season + + + diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.scss b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.scss new file mode 100644 index 00000000..fbeee9a8 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.scss @@ -0,0 +1,5 @@ +.es-autocomplete-story-ng-model { + &.mat-form-field { + width: 100%; + } +} diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.ts new file mode 100644 index 00000000..f56253cc --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.ts @@ -0,0 +1,20 @@ +import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; +import { GetFilterOptions } from '../../filter-options'; + +const OPTIONS = ['Winter', 'Spring', 'Summer', 'Autumn']; + +@Component({ + selector: 'es-autocomplete-story-ng-model', + templateUrl: './autocomplete-story-ng-model.component.html', + styleUrls: ['./autocomplete-story-ng-model.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + encapsulation: ViewEncapsulation.None +}) +export class AutocompleteStoryNgModelComponent { + public options: any[] = OPTIONS; + public text = ''; + + public onChangeText(text: string) { + this.options = GetFilterOptions(text, OPTIONS); + } +} diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.module.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.module.ts new file mode 100644 index 00000000..f9272a79 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { AutocompleteModule } from '../../autocomplete.module'; + +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatButtonModule } from '@angular/material/button'; + +import { AutocompleteStoryNgModelComponent } from './autocomplete-story-ng-model.component'; + +@NgModule({ + declarations: [AutocompleteStoryNgModelComponent], + imports: [CommonModule, FormsModule, AutocompleteModule, MatFormFieldModule, MatButtonModule], + exports: [AutocompleteStoryNgModelComponent] +}) +export class AutocompleteStoryNgModelModule {} diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.source.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.source.ts new file mode 100644 index 00000000..378d027c --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.source.ts @@ -0,0 +1,28 @@ +export const AUTOCOMPLETE_STORY_NG_MODEL_SOURCE = { + html: ` + + Season + + + `, + ts: ` + import { GetFilterOptions } from '@elonsoft/elonkit/autocomplete'; + + const OPTIONS = ['Winter', 'Spring', 'Summer', 'Autumn']; + + @Component(...) + export class AutocompleteStoryNgModelComponent { + public options: any[] = OPTIONS; + public text = ''; + + public onChangeText(text: string) { + this.options = GetFilterOptions(text, OPTIONS); + } + } + ` +}; diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/index.ts b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/index.ts new file mode 100644 index 00000000..de13ca69 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/index.ts @@ -0,0 +1 @@ +export { AUTOCOMPLETE_STORY_NG_MODEL_SOURCE } from './autocomplete-story-ng-model.source'; diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html index b8e4380d..27eccad3 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html @@ -1,6 +1,6 @@ - enter text + Color - enter text + Color (); - - @ViewChild('inputChild', { read: MatAutocompleteTrigger, static: true }) - private inputChild: MatAutocompleteTrigger; - - /** - * Template that allows add custom options - */ - @ContentChild(AutocompleteOptionDirective, { read: TemplateRef, static: false }) - public optionTemplate: any; - - /** - * @ignore - */ - constructor( - @Optional() @Self() public ngControl: NgControl, - @Optional() - public ngForm: FormGroupDirective, - @Optional() - @Inject(ES_AUTOCOMPLETE_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; - } - - /** - * @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(); - } - // tslint:disable-next-line variable-name private _debounceTime: number; @@ -199,14 +145,6 @@ export class AutocompleteComponent return !this.value; } - private static nextId = 0; - @HostBinding() public id = `es-autocomplete-${AutocompleteComponent.nextId++}`; - @HostBinding('attr.aria-describedby') public describedBy = ''; - @HostBinding('class.floating') - public get shouldLabelFloat(): boolean { - return this.focused || !!this.text; - } - // tslint:disable-next-line variable-name private _required = false; @@ -264,6 +202,74 @@ export class AutocompleteComponent return false; } + /** + * Event emitted when user change text in input + */ + @Output() public changeText = new EventEmitter(); + + @ViewChild('inputChild', { read: MatAutocompleteTrigger, static: true }) + private inputChild: MatAutocompleteTrigger; + + /** + * Template that allows add custom options + */ + @ContentChild(AutocompleteOptionDirective, { read: TemplateRef, static: false }) + public optionTemplate: any; + + private static nextId = 0; + @HostBinding() public id = `es-autocomplete-${AutocompleteComponent.nextId++}`; + @HostBinding('attr.aria-describedby') public describedBy = ''; + @HostBinding('class.floating') + public get shouldLabelFloat(): boolean { + return this.focused || !!this.text; + } + + /** + * @ignore + */ + constructor( + private changeDetector: ChangeDetectorRef, + @Optional() @Self() public ngControl: NgControl, + @Optional() + public ngForm: FormGroupDirective, + @Optional() + @Inject(ES_AUTOCOMPLETE_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(); + }); + } + + /** + * @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 */ diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx index 8db5ade5..494001b8 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx @@ -21,11 +21,15 @@ import { AutocompleteStoryCustomModule } from './__stories__/autocomplete-story- import { AutocompleteStoryCustomComponent } from './__stories__/autocomplete-story-custom/autocomplete-story-custom.component'; import { AUTOCOMPLETE_STORY_CUSTOM_SOURCE } from './__stories__/autocomplete-story-custom/autocomplete-story-custom.source'; +import { AutocompleteStoryNgModelModule } from './__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.module'; +import { AutocompleteStoryNgModelComponent } from './__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component'; +import { AUTOCOMPLETE_STORY_NG_MODEL_SOURCE } from './__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.source'; + # Autocomplete -This component demonstrates usage of storybook. +This component demonstrates usage of autocomplete. ## Demos @@ -72,6 +76,19 @@ This is a story with custom options: +This is a story with ngModel: + + + + {{ + template: ``, + moduleMetadata: { + imports: [BrowserAnimationsModule, AutocompleteStoryNgModelModule] + } + }} + + + ## API From f76456c843ca468531e5fc02de3c475ac467b7cc Mon Sep 17 00:00:00 2001 From: Anna Date: Tue, 21 Jan 2020 18:54:13 +0300 Subject: [PATCH 25/31] add tests --- .../autocomplete-story-default.component.html | 12 ++ .../autocomplete/autocomplete.component.html | 3 +- .../ui/autocomplete/autocomplete.component.ts | 20 ++- .../lib/ui/autocomplete/autocomplete.spec.ts | 148 ++++++++++++++++++ .../src/ui/counter/__specs__/counter.spec.ts | 5 +- 5 files changed, 173 insertions(+), 15 deletions(-) create mode 100644 projects/elonkit/src/lib/ui/autocomplete/autocomplete.spec.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html index 50064a1c..2bc112f8 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html @@ -10,4 +10,16 @@ > + +
+
+ + + diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html index 9c0c64ae..0b8be8e1 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html @@ -7,6 +7,7 @@ (input)="onInput($event)" (focus)="onFocus()" (blur)="onBlur()" + data-testid="input" /> - + {{ option }} { - if (!this.focused && !this.disabled && this.inputChild) { - this.focused = true; - // NOTE: workaround to focus when clicked around input - (this.inputChild as any)._element.nativeElement.focus(); - } - }, 0); - this.stateChanges.next(); + 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(); + } } /** diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.spec.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.spec.ts new file mode 100644 index 00000000..e5f29ab0 --- /dev/null +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.spec.ts @@ -0,0 +1,148 @@ +import { render, RenderResult } from '@testing-library/angular'; + +import { inject, fakeAsync, tick } from '@angular/core/testing'; +import { OverlayContainer } from '@angular/cdk/overlay'; + +import { AutocompleteModule } from './autocomplete.module'; +import { AutocompleteComponent } from './autocomplete.component'; + +const FRUITS = ['Apple', 'Lemon', 'Mango']; + +describe('Autocomplete', () => { + let component: RenderResult; + let overlay: OverlayContainer; + let overlayElement: HTMLElement; + + beforeEach(async () => { + component = await render(AutocompleteComponent, { + imports: [AutocompleteModule], + 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 show length of options array', fakeAsync(async () => { + const input = component.getByTestId('input'); + + component.focusIn(input); + + const options = overlayElement.querySelectorAll('[data-testid="mat-option"]'); + expect(options).toHaveLength(3); + + // for (let i = 0; i < FRUITS.length; i++) { + // expect(options[i].textContent).toContain(FRUITS[i]); + // } + + // all items of FRUITS array contain in overlay + for (const fruit of FRUITS) { + expect(overlayElement.textContent).toContain(fruit); + } + })); + + it('Output changeText, Input debounce time', fakeAsync(async () => { + const onChangeText = jest.fn(); + component.fixture.componentInstance.changeText.emit = onChangeText; + + const input = component.getByTestId('input'); + + component.input(input, { target: { value: 'Foo' } }); + + tick(); + expect(onChangeText).toBeCalledTimes(1); + expect(onChangeText).toBeCalledWith('Foo'); + + component.fixture.componentInstance.debounceTime = 100; + component.fixture.componentInstance.changeDetector.detectChanges(); + + component.input(input, { target: { value: 'Bar' } }); + + tick(99); + expect(onChangeText).toBeCalledTimes(1); + + tick(1); + expect(onChangeText).toBeCalledTimes(2); + expect(onChangeText).toBeCalledWith('Bar'); + })); + + it('Input freeInput === true', fakeAsync(async () => { + component.fixture.componentInstance.freeInput = true; + component.fixture.componentInstance.changeDetector.detectChanges(); + + const input = component.getByTestId('input'); + + // if user did not choose some option + component.focusIn(input); + tick(); + + component.input(input, { target: { value: 'Baz' } }); + tick(); + + component.blur(input); + tick(); + + expect(component.getByDisplayValue('Baz')); + + // if user choose some option + component.focusIn(input); + tick(); + + const options = overlayElement.querySelectorAll('[data-testid="mat-option"]'); + component.click(options[0]); + tick(); + + component.input(input, { target: { value: 'Apple232323' } }); + tick(); + + component.blur(input); + tick(); + + expect(component.getByDisplayValue('Apple232323')); + })); + + it('Input freeInput === false', fakeAsync(async () => { + component.fixture.componentInstance.freeInput = false; + component.fixture.componentInstance.changeDetector.detectChanges(); + + const input = component.getByTestId('input'); + + // if user did not choose some option + component.focusIn(input); + tick(); + + component.input(input, { target: { value: 'Baz' } }); + tick(); + + component.blur(input); + tick(); + + expect(component.getByDisplayValue('')); + + // if user choose some option + component.focusIn(input); + tick(); + + const options = overlayElement.querySelectorAll('[data-testid="mat-option"]'); + component.click(options[0]); + tick(); + + component.input(input, { target: { value: 'Apple232323' } }); + tick(); + + component.blur(input); + tick(); + + expect(component.getByDisplayValue('Apple')); + })); +}); diff --git a/projects/elonkit/src/ui/counter/__specs__/counter.spec.ts b/projects/elonkit/src/ui/counter/__specs__/counter.spec.ts index 22de7713..7ba3529c 100644 --- a/projects/elonkit/src/ui/counter/__specs__/counter.spec.ts +++ b/projects/elonkit/src/ui/counter/__specs__/counter.spec.ts @@ -54,15 +54,14 @@ describe('Counter', () => { // We can emulate user interaction click(button); + expect(onIncrease).toHaveBeenCalledWith(1); expect(getByText('You clicked 1 times')).toBeInTheDocument(); expect(getByText('You clicked 1 times')).toHaveClass('es-counter__count_active'); click(button); + expect(onIncrease).toHaveBeenCalledWith(2); expect(getByText('You clicked 2 times')).toBeInTheDocument(); expect(getByText('You clicked 2 times')).toHaveClass('es-counter__count_active'); - - expect(onIncrease).toHaveBeenNthCalledWith(1, 1); - expect(onIncrease).toHaveBeenNthCalledWith(2, 2); }); }); From 7e8ad5cdb1188c629eb7155c6abfe315015fd863 Mon Sep 17 00:00:00 2001 From: Anna Date: Wed, 22 Jan 2020 10:54:59 +0300 Subject: [PATCH 26/31] fix text headings and create text constants --- .../lib/ui/autocomplete/autocomplete.spec.ts | 213 ++++++++++-------- 1 file changed, 115 insertions(+), 98 deletions(-) diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.spec.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.spec.ts index e5f29ab0..8a51a540 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.spec.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.spec.ts @@ -9,140 +9,157 @@ import { AutocompleteComponent } from './autocomplete.component'; const FRUITS = ['Apple', 'Lemon', 'Mango']; describe('Autocomplete', () => { - let component: RenderResult; - let overlay: OverlayContainer; - let overlayElement: HTMLElement; - - beforeEach(async () => { - component = await render(AutocompleteComponent, { - imports: [AutocompleteModule], - componentProperties: { - options: FRUITS - }, - excludeComponentDeclaration: true + describe('Base', () => { + let component: RenderResult; + let overlay: OverlayContainer; + let overlayElement: HTMLElement; + + beforeEach(async () => { + component = await render(AutocompleteComponent, { + imports: [AutocompleteModule], + componentProperties: { + options: FRUITS + }, + excludeComponentDeclaration: true + }); + + inject([OverlayContainer], (oc: OverlayContainer) => { + overlay = oc; + overlayElement = oc.getContainerElement(); + })(); }); - 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); - // afterEach(inject([OverlayContainer], (currentOverlay: OverlayContainer) => { - // currentOverlay.ngOnDestroy(); - // overlay.ngOnDestroy(); - // })); + const options = overlayElement.querySelectorAll('[data-testid="mat-option"]'); + expect(options).toHaveLength(3); - it('Should show length of options array', fakeAsync(async () => { - const input = component.getByTestId('input'); + // for (let i = 0; i < FRUITS.length; i++) { + // expect(options[i].textContent).toContain(FRUITS[i]); + // } - component.focusIn(input); + // all items of FRUITS array contain in overlay + for (const fruit of FRUITS) { + expect(overlayElement.textContent).toContain(fruit); + } + })); - const options = overlayElement.querySelectorAll('[data-testid="mat-option"]'); - expect(options).toHaveLength(3); + it('Should change value on input text in view of debounce time', fakeAsync(async () => { + const TEXT_FOO = 'Foo'; + const TEXT_BAR = 'Bar'; + const onChangeText = jest.fn(); + component.fixture.componentInstance.changeText.emit = onChangeText; - // for (let i = 0; i < FRUITS.length; i++) { - // expect(options[i].textContent).toContain(FRUITS[i]); - // } + const input = component.getByTestId('input'); - // all items of FRUITS array contain in overlay - for (const fruit of FRUITS) { - expect(overlayElement.textContent).toContain(fruit); - } - })); + component.input(input, { target: { value: TEXT_FOO } }); - it('Output changeText, Input debounce time', fakeAsync(async () => { - const onChangeText = jest.fn(); - component.fixture.componentInstance.changeText.emit = onChangeText; + tick(); + expect(onChangeText).toBeCalledTimes(1); + expect(onChangeText).toBeCalledWith(TEXT_FOO); - const input = component.getByTestId('input'); + component.fixture.componentInstance.debounceTime = 100; + component.fixture.componentInstance.changeDetector.detectChanges(); - component.input(input, { target: { value: 'Foo' } }); + component.input(input, { target: { value: TEXT_BAR } }); - tick(); - expect(onChangeText).toBeCalledTimes(1); - expect(onChangeText).toBeCalledWith('Foo'); + tick(99); + expect(onChangeText).toBeCalledTimes(1); - component.fixture.componentInstance.debounceTime = 100; - component.fixture.componentInstance.changeDetector.detectChanges(); + tick(1); + expect(onChangeText).toBeCalledTimes(2); + expect(onChangeText).toBeCalledWith(TEXT_BAR); + })); - component.input(input, { target: { value: 'Bar' } }); + it('Should display entered text any kind', fakeAsync(async () => { + const TEXT_BAZ = 'Baz'; + const TEXT_APPLE_SMTH = 'Apple232323'; - tick(99); - expect(onChangeText).toBeCalledTimes(1); + component.fixture.componentInstance.freeInput = true; + component.fixture.componentInstance.changeDetector.detectChanges(); - tick(1); - expect(onChangeText).toBeCalledTimes(2); - expect(onChangeText).toBeCalledWith('Bar'); - })); + const input = component.getByTestId('input'); - it('Input freeInput === true', fakeAsync(async () => { - component.fixture.componentInstance.freeInput = true; - component.fixture.componentInstance.changeDetector.detectChanges(); + // if user did not choose some option + component.focusIn(input); + tick(); - const input = component.getByTestId('input'); + component.input(input, { target: { value: TEXT_BAZ } }); + tick(); - // if user did not choose some option - component.focusIn(input); - tick(); + component.blur(input); + tick(); - component.input(input, { target: { value: 'Baz' } }); - tick(); + expect(component.getByDisplayValue(TEXT_BAZ)); - component.blur(input); - tick(); + // if user choose some option + component.focusIn(input); + tick(); - expect(component.getByDisplayValue('Baz')); + const options = overlayElement.querySelectorAll('[data-testid="mat-option"]'); + component.click(options[0]); + tick(); - // if user choose some option - component.focusIn(input); - tick(); + component.input(input, { target: { value: TEXT_APPLE_SMTH } }); + tick(); - const options = overlayElement.querySelectorAll('[data-testid="mat-option"]'); - component.click(options[0]); - tick(); + component.blur(input); + tick(); - component.input(input, { target: { value: 'Apple232323' } }); - tick(); + expect(component.getByDisplayValue(TEXT_APPLE_SMTH)); + })); - component.blur(input); - tick(); + it('Should display entered text only from options', fakeAsync(async () => { + const TEXT_BAZ = 'Baz'; + const TEXT_APPLE = 'Apple'; + const TEXT_APPLE_SMTH = 'Apple232323'; - expect(component.getByDisplayValue('Apple232323')); - })); + component.fixture.componentInstance.freeInput = false; + component.fixture.componentInstance.changeDetector.detectChanges(); - it('Input freeInput === false', fakeAsync(async () => { - component.fixture.componentInstance.freeInput = false; - component.fixture.componentInstance.changeDetector.detectChanges(); + const input = component.getByTestId('input'); - const input = component.getByTestId('input'); + // if user did not choose some option + component.focusIn(input); + tick(); - // if user did not choose some option - component.focusIn(input); - tick(); + component.input(input, { target: { value: TEXT_BAZ } }); + tick(); - component.input(input, { target: { value: 'Baz' } }); - tick(); + component.blur(input); + tick(); - component.blur(input); - tick(); + expect(component.getByDisplayValue('')); - expect(component.getByDisplayValue('')); + // if user choose some option + component.focusIn(input); + tick(); - // if user choose some option - component.focusIn(input); - tick(); + const options = overlayElement.querySelectorAll('[data-testid="mat-option"]'); + component.click(options[0]); + tick(); - const options = overlayElement.querySelectorAll('[data-testid="mat-option"]'); - component.click(options[0]); - tick(); + component.input(input, { target: { value: TEXT_APPLE_SMTH } }); + tick(); - component.input(input, { target: { value: 'Apple232323' } }); - tick(); + component.blur(input); + tick(); - component.blur(input); - tick(); + expect(component.getByDisplayValue(TEXT_APPLE)); + })); + }); - expect(component.getByDisplayValue('Apple')); - })); + describe('Custom options', () => { + it('Should fail', () => { + expect(2 + 2).toBe(4); + }); + }); }); From 5081a25b50ab0de6a3ca02a8d42e4b778c703f78 Mon Sep 17 00:00:00 2001 From: Anna Date: Wed, 22 Jan 2020 13:32:49 +0300 Subject: [PATCH 27/31] add template options test --- .../lib/ui/autocomplete/autocomplete.spec.ts | 91 +++++++++++++++++-- 1 file changed, 81 insertions(+), 10 deletions(-) diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.spec.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.spec.ts index 8a51a540..77bcae73 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.spec.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.spec.ts @@ -1,3 +1,6 @@ +import { FormsModule } from '@angular/forms'; +import { MatFormFieldModule } from '@angular/material/form-field'; + import { render, RenderResult } from '@testing-library/angular'; import { inject, fakeAsync, tick } from '@angular/core/testing'; @@ -5,8 +8,45 @@ import { OverlayContainer } from '@angular/cdk/overlay'; import { AutocompleteModule } from './autocomplete.module'; import { AutocompleteComponent } from './autocomplete.component'; +import { Component } from '@angular/core'; + +@Component({ + template: ` + + Friend + + + + {{ option.name }} + + + + ` +}) +class AutocompleteCustomComponent { + public text = ''; + public options: any[] = FRIENDS; + public valueFn(option: any): any { + return option.name; + } +} const FRUITS = ['Apple', 'Lemon', 'Mango']; +const FRIENDS = [ + { + name: 'Anna', + photo: 'https://joeschmoe.io/api/v1/jenni' + }, + { + name: 'Mary', + photo: 'https://joeschmoe.io/api/v1/julie' + } +]; describe('Autocomplete', () => { describe('Base', () => { @@ -29,10 +69,10 @@ describe('Autocomplete', () => { })(); }); - // afterEach(inject([OverlayContainer], (currentOverlay: OverlayContainer) => { - // currentOverlay.ngOnDestroy(); - // overlay.ngOnDestroy(); - // })); + afterEach(inject([OverlayContainer], (currentOverlay: OverlayContainer) => { + currentOverlay.ngOnDestroy(); + overlay.ngOnDestroy(); + })); it('Should display passed options', fakeAsync(async () => { const input = component.getByTestId('input'); @@ -42,10 +82,6 @@ describe('Autocomplete', () => { const options = overlayElement.querySelectorAll('[data-testid="mat-option"]'); expect(options).toHaveLength(3); - // for (let i = 0; i < FRUITS.length; i++) { - // expect(options[i].textContent).toContain(FRUITS[i]); - // } - // all items of FRUITS array contain in overlay for (const fruit of FRUITS) { expect(overlayElement.textContent).toContain(fruit); @@ -158,8 +194,43 @@ describe('Autocomplete', () => { }); describe('Custom options', () => { - it('Should fail', () => { - expect(2 + 2).toBe(4); + let component: RenderResult; + let overlay: OverlayContainer; + let overlayElement: HTMLElement; + + beforeEach(async () => { + component = await render(AutocompleteCustomComponent, { + imports: [AutocompleteModule, FormsModule, MatFormFieldModule], + componentProperties: { + options: FRIENDS + } + }); + + inject([OverlayContainer], (oc: OverlayContainer) => { + overlay = oc; + overlayElement = oc.getContainerElement(); + })(); }); + + afterEach(inject([OverlayContainer], (currentOverlay: OverlayContainer) => { + currentOverlay.ngOnDestroy(); + overlay.ngOnDestroy(); + })); + + it('Should display options with photo and name', fakeAsync(async () => { + const input = component.getByTestId('input'); + + component.focusIn(input); + + const options = overlayElement.querySelectorAll('[data-testid="mat-option"]'); + + expect(options).toHaveLength(2); + + for (let i = 0; i < FRIENDS.length; i++) { + const image = options[i].querySelector('img'); + expect(options[i].textContent).toContain(FRIENDS[i].name); + expect(image).toHaveAttribute('src', FRIENDS[i].photo); + } + })); }); }); From a298abc69d7732e9d9d1eb85e61e721dd0146040 Mon Sep 17 00:00:00 2001 From: Denis Yakshov Date: Mon, 27 Jan 2020 12:46:25 +0300 Subject: [PATCH 28/31] Fix autocomplete dropdown position --- .../autocomplete/autocomplete.component.html | 1 + .../ui/autocomplete/autocomplete.component.ts | 21 +++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html index 0b8be8e1..bbe66945 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html @@ -2,6 +2,7 @@ matInput #inputChild [matAutocomplete]="auto" + [matAutocompleteConnectedTo]="origin" [value]="text" [disabled]="disabled" (input)="onInput($event)" diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts index 68529031..b15890b8 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts +++ b/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts @@ -15,7 +15,8 @@ import { ContentChild, TemplateRef, InjectionToken, - Inject + Inject, + Host } from '@angular/core'; import { NgControl, ControlValueAccessor, FormGroupDirective } from '@angular/forms'; @@ -24,8 +25,8 @@ import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { Subject, timer } from 'rxjs'; import { debounce } from 'rxjs/operators'; -import { MatFormFieldControl } from '@angular/material/form-field'; -import { MatAutocompleteTrigger } from '@angular/material/autocomplete'; +import { MatFormField, MatFormFieldControl } from '@angular/material/form-field'; +import { MatAutocompleteTrigger, MatAutocompleteOrigin } from '@angular/material/autocomplete'; import { AutocompleteOptionDirective } from '../autocomplete/autocomplete-option.directive'; @@ -58,6 +59,11 @@ export class AutocompleteComponent public stateChanges = new Subject(); private text$ = new Subject(); + /** + * @ignore + */ + public origin: MatAutocompleteOrigin; + /** * Array of options */ @@ -234,7 +240,8 @@ export class AutocompleteComponent public ngForm: FormGroupDirective, @Optional() @Inject(ES_AUTOCOMPLETE_DEFAULT_OPTIONS) - private autocompleteDefaultOptions: EsAutocompleteDefaultOptions + private autocompleteDefaultOptions: EsAutocompleteDefaultOptions, + @Optional() @Host() private matFormField: MatFormField ) { if (this.ngControl != null) { this.ngControl.valueAccessor = this; @@ -257,6 +264,12 @@ export class AutocompleteComponent * @ignore */ public ngOnInit() { + if (this.matFormField) { + this.origin = { + elementRef: this.matFormField.getConnectedOverlayOrigin() + }; + } + this.text$.pipe(debounce(() => timer(this.debounceTime))).subscribe(text => { this.changeText.emit(text); }); From 0136f314967c9bc1fa7d8fd4fb6ba56b45efed6b Mon Sep 17 00:00:00 2001 From: Denis Yakshov Date: Tue, 25 Feb 2020 11:09:07 +0300 Subject: [PATCH 29/31] Add public api --- jest.setup.ts | 2 +- projects/elonkit/src/lib/ui/autocomplete/index.ts | 3 --- projects/elonkit/src/public-api.ts | 1 + .../autocomplete/__specs__}/autocomplete.spec.ts | 12 ++++++------ .../autocomplete-story-custom.component.html | 0 .../autocomplete-story-custom.component.scss | 0 .../autocomplete-story-custom.component.ts | 0 .../autocomplete-story-custom.module.ts | 0 .../autocomplete-story-custom.source.ts | 0 .../__stories__/autocomplete-story-custom/index.ts | 0 .../autocomplete-story-default.component.html | 0 .../autocomplete-story-default.component.scss | 0 .../autocomplete-story-default.component.ts | 0 .../autocomplete-story-default.module.ts | 0 .../autocomplete-story-default.source.ts | 0 .../__stories__/autocomplete-story-default/index.ts | 0 .../autocomplete-story-ng-model.component.html | 0 .../autocomplete-story-ng-model.component.scss | 0 .../autocomplete-story-ng-model.component.ts | 0 .../autocomplete-story-ng-model.module.ts | 0 .../autocomplete-story-ng-model.source.ts | 0 .../__stories__/autocomplete-story-ng-model/index.ts | 0 .../autocomplete-story-service.component.html | 0 .../autocomplete-story-service.component.scss | 0 .../autocomplete-story-service.component.ts | 0 .../autocomplete-story-service.module.ts | 0 .../autocomplete-story-service.source.ts | 0 .../autocomplete.service.ts | 0 .../__stories__/autocomplete-story-service/index.ts | 0 .../ui/autocomplete/autocomplete-option.directive.ts | 0 .../ui/autocomplete/autocomplete.component.html | 0 .../ui/autocomplete/autocomplete.component.scss | 0 .../ui/autocomplete/autocomplete.component.ts | 0 .../{lib => }/ui/autocomplete/autocomplete.module.ts | 0 .../ui/autocomplete/autocomplete.stories.mdx | 0 .../src/{lib => }/ui/autocomplete/filter-options.ts | 0 projects/elonkit/src/ui/autocomplete/index.ts | 1 + projects/elonkit/src/ui/autocomplete/ng-package.json | 5 +++++ projects/elonkit/src/ui/autocomplete/public-api.ts | 3 +++ 39 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 projects/elonkit/src/lib/ui/autocomplete/index.ts rename projects/elonkit/src/{lib/ui/autocomplete => ui/autocomplete/__specs__}/autocomplete.spec.ts (98%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.scss (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.source.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-custom/index.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.scss (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.module.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.source.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-default/index.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.html (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.scss (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.module.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.source.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-ng-model/index.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.scss (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.module.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.source.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/__stories__/autocomplete-story-service/index.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/autocomplete-option.directive.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/autocomplete.component.html (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/autocomplete.component.scss (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/autocomplete.component.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/autocomplete.module.ts (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/autocomplete.stories.mdx (100%) rename projects/elonkit/src/{lib => }/ui/autocomplete/filter-options.ts (100%) create mode 100644 projects/elonkit/src/ui/autocomplete/index.ts create mode 100644 projects/elonkit/src/ui/autocomplete/ng-package.json create mode 100644 projects/elonkit/src/ui/autocomplete/public-api.ts diff --git a/jest.setup.ts b/jest.setup.ts index aa5a853b..e06f1834 100644 --- a/jest.setup.ts +++ b/jest.setup.ts @@ -1,2 +1,2 @@ // https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom/extend-expect'; +import '@testing-library/jest-dom'; diff --git a/projects/elonkit/src/lib/ui/autocomplete/index.ts b/projects/elonkit/src/lib/ui/autocomplete/index.ts deleted file mode 100644 index fda910de..00000000 --- a/projects/elonkit/src/lib/ui/autocomplete/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { AutocompleteModule } from './autocomplete.module'; -export { AutocompleteComponent } from './autocomplete.component'; -export { GetFilterOptions, GetFilterOptionsByKey } from './filter-options'; diff --git a/projects/elonkit/src/public-api.ts b/projects/elonkit/src/public-api.ts index 1fb27f35..4db48736 100644 --- a/projects/elonkit/src/public-api.ts +++ b/projects/elonkit/src/public-api.ts @@ -1,3 +1,4 @@ +export * from './ui/autocomplete'; export * from './ui/counter'; export * from './ui/inline-form-field'; export * from './ui/timepicker'; diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.spec.ts b/projects/elonkit/src/ui/autocomplete/__specs__/autocomplete.spec.ts similarity index 98% rename from projects/elonkit/src/lib/ui/autocomplete/autocomplete.spec.ts rename to projects/elonkit/src/ui/autocomplete/__specs__/autocomplete.spec.ts index 77bcae73..106c697a 100644 --- a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.spec.ts +++ b/projects/elonkit/src/ui/autocomplete/__specs__/autocomplete.spec.ts @@ -1,14 +1,14 @@ +import { Component } from '@angular/core'; +import { inject, fakeAsync, tick } from '@angular/core/testing'; + import { FormsModule } from '@angular/forms'; + +import { OverlayContainer } from '@angular/cdk/overlay'; import { MatFormFieldModule } from '@angular/material/form-field'; import { render, RenderResult } from '@testing-library/angular'; -import { inject, fakeAsync, tick } from '@angular/core/testing'; -import { OverlayContainer } from '@angular/cdk/overlay'; - -import { AutocompleteModule } from './autocomplete.module'; -import { AutocompleteComponent } from './autocomplete.component'; -import { Component } from '@angular/core'; +import { AutocompleteModule, AutocompleteComponent } from '..'; @Component({ template: ` diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.html diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.scss b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.scss similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.scss rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.scss diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.component.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.source.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.source.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.source.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.source.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/index.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/index.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-custom/index.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/index.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.scss b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.scss similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.scss rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.scss diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.module.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.module.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.module.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.module.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.source.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.source.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.source.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.source.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/index.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-default/index.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-default/index.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-default/index.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.html b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.html similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.html rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.html diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.scss b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.scss similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.scss rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.scss diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.module.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.module.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.module.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.module.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.source.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.source.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.source.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.source.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/index.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/index.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-ng-model/index.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/index.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.scss b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.scss similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.scss rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.scss diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.module.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.module.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.module.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.module.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.source.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.source.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.source.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.source.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/index.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/index.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/__stories__/autocomplete-story-service/index.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/index.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete-option.directive.ts b/projects/elonkit/src/ui/autocomplete/autocomplete-option.directive.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/autocomplete-option.directive.ts rename to projects/elonkit/src/ui/autocomplete/autocomplete-option.directive.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html b/projects/elonkit/src/ui/autocomplete/autocomplete.component.html similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.html rename to projects/elonkit/src/ui/autocomplete/autocomplete.component.html diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss b/projects/elonkit/src/ui/autocomplete/autocomplete.component.scss similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.scss rename to projects/elonkit/src/ui/autocomplete/autocomplete.component.scss diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/ui/autocomplete/autocomplete.component.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/autocomplete.component.ts rename to projects/elonkit/src/ui/autocomplete/autocomplete.component.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts b/projects/elonkit/src/ui/autocomplete/autocomplete.module.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/autocomplete.module.ts rename to projects/elonkit/src/ui/autocomplete/autocomplete.module.ts diff --git a/projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx b/projects/elonkit/src/ui/autocomplete/autocomplete.stories.mdx similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/autocomplete.stories.mdx rename to projects/elonkit/src/ui/autocomplete/autocomplete.stories.mdx diff --git a/projects/elonkit/src/lib/ui/autocomplete/filter-options.ts b/projects/elonkit/src/ui/autocomplete/filter-options.ts similarity index 100% rename from projects/elonkit/src/lib/ui/autocomplete/filter-options.ts rename to projects/elonkit/src/ui/autocomplete/filter-options.ts diff --git a/projects/elonkit/src/ui/autocomplete/index.ts b/projects/elonkit/src/ui/autocomplete/index.ts new file mode 100644 index 00000000..7e1a213e --- /dev/null +++ b/projects/elonkit/src/ui/autocomplete/index.ts @@ -0,0 +1 @@ +export * from './public-api'; diff --git a/projects/elonkit/src/ui/autocomplete/ng-package.json b/projects/elonkit/src/ui/autocomplete/ng-package.json new file mode 100644 index 00000000..789c95e4 --- /dev/null +++ b/projects/elonkit/src/ui/autocomplete/ng-package.json @@ -0,0 +1,5 @@ +{ + "lib": { + "entryFile": "public-api.ts" + } +} diff --git a/projects/elonkit/src/ui/autocomplete/public-api.ts b/projects/elonkit/src/ui/autocomplete/public-api.ts new file mode 100644 index 00000000..64f2d6cb --- /dev/null +++ b/projects/elonkit/src/ui/autocomplete/public-api.ts @@ -0,0 +1,3 @@ +export * from './autocomplete.module'; +export * from './autocomplete.component'; +export * from './filter-options'; From 30ae05f19910d009545f6c24c5064477fafc0132 Mon Sep 17 00:00:00 2001 From: Denis Yakshov Date: Wed, 26 Feb 2020 10:34:22 +0300 Subject: [PATCH 30/31] Clean some code --- .../autocomplete-story-custom.source.ts | 9 +-- ...autocomplete-story-ng-model.component.html | 10 --- ...autocomplete-story-ng-model.component.scss | 5 -- .../autocomplete-story-ng-model.component.ts | 20 ------ .../autocomplete-story-ng-model.module.ts | 17 ----- .../autocomplete-story-ng-model.source.ts | 28 -------- .../autocomplete-story-ng-model/index.ts | 1 - .../autocomplete-story-service.component.html | 2 +- .../autocomplete-story-service.component.ts | 4 +- .../autocomplete-story-service.module.ts | 11 ++-- ... => autocomplete-story-service.service.ts} | 2 +- .../autocomplete/autocomplete.component.html | 4 +- .../ui/autocomplete/autocomplete.component.ts | 66 +++++++++---------- .../ui/autocomplete/autocomplete.stories.mdx | 17 ----- 14 files changed, 48 insertions(+), 148 deletions(-) delete mode 100644 projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.html delete mode 100644 projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.scss delete mode 100644 projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.ts delete mode 100644 projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.module.ts delete mode 100644 projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.source.ts delete mode 100644 projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/index.ts rename projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/{autocomplete.service.ts => autocomplete-story-service.service.ts} (89%) diff --git a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.source.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.source.ts index 0d0db64e..54212670 100644 --- a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.source.ts +++ b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.source.ts @@ -7,13 +7,14 @@ export const AUTOCOMPLETE_STORY_CUSTOM_SOURCE = { formControlName="autocomplete" [options]="options" [valueFn]="valueFn" - (changeText)="onChangeText($event)"> + (changeText)="onChangeText($event)" + > - + {{ option.name }} {{ option.id }} -
+
`, ts: ` @@ -59,7 +60,7 @@ export const AUTOCOMPLETE_STORY_CUSTOM_SOURCE = { `, scss: ` .es-autocomplete-story-custom { - &__option-img { + &__image { height: 25px; margin-right: 8px; vertical-align: middle; diff --git a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.html b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.html deleted file mode 100644 index e4de5628..00000000 --- a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.html +++ /dev/null @@ -1,10 +0,0 @@ - - Season - - - diff --git a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.scss b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.scss deleted file mode 100644 index fbeee9a8..00000000 --- a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.scss +++ /dev/null @@ -1,5 +0,0 @@ -.es-autocomplete-story-ng-model { - &.mat-form-field { - width: 100%; - } -} diff --git a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.ts deleted file mode 100644 index f56253cc..00000000 --- a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core'; -import { GetFilterOptions } from '../../filter-options'; - -const OPTIONS = ['Winter', 'Spring', 'Summer', 'Autumn']; - -@Component({ - selector: 'es-autocomplete-story-ng-model', - templateUrl: './autocomplete-story-ng-model.component.html', - styleUrls: ['./autocomplete-story-ng-model.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, - encapsulation: ViewEncapsulation.None -}) -export class AutocompleteStoryNgModelComponent { - public options: any[] = OPTIONS; - public text = ''; - - public onChangeText(text: string) { - this.options = GetFilterOptions(text, OPTIONS); - } -} diff --git a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.module.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.module.ts deleted file mode 100644 index f9272a79..00000000 --- a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.module.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { NgModule } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; - -import { AutocompleteModule } from '../../autocomplete.module'; - -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatButtonModule } from '@angular/material/button'; - -import { AutocompleteStoryNgModelComponent } from './autocomplete-story-ng-model.component'; - -@NgModule({ - declarations: [AutocompleteStoryNgModelComponent], - imports: [CommonModule, FormsModule, AutocompleteModule, MatFormFieldModule, MatButtonModule], - exports: [AutocompleteStoryNgModelComponent] -}) -export class AutocompleteStoryNgModelModule {} diff --git a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.source.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.source.ts deleted file mode 100644 index 378d027c..00000000 --- a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.source.ts +++ /dev/null @@ -1,28 +0,0 @@ -export const AUTOCOMPLETE_STORY_NG_MODEL_SOURCE = { - html: ` - - Season - - - `, - ts: ` - import { GetFilterOptions } from '@elonsoft/elonkit/autocomplete'; - - const OPTIONS = ['Winter', 'Spring', 'Summer', 'Autumn']; - - @Component(...) - export class AutocompleteStoryNgModelComponent { - public options: any[] = OPTIONS; - public text = ''; - - public onChangeText(text: string) { - this.options = GetFilterOptions(text, OPTIONS); - } - } - ` -}; diff --git a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/index.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/index.ts deleted file mode 100644 index de13ca69..00000000 --- a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-ng-model/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { AUTOCOMPLETE_STORY_NG_MODEL_SOURCE } from './autocomplete-story-ng-model.source'; diff --git a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html index 27eccad3..b42e3b58 100644 --- a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html +++ b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.html @@ -4,7 +4,7 @@ diff --git a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts index 9756c34b..f690517b 100644 --- a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts +++ b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.component.ts @@ -6,7 +6,7 @@ import { OnDestroy } from '@angular/core'; import { FormGroup, FormBuilder } from '@angular/forms'; -import { AutocompleteService } from '../autocomplete-story-service/autocomplete.service'; +import { AutocompleteStoryServiceService } from './autocomplete-story-service.service'; import { BehaviorSubject, Subscription } from 'rxjs'; import { switchMap, tap } from 'rxjs/operators'; @@ -28,7 +28,7 @@ export class AutocompleteStoryServiceComponent implements OnDestroy { constructor( private formBuilder: FormBuilder, - private autocompleteService: AutocompleteService, + private autocompleteService: AutocompleteStoryServiceService, private changeDetector: ChangeDetectorRef ) { this.form = this.formBuilder.group({ diff --git a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.module.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.module.ts index d3d44bc2..963d354b 100644 --- a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.module.ts +++ b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.module.ts @@ -2,25 +2,26 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ReactiveFormsModule } from '@angular/forms'; -import { AutocompleteModule } from '../../autocomplete.module'; +import { AutocompleteModule } from '../..'; -import { MatFormFieldModule } from '@angular/material/form-field'; import { MatButtonModule } from '@angular/material/button'; - -import { AutocompleteService } from '../autocomplete-story-service/autocomplete.service'; +import { MatFormFieldModule } from '@angular/material/form-field'; import { AutocompleteStoryServiceComponent } from './autocomplete-story-service.component'; +import { AutocompleteStoryServiceService } from './autocomplete-story-service.service'; @NgModule({ declarations: [AutocompleteStoryServiceComponent], imports: [ CommonModule, ReactiveFormsModule, + AutocompleteModule, + MatFormFieldModule, MatButtonModule ], exports: [AutocompleteStoryServiceComponent], - providers: [AutocompleteService] + providers: [AutocompleteStoryServiceService] }) export class AutocompleteStoryServiceModule {} diff --git a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.service.ts similarity index 89% rename from projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts rename to projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.service.ts index 9b931279..0ef6c49f 100644 --- a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete.service.ts +++ b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-service/autocomplete-story-service.service.ts @@ -8,7 +8,7 @@ import { GetFilterOptions } from '../../filter-options'; const OPTIONS = ['Red', 'White', 'Green']; @Injectable() -export class AutocompleteService { +export class AutocompleteStoryServiceService { public getOptions(text?: string): Observable { const options = GetFilterOptions(text, OPTIONS); return of({ diff --git a/projects/elonkit/src/ui/autocomplete/autocomplete.component.html b/projects/elonkit/src/ui/autocomplete/autocomplete.component.html index bbe66945..b076bf30 100644 --- a/projects/elonkit/src/ui/autocomplete/autocomplete.component.html +++ b/projects/elonkit/src/ui/autocomplete/autocomplete.component.html @@ -15,7 +15,7 @@ [displayWith]="displayWith" (optionSelected)="onSuggestionSelect($event.option.value)" > - + {{ option }} @@ -27,7 +27,7 @@ - +
diff --git a/projects/elonkit/src/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/ui/autocomplete/autocomplete.component.ts index b15890b8..e0dd18ec 100644 --- a/projects/elonkit/src/ui/autocomplete/autocomplete.component.ts +++ b/projects/elonkit/src/ui/autocomplete/autocomplete.component.ts @@ -3,14 +3,14 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, ViewEncapsulation, + OnInit, OnDestroy, + Input, + Output, + EventEmitter, HostBinding, Optional, Self, - Input, - EventEmitter, - Output, - OnInit, ViewChild, ContentChild, TemplateRef, @@ -23,12 +23,12 @@ import { NgControl, ControlValueAccessor, FormGroupDirective } from '@angular/fo import { coerceBooleanProperty } from '@angular/cdk/coercion'; import { Subject, timer } from 'rxjs'; -import { debounce } from 'rxjs/operators'; +import { debounce, takeUntil } from 'rxjs/operators'; import { MatFormField, MatFormFieldControl } from '@angular/material/form-field'; import { MatAutocompleteTrigger, MatAutocompleteOrigin } from '@angular/material/autocomplete'; -import { AutocompleteOptionDirective } from '../autocomplete/autocomplete-option.directive'; +import { AutocompleteOptionDirective } from './autocomplete-option.directive'; export const ES_AUTOCOMPLETE_DEFAULT_OPTIONS = new InjectionToken( 'ES_AUTOCOMPLETE_DEFAULT_OPTIONS' @@ -48,7 +48,7 @@ export interface EsAutocompleteDefaultOptions { providers: [{ provide: MatFormFieldControl, useExisting: AutocompleteComponent }] }) export class AutocompleteComponent - implements MatFormFieldControl, ControlValueAccessor, OnDestroy, OnInit { + implements MatFormFieldControl, ControlValueAccessor, OnInit, OnDestroy { /** * @ignore */ @@ -65,20 +65,20 @@ export class AutocompleteComponent public origin: MatAutocompleteOrigin; /** - * Array of options + * Array of options to display. */ @Input() public options: any[]; /** * @ignore */ - @Input() public isLoading = false; + @Input() public loading = false; /** - * Function that maps an option control value to its display value in the trigger + * 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; + @Input() public displayWith = (value?: any): string => { + return value; }; /** @@ -99,10 +99,7 @@ export class AutocompleteComponent return this._debounceTime; } public set debounceTime(value: number) { - this._debounceTime = - value || - (this.autocompleteDefaultOptions && this.autocompleteDefaultOptions.debounceTime) || - 0; + this._debounceTime = value ?? (this.autocompleteDefaultOptions?.debounceTime || 0); } // tslint:disable-next-line variable-name @@ -116,12 +113,7 @@ export class AutocompleteComponent return this._freeInput; } public set freeInput(value: boolean) { - this._freeInput = - value !== undefined - ? value - : this.autocompleteDefaultOptions && this.autocompleteDefaultOptions.freeInput - ? this.autocompleteDefaultOptions.freeInput - : false; + this._freeInput = value ?? (this.autocompleteDefaultOptions?.freeInput || false); } // tslint:disable-next-line variable-name @@ -202,7 +194,7 @@ export class AutocompleteComponent const form = this.ngForm; if (control) { - return control.invalid && (control.touched || (form && form.submitted)); + return control.invalid && (control.touched || form?.submitted); } return false; @@ -223,13 +215,18 @@ export class AutocompleteComponent public optionTemplate: any; private static nextId = 0; + @HostBinding() public id = `es-autocomplete-${AutocompleteComponent.nextId++}`; + @HostBinding('attr.aria-describedby') public describedBy = ''; + @HostBinding('class.floating') public get shouldLabelFloat(): boolean { return this.focused || !!this.text; } + private destroyed$ = new Subject(); + /** * @ignore */ @@ -246,14 +243,8 @@ export class AutocompleteComponent 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.debounceTime = autocompleteDefaultOptions?.debounceTime || 0; + this.freeInput = !!autocompleteDefaultOptions?.freeInput; this.stateChanges.subscribe(() => { this.changeDetector.detectChanges(); @@ -270,17 +261,22 @@ export class AutocompleteComponent }; } - this.text$.pipe(debounce(() => timer(this.debounceTime))).subscribe(text => { - this.changeText.emit(text); - }); + this.text$ + .pipe( + takeUntil(this.destroyed$), + debounce(() => timer(this.debounceTime)) + ) + .subscribe(text => { + this.changeText.emit(text); + }); } /** * @ignore */ public ngOnDestroy() { + this.destroyed$.next(); this.stateChanges.complete(); - this.changeText.complete(); } /** diff --git a/projects/elonkit/src/ui/autocomplete/autocomplete.stories.mdx b/projects/elonkit/src/ui/autocomplete/autocomplete.stories.mdx index 494001b8..c76afc3b 100644 --- a/projects/elonkit/src/ui/autocomplete/autocomplete.stories.mdx +++ b/projects/elonkit/src/ui/autocomplete/autocomplete.stories.mdx @@ -21,10 +21,6 @@ import { AutocompleteStoryCustomModule } from './__stories__/autocomplete-story- import { AutocompleteStoryCustomComponent } from './__stories__/autocomplete-story-custom/autocomplete-story-custom.component'; import { AUTOCOMPLETE_STORY_CUSTOM_SOURCE } from './__stories__/autocomplete-story-custom/autocomplete-story-custom.source'; -import { AutocompleteStoryNgModelModule } from './__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.module'; -import { AutocompleteStoryNgModelComponent } from './__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.component'; -import { AUTOCOMPLETE_STORY_NG_MODEL_SOURCE } from './__stories__/autocomplete-story-ng-model/autocomplete-story-ng-model.source'; - # Autocomplete @@ -76,19 +72,6 @@ This is a story with custom options:
-This is a story with ngModel: - - - - {{ - template: ``, - moduleMetadata: { - imports: [BrowserAnimationsModule, AutocompleteStoryNgModelModule] - } - }} - - - ## API From 24e5ac08f7119aaec38b861418ce1bd10462a704 Mon Sep 17 00:00:00 2001 From: Denis Yakshov Date: Mon, 16 Mar 2020 12:28:32 +0300 Subject: [PATCH 31/31] Fix autocomplete label float --- .../autocomplete-story-custom.module.ts | 13 +-------- .../autocomplete-story-default.component.html | 12 -------- .../ui/autocomplete/autocomplete.component.ts | 29 ++++++++----------- 3 files changed, 13 insertions(+), 41 deletions(-) diff --git a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts index 6250fe43..1c1047f1 100644 --- a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts +++ b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-custom/autocomplete-story-custom.module.ts @@ -4,8 +4,6 @@ import { ReactiveFormsModule } from '@angular/forms'; import { AutocompleteModule } from '../../autocomplete.module'; -import { ES_AUTOCOMPLETE_DEFAULT_OPTIONS } from '../../autocomplete.component'; - import { MatFormFieldModule } from '@angular/material/form-field'; import { MatButtonModule } from '@angular/material/button'; @@ -20,15 +18,6 @@ import { AutocompleteStoryCustomComponent } from './autocomplete-story-custom.co MatFormFieldModule, MatButtonModule ], - exports: [AutocompleteStoryCustomComponent], - providers: [ - { - provide: ES_AUTOCOMPLETE_DEFAULT_OPTIONS, - useValue: { - debounceTime: 1000, - freeInput: true - } - } - ] + exports: [AutocompleteStoryCustomComponent] }) export class AutocompleteStoryCustomModule {} diff --git a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html index 2bc112f8..50064a1c 100644 --- a/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html +++ b/projects/elonkit/src/ui/autocomplete/__stories__/autocomplete-story-default/autocomplete-story-default.component.html @@ -10,16 +10,4 @@ > - -
-
- - - diff --git a/projects/elonkit/src/ui/autocomplete/autocomplete.component.ts b/projects/elonkit/src/ui/autocomplete/autocomplete.component.ts index e0dd18ec..8d314c53 100644 --- a/projects/elonkit/src/ui/autocomplete/autocomplete.component.ts +++ b/projects/elonkit/src/ui/autocomplete/autocomplete.component.ts @@ -88,7 +88,6 @@ export class AutocompleteComponent return option; }; - // tslint:disable-next-line variable-name private _debounceTime: number; /** @@ -102,7 +101,6 @@ export class AutocompleteComponent this._debounceTime = value ?? (this.autocompleteDefaultOptions?.debounceTime || 0); } - // tslint:disable-next-line variable-name private _freeInput: boolean; /** @@ -116,7 +114,6 @@ export class AutocompleteComponent this._freeInput = value ?? (this.autocompleteDefaultOptions?.freeInput || false); } - // tslint:disable-next-line variable-name private _value = ''; public get value(): any { @@ -128,14 +125,13 @@ export class AutocompleteComponent this.stateChanges.next(); } - // tslint:disable-next-line variable-name private _focused = false; public get focused() { return this._focused; } - public set focused(focused: boolean) { - this._focused = focused; + public set focused(value: boolean) { + this._focused = value; this.stateChanges.next(); } @@ -143,7 +139,6 @@ export class AutocompleteComponent return !this.value; } - // tslint:disable-next-line variable-name private _required = false; /** @@ -153,12 +148,11 @@ export class AutocompleteComponent public get required() { return this._required; } - public set required(req) { - this._required = coerceBooleanProperty(req); + public set required(value) { + this._required = coerceBooleanProperty(value); this.stateChanges.next(); } - // tslint:disable-next-line variable-name private _disabled = false; /** @@ -168,12 +162,11 @@ export class AutocompleteComponent public get disabled(): boolean { return this._disabled; } - public set disabled(dis: boolean) { - this._disabled = coerceBooleanProperty(dis); + public set disabled(value: boolean) { + this._disabled = coerceBooleanProperty(value); this.stateChanges.next(); } - // tslint:disable-next-line variable-name private _placeholder = ''; /** @@ -184,8 +177,8 @@ export class AutocompleteComponent return this._placeholder; } - public set placeholder(plh) { - this._placeholder = plh; + public set placeholder(value: string) { + this._placeholder = value; this.stateChanges.next(); } @@ -311,7 +304,7 @@ export class AutocompleteComponent public writeValue(value: any) { if (value !== undefined) { this.value = value; - this.text = this.value; + this.text = this.displayWith(this.value); this.stateChanges.next(); } } @@ -367,7 +360,7 @@ export class AutocompleteComponent this.focused = false; if (!this.freeInput) { - this.text = this.value; + this.text = this.displayWith(this.value); } // this.changeText.emit(this.text); @@ -380,6 +373,8 @@ export class AutocompleteComponent public onSuggestionSelect(event: Event) { this.value = event; this.onChange(this.value); + this.text = this.displayWith(this.value); + this.stateChanges.next(); } }