Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions packages/components/tree-select/tree-select.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
KbqPseudoCheckbox,
KbqPseudoCheckboxModule,
KbqPseudoCheckboxState,
LEFT_ARROW,
RIGHT_ARROW,
SPACE,
ShowOnControlDirtyErrorStateMatcher,
Expand Down Expand Up @@ -3124,6 +3125,84 @@ describe('KbqTreeSelect', () => {
expect(document.activeElement).toBe(searchInput);
}));

it('should keep the caret in the search field when LEFT_ARROW moves to the parent option', fakeAsync(() => {
trigger.click();
fixture.detectChanges();
flush();

const searchInput: HTMLElement = overlayContainerElement.querySelector('.search-input')!;
const inputElementDebug = fixture.debugElement.query(By.css('.search-input'));

inputElementDebug.nativeElement.value = 'core';
inputElementDebug.triggerEventHandler('input', { target: inputElementDebug.nativeElement });
tick();
fixture.detectChanges();
flush();

const select = fixture.componentInstance.select();
const tree = select.tree()!;

const pressPanelKey = (keyCode: number) => {
select.panelKeydownHandler(createKeyboardEvent('keydown', keyCode));
fixture.detectChanges();
flush();
};

// the filter keeps the ancestors of the match: Documents > angular > src > core
expect(
fixture.debugElement
.queryAll(By.css('kbq-tree-option'))
.map((el) => el.nativeElement.textContent.trim())
).toEqual(['Documents', 'angular', 'src', 'core']);

pressPanelKey(DOWN_ARROW);
pressPanelKey(DOWN_ARROW);
pressPanelKey(DOWN_ARROW);

expect(tree.keyManager.activeItem!.value).toBe('core');
expect(document.activeElement).toBe(searchInput);

// `core` is a leaf, so LEFT_ARROW takes the move-to-parent branch — the highlight moves
// up, but the caret must stay in the search field
pressPanelKey(LEFT_ARROW);

expect(tree.keyManager.activeItem!.value).toBe('src');
expect(document.activeElement).toBe(searchInput);
}));

it('should return the caret to the search field on RIGHT_ARROW', fakeAsync(() => {
trigger.click();
fixture.detectChanges();
flush();

const searchInput: HTMLElement = overlayContainerElement.querySelector('.search-input')!;

const select = fixture.componentInstance.select();
const tree = select.tree()!;

const pressPanelKey = (keyCode: number) => {
select.panelKeydownHandler(createKeyboardEvent('keydown', keyCode));
fixture.detectChanges();
flush();
};

pressPanelKey(DOWN_ARROW);

const activeOption = tree.keyManager.activeItem!;

// RIGHT_ARROW only expands and never moves the active item, so nothing takes the focus
// away from the search field on its own. Hand the focus to the option the way the key
// manager does, to prove the branch restores it rather than relying on it never moving.
activeOption.focus('keyboard');

expect(document.activeElement).not.toBe(searchInput);

pressPanelKey(RIGHT_ARROW);

expect(tree.keyManager.activeItem).toBe(activeOption);
expect(document.activeElement).toBe(searchInput);
}));

it('should show empty message', fakeAsync(() => {
trigger.click();
fixture.detectChanges();
Expand Down
12 changes: 11 additions & 1 deletion packages/components/tree-select/tree-select.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1294,7 +1294,17 @@ export class KbqTreeSelect
this.close();
this.focus();
} else if (keyCode === LEFT_ARROW || keyCode === RIGHT_ARROW) {
return this.originalOnKeyDown.call(this.tree(), event);
this.originalOnKeyDown.call(tree, event);

// LEFT_ARROW moves focus to the parent option when the active one is already collapsed,
// so the search field has to be given the caret back, the same way the other keys do below.
const search = this.search();

if (search && this.shouldShowSearch()) {
search.focus();
}

return;
} else if (keyCode === HOME) {
event.preventDefault();

Expand Down
Loading
Loading