diff --git a/src/modules/autocomplete/autocomplete-input.directive.ts b/src/modules/autocomplete/autocomplete-input.directive.ts index 746bdf48e..6da9fbb6b 100644 --- a/src/modules/autocomplete/autocomplete-input.directive.ts +++ b/src/modules/autocomplete/autocomplete-input.directive.ts @@ -67,7 +67,7 @@ export class SkyAutocompleteInputDirective private _value: any; constructor( - private elementRef: ElementRef, + public elementRef: ElementRef, private renderer: Renderer2 ) { } diff --git a/src/modules/autocomplete/autocomplete.component.html b/src/modules/autocomplete/autocomplete.component.html index eff14471c..1d2d66768 100644 --- a/src/modules/autocomplete/autocomplete.component.html +++ b/src/modules/autocomplete/autocomplete.component.html @@ -2,18 +2,18 @@
- - - - - - + [@.disabled]="true" + #popover> + (menuChanges)="onMenuChanges($event)" + #dropdownMenu> @@ -27,7 +27,7 @@ - +
{ fixture.detectChanges(); const inputElement = getInputElement(); - const messageSpy = spyOn(autocomplete as any, 'sendDropdownMessage') + const messageSpy = spyOn(autocomplete as any, 'sendMessage') .and.callThrough(); inputElement.value = 'r'; @@ -207,20 +207,22 @@ describe('Autocomplete component', () => { fixture.detectChanges(); const inputElement = getInputElement(); - const messageSpy = spyOn(autocomplete as any, 'sendDropdownMessage') + const messageSpy = spyOn(autocomplete as any, 'sendMessage') .and.callThrough(); inputElement.value = 'r'; SkyAppTestUtility.fireDomEvent(inputElement, 'keyup'); tick(); + fixture.detectChanges(); + inputElement.value = 're'; SkyAppTestUtility.fireDomEvent(inputElement, 'keyup'); tick(); expect(messageSpy) .toHaveBeenCalledWith(SkyDropdownMessageType.Open); - expect(messageSpy.calls.count()).toEqual(1); + expect(messageSpy.calls.count()).toEqual(2); }) ); @@ -395,7 +397,7 @@ describe('Autocomplete component', () => { }); tick(); - const messageSpy = spyOn(autocomplete as any, 'sendDropdownMessage') + const messageSpy = spyOn(autocomplete as any, 'sendMessage') .and.callThrough(); const notifySpy = spyOn(autocomplete.selectionChange, 'emit') .and.callThrough(); @@ -422,7 +424,7 @@ describe('Autocomplete component', () => { SkyAppTestUtility.fireDomEvent(inputElement, 'keyup'); tick(); - const messageSpy = spyOn(autocomplete as any, 'sendDropdownMessage') + const messageSpy = spyOn(autocomplete as any, 'sendMessage') .and.callThrough(); const notifySpy = spyOn(autocomplete.selectionChange, 'emit') .and.callThrough(); @@ -448,7 +450,7 @@ describe('Autocomplete component', () => { tick(); fixture.detectChanges(); - const spy = spyOn(autocomplete as any, 'sendDropdownMessage') + const spy = spyOn(autocomplete as any, 'sendMessage') .and.callThrough(); const autocompleteElement = getAutocompleteElement(); const dropdownElement = autocompleteElement @@ -506,7 +508,7 @@ describe('Autocomplete component', () => { SkyAppTestUtility.fireDomEvent(inputElement, 'keyup'); tick(); - const spy = spyOn(autocomplete as any, 'sendDropdownMessage').and.callThrough(); + const spy = spyOn(autocomplete as any, 'sendMessage').and.callThrough(); const autocompleteElement = getAutocompleteElement(); SkyAppTestUtility.fireDomEvent(autocompleteElement, 'keydown', { @@ -603,7 +605,7 @@ describe('Autocomplete component', () => { tick(); fixture.detectChanges(); - const messageSpy = spyOn(autocomplete as any, 'sendDropdownMessage') + const messageSpy = spyOn(autocomplete as any, 'sendMessage') .and.callThrough(); const notifySpy = spyOn(autocomplete.selectionChange, 'emit') .and.callThrough(); @@ -632,7 +634,7 @@ describe('Autocomplete component', () => { fixture.detectChanges(); tick(); - const spy = spyOn(autocomplete as any, 'sendDropdownMessage').and.callThrough(); + const spy = spyOn(autocomplete as any, 'sendMessage').and.callThrough(); SkyAppTestUtility.fireDomEvent(inputElement, 'mouseenter'); tick(); diff --git a/src/modules/autocomplete/autocomplete.component.ts b/src/modules/autocomplete/autocomplete.component.ts index 95f237ba9..bf4f666c8 100644 --- a/src/modules/autocomplete/autocomplete.component.ts +++ b/src/modules/autocomplete/autocomplete.component.ts @@ -21,7 +21,8 @@ import 'rxjs/add/observable/fromEvent'; import { SkyDropdownMenuChange, SkyDropdownMessageType, - SkyDropdownMessage + SkyDropdownMessage, + SkyDropdownMenuComponent } from '../dropdown'; import { @@ -34,6 +35,7 @@ import { import { SkyAutocompleteAdapterService } from './autocomplete-adapter.service'; import { SkyAutocompleteInputDirective } from './autocomplete-input.directive'; import { skyAutocompleteDefaultSearchFunction } from './autocomplete-default-search-function'; +import { SkyPopoverComponent, SkyPopoverAlignment } from '../popover'; @Component({ selector: 'sky-autocomplete', @@ -115,8 +117,8 @@ export class SkyAutocompleteComponent return this._selectionChange; } - public get dropdownController(): Subject { - return this._dropdownController; + public get messageStream(): Subject { + return this._messageStream; } public get searchResults(): any[] { @@ -127,9 +129,17 @@ export class SkyAutocompleteComponent return this._highlightText || ''; } + public alignment: SkyPopoverAlignment = 'left'; + @ViewChild('defaultSearchResultTemplate') private defaultSearchResultTemplate: TemplateRef; + @ViewChild(SkyPopoverComponent) + private popover: SkyPopoverComponent; + + @ViewChild('dropdownMenu') + private dropdownMenu: SkyDropdownMenuComponent; + @ContentChild(SkyAutocompleteInputDirective) private inputDirective: SkyAutocompleteInputDirective; @@ -140,7 +150,7 @@ export class SkyAutocompleteComponent private _data: any[]; private _descriptorProperty: string; - private _dropdownController = new Subject(); + private _messageStream = new Subject(); private _highlightText: string; private _propertiesToSearch: string[]; private _search: SkyAutocompleteSearchFunction; @@ -178,6 +188,12 @@ export class SkyAutocompleteComponent .subscribe(() => { this.isMouseEnter = false; }); + + this.messageStream + .takeUntil(this.ngUnsubscribe) + .subscribe((message: SkyDropdownMessage) => { + this.handleIncomingMessages(message); + }); } public ngAfterContentInit(): void { @@ -224,17 +240,21 @@ export class SkyAutocompleteComponent } if (change.items) { - this.sendDropdownMessage(SkyDropdownMessageType.FocusFirstItem); + this.sendMessage(SkyDropdownMessageType.FocusFirstItem); } } + public onPopoverOpened() { + this.sendMessage(SkyDropdownMessageType.Open); + } + private handleKeyDown(event: KeyboardEvent): void { const key = event.key.toLowerCase(); /* tslint:disable-next-line:switch-default */ switch (key) { case 'arrowup': - this.sendDropdownMessage(SkyDropdownMessageType.FocusPreviousItem); + this.sendMessage(SkyDropdownMessageType.FocusPreviousItem); event.preventDefault(); break; @@ -246,7 +266,7 @@ export class SkyAutocompleteComponent this.searchTextChanged(text); event.preventDefault(); } else { - this.sendDropdownMessage(SkyDropdownMessageType.FocusNextItem); + this.sendMessage(SkyDropdownMessageType.FocusNextItem); event.preventDefault(); } break; @@ -285,7 +305,7 @@ export class SkyAutocompleteComponent if (isLongEnough && isDifferent) { this.performSearch().then((results: any[]) => { if (!this.hasSearchResults()) { - this.sendDropdownMessage(SkyDropdownMessageType.Open); + this.positionPopover(); } this._searchResults = results; @@ -317,15 +337,48 @@ export class SkyAutocompleteComponent this.closeDropdown(); } + private handleIncomingMessages(message: SkyDropdownMessage) { + /* tslint:disable-next-line:switch-default */ + switch (message.type) { + case SkyDropdownMessageType.Open: + this.dropdownMenu.focusFirstItem(); + break; + + case SkyDropdownMessageType.FocusNextItem: + this.dropdownMenu.focusNextItem(); + break; + + case SkyDropdownMessageType.FocusPreviousItem: + this.dropdownMenu.focusPreviousItem(); + break; + + case SkyDropdownMessageType.Close: + this.popover.close(); + break; + + case SkyDropdownMessageType.FocusTriggerButton: + this.inputDirective.elementRef.nativeElement.focus(); + break; + } + } + + private positionPopover() { + this.popover.positionNextTo( + this.elementRef, + 'below', + this.alignment + ); + } + private closeDropdown(): void { this._searchResults = []; this._highlightText = ''; this.changeDetector.markForCheck(); - this.sendDropdownMessage(SkyDropdownMessageType.Close); + this.sendMessage(SkyDropdownMessageType.Close); } - private sendDropdownMessage(type: SkyDropdownMessageType): void { - this.dropdownController.next({ type }); + private sendMessage(type: SkyDropdownMessageType): void { + this.messageStream.next({ type }); } private hasSearchResults(): boolean { diff --git a/src/modules/autocomplete/autocomplete.module.ts b/src/modules/autocomplete/autocomplete.module.ts index 15b2682c7..6c5c9ded2 100644 --- a/src/modules/autocomplete/autocomplete.module.ts +++ b/src/modules/autocomplete/autocomplete.module.ts @@ -7,6 +7,7 @@ import { SkyTextHighlightModule } from '../text-highlight'; import { SkyAutocompleteComponent } from './autocomplete.component'; import { SkyAutocompleteInputDirective } from './autocomplete-input.directive'; +import { SkyPopoverModule } from '../popover'; @NgModule({ declarations: [ @@ -17,7 +18,8 @@ import { SkyAutocompleteInputDirective } from './autocomplete-input.directive'; CommonModule, FormsModule, SkyTextHighlightModule, - SkyDropdownModule + SkyDropdownModule, + SkyPopoverModule ], exports: [ SkyAutocompleteComponent, diff --git a/src/modules/colorpicker/colorpicker.component.html b/src/modules/colorpicker/colorpicker.component.html index e6a545e51..eb1394c62 100644 --- a/src/modules/colorpicker/colorpicker.component.html +++ b/src/modules/colorpicker/colorpicker.component.html @@ -1,9 +1,7 @@ -
- - -
@@ -172,7 +170,190 @@
- + --> + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + +
+
+ + + + + +
+
+ +
+ +
+
+ + +
+