#833 Fix Backspace Behaviour in Searchbar

This commit is contained in:
Sebastian
2020-07-13 17:42:28 +02:00
parent 72bebedd70
commit 31a4774ba0
2 changed files with 113 additions and 1 deletions

View File

@@ -0,0 +1,96 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AutocompleteResultsComponent } from './autocomplete-results.component';
import { ResultItemComponent } from './result-item';
import { ActiveDescendantKeyManager, Highlightable } from '@angular/cdk/a11y';
import { QueryList } from '@angular/core';
fdescribe('#AutocompleteResultsComponent', () => {
let fixture: ComponentFixture<AutocompleteResultsComponent>;
let component: AutocompleteResultsComponent;
let items: QueryList<Highlightable & ResultItemComponent>;
beforeEach(async () => {
TestBed.configureTestingModule({
declarations: [AutocompleteResultsComponent, ResultItemComponent],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(AutocompleteResultsComponent);
component = fixture.componentInstance;
items = new QueryList();
component['keyManager'] = new ActiveDescendantKeyManager<
ResultItemComponent
>(items).withWrap();
spyOn(component, 'ngAfterViewInit').and.callFake(() => {});
component.results = [];
fixture.detectChanges();
});
it('should be created', () => {
expect(component instanceof AutocompleteResultsComponent).toBeTruthy();
});
describe('Deselect Items on keypress', () => {
let activeItemMock: Highlightable & ResultItemComponent;
beforeEach(() => {
activeItemMock = ({
result: 'Test Result',
} as unknown) as Highlightable & ResultItemComponent;
spyOn(component, 'onKeyDown').and.callThrough();
spyOn(component.selectItem, 'emit').and.callFake(() => {});
spyOnProperty(component['keyManager'], 'activeItem').and.returnValue(
activeItemMock
);
spyOn(component['keyManager'], 'setActiveItem').and.callFake(() => {});
});
it('should deselect the current active item if a letter is typed', () => {
const event = new KeyboardEvent('keyup', { key: 'a' });
window.dispatchEvent(event);
fixture.detectChanges();
expect(component.onKeyDown).toHaveBeenCalled();
expect(component['keyManager'].setActiveItem).toHaveBeenCalledWith(null);
});
it('should deselect the current active item if backspace is typed', () => {
const event = new KeyboardEvent('keyup', { key: 'Backspace' });
window.dispatchEvent(event);
fixture.detectChanges();
expect(component.onKeyDown).toHaveBeenCalled();
expect(component['keyManager'].setActiveItem).toHaveBeenCalledWith(null);
});
it('should not deselect if ArrowUp is pressed', () => {
const event = new KeyboardEvent('keyup', { key: 'ArrowUp' });
window.dispatchEvent(event);
fixture.detectChanges();
expect(component.onKeyDown).toHaveBeenCalled();
expect(component['keyManager'].setActiveItem).not.toHaveBeenCalledWith(
null
);
expect(component.selectItem.emit).toHaveBeenCalledWith(
activeItemMock.result
);
});
it('should not deselect if ArrowDown is pressed', () => {
const event = new KeyboardEvent('keyup', { key: 'ArrowDown' });
window.dispatchEvent(event);
fixture.detectChanges();
expect(component.onKeyDown).toHaveBeenCalled();
expect(component['keyManager'].setActiveItem).not.toHaveBeenCalledWith(
null
);
expect(component.selectItem.emit).toHaveBeenCalledWith(
activeItemMock.result
);
});
});
});

View File

@@ -33,12 +33,16 @@ export class AutocompleteResultsComponent implements AfterViewInit {
constructor() {}
@HostListener('window:keyup', ['$event']) onKeyDown(event: KeyboardEvent) {
if (event.key === 'ArrowDown' || 'ArrowUp') {
if (this.isUpOrDownKey(event.key)) {
this.keyManager.onKeydown(event);
if (this.keyManager.activeItem) {
this.selectItem.emit(this.keyManager.activeItem.result);
}
}
if (this.shouldDeselectItem(event.key)) {
this.keyManager.setActiveItem(null);
}
}
ngAfterViewInit() {
@@ -57,4 +61,16 @@ export class AutocompleteResultsComponent implements AfterViewInit {
private getItemIndex(item: AutocompleteDTO): number {
return this.results.indexOf(item);
}
private shouldDeselectItem(key: string): boolean {
const isBackspace = key === 'Backspace';
const isLetter = key.length === 1 && /^[a-zA-Z]+$/.test(key);
const isNumber = key.length === 1 && /^[0-9]+$/.test(key);
return isBackspace || isLetter || isNumber;
}
private isUpOrDownKey(key: string): boolean {
return key === 'ArrowDown' || key === 'ArrowUp';
}
}