diff --git a/components/auto-complete/nz-autocomplete-optgroup.component.ts b/components/auto-complete/autocomplete-optgroup.component.ts
similarity index 74%
rename from components/auto-complete/nz-autocomplete-optgroup.component.ts
rename to components/auto-complete/autocomplete-optgroup.component.ts
index 6cd26ee8ad0..d9c67ac95cd 100644
--- a/components/auto-complete/nz-autocomplete-optgroup.component.ts
+++ b/components/auto-complete/autocomplete-optgroup.component.ts
@@ -14,11 +14,12 @@ import { ChangeDetectionStrategy, Component, Input, TemplateRef, ViewEncapsulati
preserveWhitespaces: false,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
- templateUrl: './nz-autocomplete-optgroup.component.html',
- host: {
- role: 'group',
- class: 'ant-select-dropdown-menu-item-group'
- }
+ template: `
+
+ {{ nzLabel }}
+
+
+ `
})
export class NzAutocompleteOptgroupComponent {
@Input() nzLabel: string | TemplateRef;
diff --git a/components/auto-complete/nz-autocomplete-option.component.ts b/components/auto-complete/autocomplete-option.component.ts
similarity index 74%
rename from components/auto-complete/nz-autocomplete-option.component.ts
rename to components/auto-complete/autocomplete-option.component.ts
index 2b3757739e6..7e52e70878c 100644
--- a/components/auto-complete/nz-autocomplete-option.component.ts
+++ b/components/auto-complete/autocomplete-option.component.ts
@@ -13,12 +13,15 @@ import {
ElementRef,
EventEmitter,
Input,
+ Optional,
Output,
ViewEncapsulation
} from '@angular/core';
import { InputBoolean, scrollIntoView } from 'ng-zorro-antd/core';
+import { NzAutocompleteOptgroupComponent } from './autocomplete-optgroup.component';
+
export class NzOptionSelectionChange {
constructor(public source: NzAutocompleteOptionComponent, public isUserInput: boolean = false) {}
}
@@ -29,16 +32,22 @@ export class NzOptionSelectionChange {
preserveWhitespaces: false,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
- templateUrl: './nz-autocomplete-option.component.html',
+ template: `
+
+
+
+ `,
host: {
role: 'menuitem',
- class: 'ant-select-dropdown-menu-item',
- '[class.ant-select-dropdown-menu-item-selected]': 'selected',
- '[class.ant-select-dropdown-menu-item-active]': 'active',
- '[class.ant-select-dropdown-menu-item-disabled]': 'nzDisabled',
+ class: 'ant-select-item ant-select-item-option',
+ '[class.ant-select-item-option-grouped]': 'nzAutocompleteOptgroupComponent',
+ '[class.ant-select-item-option-selected]': 'selected',
+ '[class.ant-select-item-option-active]': 'active',
+ '[class.ant-select-item-option-disabled]': 'nzDisabled',
'[attr.aria-selected]': 'selected.toString()',
'[attr.aria-disabled]': 'nzDisabled.toString()',
'(click)': 'selectViaInteraction()',
+ '(mouseenter)': 'onMouseEnter()',
'(mousedown)': '$event.preventDefault()'
}
})
@@ -48,11 +57,17 @@ export class NzAutocompleteOptionComponent {
@Input() nzLabel: string;
@Input() @InputBoolean() nzDisabled = false;
@Output() readonly selectionChange = new EventEmitter();
+ @Output() readonly mouseEntered = new EventEmitter();
active = false;
selected = false;
- constructor(private changeDetectorRef: ChangeDetectorRef, private element: ElementRef) {}
+ constructor(
+ private changeDetectorRef: ChangeDetectorRef,
+ private element: ElementRef,
+ @Optional()
+ public nzAutocompleteOptgroupComponent: NzAutocompleteOptgroupComponent
+ ) {}
select(emit: boolean = true): void {
this.selected = true;
@@ -62,6 +77,10 @@ export class NzAutocompleteOptionComponent {
}
}
+ onMouseEnter(): void {
+ this.mouseEntered.emit(this);
+ }
+
deselect(): void {
this.selected = false;
this.changeDetectorRef.markForCheck();
diff --git a/components/auto-complete/nz-autocomplete-trigger.directive.ts b/components/auto-complete/autocomplete-trigger.directive.ts
similarity index 98%
rename from components/auto-complete/nz-autocomplete-trigger.directive.ts
rename to components/auto-complete/autocomplete-trigger.directive.ts
index 8f24f2758b0..1f70fc26379 100644
--- a/components/auto-complete/nz-autocomplete-trigger.directive.ts
+++ b/components/auto-complete/autocomplete-trigger.directive.ts
@@ -36,8 +36,8 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { fromEvent, merge, Subscription } from 'rxjs';
import { delay, distinct, map, take, tap } from 'rxjs/operators';
-import { NzAutocompleteOptionComponent } from './nz-autocomplete-option.component';
-import { NzAutocompleteComponent } from './nz-autocomplete.component';
+import { NzAutocompleteOptionComponent } from './autocomplete-option.component';
+import { NzAutocompleteComponent } from './autocomplete.component';
export const NZ_AUTOCOMPLETE_VALUE_ACCESSOR: ExistingProvider = {
provide: NG_VALUE_ACCESSOR,
diff --git a/components/auto-complete/nz-autocomplete.component.ts b/components/auto-complete/autocomplete.component.ts
similarity index 74%
rename from components/auto-complete/nz-autocomplete.component.ts
rename to components/auto-complete/autocomplete.component.ts
index 20b0cc06f50..f9bdeb56b0b 100644
--- a/components/auto-complete/nz-autocomplete.component.ts
+++ b/components/auto-complete/autocomplete.component.ts
@@ -32,7 +32,7 @@ import { filter, switchMap, take } from 'rxjs/operators';
import { CompareWith, InputBoolean, NzDropDownPosition, NzNoAnimationDirective, slideMotion } from 'ng-zorro-antd/core';
-import { NzAutocompleteOptionComponent, NzOptionSelectionChange } from './nz-autocomplete-option.component';
+import { NzAutocompleteOptionComponent, NzOptionSelectionChange } from './autocomplete-option.component';
export interface AutocompleteDataSourceItem {
value: string;
@@ -47,17 +47,37 @@ export type AutocompleteDataSource = AutocompleteDataSourceItem[] | string[] | n
preserveWhitespaces: false,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
- templateUrl: './nz-autocomplete.component.html',
+ template: `
+
+
+
+
+
+
+ {{ option }}
+
+
+ `,
animations: [slideMotion],
styles: [
`
- .ant-select-dropdown {
- top: 100%;
- left: 0;
- position: relative;
- width: 100%;
- margin-top: 4px;
- margin-bottom: 4px;
+ .ant-select-dropdown-hidden {
+ display: none;
}
`
]
@@ -70,7 +90,8 @@ export class NzAutocompleteComponent implements AfterContentInit, AfterViewInit,
@Input() @InputBoolean() nzBackfill = false;
@Input() compareWith: CompareWith = (o1, o2) => o1 === o2;
@Input() nzDataSource: AutocompleteDataSource;
- @Output() readonly selectionChange: EventEmitter = new EventEmitter();
+ @Output()
+ readonly selectionChange: EventEmitter = new EventEmitter();
showPanel: boolean = true;
isOpen: boolean = false;
@@ -90,7 +111,8 @@ export class NzAutocompleteComponent implements AfterContentInit, AfterViewInit,
}
/** Provided by content */
- @ContentChildren(NzAutocompleteOptionComponent, { descendants: true }) fromContentOptions: QueryList;
+ @ContentChildren(NzAutocompleteOptionComponent, { descendants: true })
+ fromContentOptions: QueryList;
/** Provided by dataSource */
@ViewChildren(NzAutocompleteOptionComponent) fromDataSourceOptions: QueryList;
@@ -101,6 +123,7 @@ export class NzAutocompleteComponent implements AfterContentInit, AfterViewInit,
private activeItemIndex: number = -1;
private selectionChangeSubscription = Subscription.EMPTY;
+ private optionMouseEnterSubscription = Subscription.EMPTY;
private dataSourceChangeSubscription = Subscription.EMPTY;
/** Options changes listener */
readonly optionSelectionChanges: Observable = defer(() => {
@@ -112,6 +135,15 @@ export class NzAutocompleteComponent implements AfterContentInit, AfterViewInit,
switchMap(() => this.optionSelectionChanges)
);
});
+ readonly optionMouseEnter: Observable = defer(() => {
+ if (this.options) {
+ return merge(...this.options.map(option => option.mouseEntered));
+ }
+ return this.ngZone.onStable.asObservable().pipe(
+ take(1),
+ switchMap(() => this.optionMouseEnter)
+ );
+ });
constructor(
private changeDetectorRef: ChangeDetectorRef,
@@ -134,6 +166,7 @@ export class NzAutocompleteComponent implements AfterContentInit, AfterViewInit,
ngOnDestroy(): void {
this.dataSourceChangeSubscription.unsubscribe();
this.selectionChangeSubscription.unsubscribe();
+ this.optionMouseEnterSubscription.unsubscribe();
}
setVisibility(): void {
@@ -213,5 +246,13 @@ export class NzAutocompleteComponent implements AfterContentInit, AfterViewInit,
this.clearSelectedOptions(event.source, true);
this.selectionChange.emit(event.source);
});
+
+ this.optionMouseEnterSubscription.unsubscribe();
+ this.optionMouseEnterSubscription = this.optionMouseEnter.subscribe((event: NzAutocompleteOptionComponent) => {
+ event.setActiveStyles();
+ this.activeItem = event;
+ this.activeItemIndex = this.getOptionIndex(this.activeItem.nzValue);
+ this.clearSelectedOptions(event);
+ });
}
}
diff --git a/components/auto-complete/nz-autocomplete.module.ts b/components/auto-complete/autocomplete.module.ts
similarity index 73%
rename from components/auto-complete/nz-autocomplete.module.ts
rename to components/auto-complete/autocomplete.module.ts
index 1ce4fc5fda5..ed43be311cb 100644
--- a/components/auto-complete/nz-autocomplete.module.ts
+++ b/components/auto-complete/autocomplete.module.ts
@@ -13,10 +13,10 @@ import { FormsModule } from '@angular/forms';
import { NzNoAnimationModule, NzOutletModule } from 'ng-zorro-antd/core';
-import { NzAutocompleteOptgroupComponent } from './nz-autocomplete-optgroup.component';
-import { NzAutocompleteOptionComponent } from './nz-autocomplete-option.component';
-import { NzAutocompleteTriggerDirective } from './nz-autocomplete-trigger.directive';
-import { NzAutocompleteComponent } from './nz-autocomplete.component';
+import { NzAutocompleteOptgroupComponent } from './autocomplete-optgroup.component';
+import { NzAutocompleteOptionComponent } from './autocomplete-option.component';
+import { NzAutocompleteTriggerDirective } from './autocomplete-trigger.directive';
+import { NzAutocompleteComponent } from './autocomplete.component';
@NgModule({
declarations: [NzAutocompleteComponent, NzAutocompleteOptionComponent, NzAutocompleteTriggerDirective, NzAutocompleteOptgroupComponent],
diff --git a/components/auto-complete/nz-autocomplete.spec.ts b/components/auto-complete/autocomplete.spec.ts
similarity index 94%
rename from components/auto-complete/nz-autocomplete.spec.ts
rename to components/auto-complete/autocomplete.spec.ts
index 4b55fd52e5c..d167ad1b28d 100644
--- a/components/auto-complete/nz-autocomplete.spec.ts
+++ b/components/auto-complete/autocomplete.spec.ts
@@ -11,8 +11,8 @@ import { Subject } from 'rxjs';
import { createKeyboardEvent, dispatchFakeEvent, dispatchKeyboardEvent, MockNgZone, typeInElement } from 'ng-zorro-antd/core';
+import { getNzAutocompleteMissingPanelError } from './autocomplete-trigger.directive';
import { NzAutocompleteComponent, NzAutocompleteModule, NzAutocompleteOptionComponent, NzAutocompleteTriggerDirective } from './index';
-import { getNzAutocompleteMissingPanelError } from './nz-autocomplete-trigger.directive';
describe('auto-complete', () => {
let overlayContainer: OverlayContainer;
@@ -102,11 +102,10 @@ describe('auto-complete', () => {
input.disabled = true;
fixture.detectChanges();
- expect(trigger.panelOpen).toBe(false);
dispatchFakeEvent(input, 'focusin');
flush();
-
fixture.detectChanges();
+
expect(trigger.panelOpen).toBe(false);
}));
@@ -243,16 +242,6 @@ describe('auto-complete', () => {
TAB_EVENT = createKeyboardEvent('keydown', TAB);
});
- it('should open the panel when the input is focused', () => {
- expect(fixture.componentInstance.trigger.panelOpen).toBe(false);
-
- dispatchFakeEvent(input, 'focusin');
- fixture.detectChanges();
-
- expect(fixture.componentInstance.trigger.panelOpen).toBe(true);
- expect(overlayContainerElement.textContent).toContain('Burns Bay Road');
- });
-
it('should have correct width when setting', () => {
fixture.componentInstance.width = 500;
fixture.detectChanges();
@@ -603,8 +592,8 @@ describe('auto-complete', () => {
componentInstance.trigger.handleKeydown(DOWN_ARROW_EVENT);
fixture.detectChanges();
- expect(optionEls[0].classList).not.toContain('ant-select-dropdown-menu-item-active');
- expect(optionEls[1].classList).toContain('ant-select-dropdown-menu-item-active');
+ expect(optionEls[0].classList).not.toContain('ant-select-item-option-active');
+ expect(optionEls[1].classList).toContain('ant-select-item-option-active');
});
it('should set the active item to the first option when DOWN key is pressed in last item', () => {
@@ -616,8 +605,33 @@ describe('auto-complete', () => {
[1, 2, 3].forEach(() => componentInstance.trigger.handleKeydown(DOWN_ARROW_EVENT));
fixture.detectChanges();
- expect(optionEls[1].classList).not.toContain('ant-select-dropdown-menu-item-active');
- expect(optionEls[0].classList).toContain('ant-select-dropdown-menu-item-active');
+ expect(optionEls[1].classList).not.toContain('ant-select-item-option-active');
+ expect(optionEls[0].classList).toContain('ant-select-item-option-active');
+ });
+
+ it('should set the active item when mouse is enter', () => {
+ const componentInstance = fixture.componentInstance;
+ const optionEls = overlayContainerElement.querySelectorAll('nz-auto-option') as NodeListOf;
+
+ expect(componentInstance.trigger.panelOpen).toBe(true);
+
+ fixture.detectChanges();
+
+ dispatchFakeEvent(optionEls[1], 'mouseenter');
+
+ fixture.detectChanges();
+
+ expect(optionEls[0].classList).not.toContain('ant-select-item-option-active');
+ expect(optionEls[1].classList).toContain('ant-select-item-option-active');
+ expect(optionEls[2].classList).not.toContain('ant-select-item-option-active');
+
+ dispatchFakeEvent(optionEls[0], 'mouseenter');
+
+ fixture.detectChanges();
+
+ expect(optionEls[0].classList).toContain('ant-select-item-option-active');
+ expect(optionEls[1].classList).not.toContain('ant-select-item-option-active');
+ expect(optionEls[2].classList).not.toContain('ant-select-item-option-active');
});
it('should set the active item to the last option when UP key is pressed', () => {
@@ -629,9 +643,9 @@ describe('auto-complete', () => {
componentInstance.trigger.handleKeydown(UP_ARROW_EVENT);
fixture.detectChanges();
- expect(optionEls[0].classList).not.toContain('ant-select-dropdown-menu-item-active');
- expect(optionEls[1].classList).not.toContain('ant-select-dropdown-menu-item-active');
- expect(optionEls[2].classList).toContain('ant-select-dropdown-menu-item-active');
+ expect(optionEls[0].classList).not.toContain('ant-select-item-option-active');
+ expect(optionEls[1].classList).not.toContain('ant-select-item-option-active');
+ expect(optionEls[2].classList).toContain('ant-select-item-option-active');
});
it('should set the active item to the previous option when UP key is pressed', () => {
@@ -643,9 +657,9 @@ describe('auto-complete', () => {
[1, 2].forEach(() => componentInstance.trigger.handleKeydown(UP_ARROW_EVENT));
fixture.detectChanges();
- expect(optionEls[0].classList).not.toContain('ant-select-dropdown-menu-item-active');
- expect(optionEls[1].classList).toContain('ant-select-dropdown-menu-item-active');
- expect(optionEls[2].classList).not.toContain('ant-select-dropdown-menu-item-active');
+ expect(optionEls[0].classList).not.toContain('ant-select-item-option-active');
+ expect(optionEls[1].classList).toContain('ant-select-item-option-active');
+ expect(optionEls[2].classList).not.toContain('ant-select-item-option-active');
});
it('should set the active item properly after filtering', () => {
@@ -659,8 +673,8 @@ describe('auto-complete', () => {
const optionEls = overlayContainerElement.querySelectorAll('nz-auto-option') as NodeListOf;
- expect(optionEls[0].classList).not.toContain('ant-select-dropdown-menu-item-active');
- expect(optionEls[1].classList).toContain('ant-select-dropdown-menu-item-active');
+ expect(optionEls[0].classList).not.toContain('ant-select-item-option-active');
+ expect(optionEls[1].classList).toContain('ant-select-item-option-active');
expect(optionEls[1].innerText).toEqual('Wall Street');
});
diff --git a/components/auto-complete/nz-autocomplete-optgroup.component.html b/components/auto-complete/nz-autocomplete-optgroup.component.html
deleted file mode 100644
index 01eaa19fa75..00000000000
--- a/components/auto-complete/nz-autocomplete-optgroup.component.html
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
diff --git a/components/auto-complete/nz-autocomplete-option.component.html b/components/auto-complete/nz-autocomplete-option.component.html
deleted file mode 100644
index 6dbc7430638..00000000000
--- a/components/auto-complete/nz-autocomplete-option.component.html
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/components/auto-complete/nz-autocomplete.component.html b/components/auto-complete/nz-autocomplete.component.html
deleted file mode 100644
index bb1098b9347..00000000000
--- a/components/auto-complete/nz-autocomplete.component.html
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
- {{
- option
- }}
-
-
diff --git a/components/auto-complete/public-api.ts b/components/auto-complete/public-api.ts
index dcf7b1f5e65..fca0f6ee830 100644
--- a/components/auto-complete/public-api.ts
+++ b/components/auto-complete/public-api.ts
@@ -6,8 +6,8 @@
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
-export * from './nz-autocomplete.module';
-export * from './nz-autocomplete.component';
-export * from './nz-autocomplete-trigger.directive';
-export * from './nz-autocomplete-option.component';
-export * from './nz-autocomplete-optgroup.component';
+export * from './autocomplete.module';
+export * from './autocomplete.component';
+export * from './autocomplete-trigger.directive';
+export * from './autocomplete-option.component';
+export * from './autocomplete-optgroup.component';