Skip to content

Commit 580ef96

Browse files
committed
feat(combo): update Escape key behavior
1 parent efadf61 commit 580ef96

File tree

3 files changed

+104
-12
lines changed

3 files changed

+104
-12
lines changed

src/components/combo/combo.spec.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import {
77
arrowUp,
88
endKey,
99
enterKey,
10+
escapeKey,
1011
homeKey,
1112
spaceBar,
13+
tabKey,
1214
} from '../common/controllers/key-bindings.js';
1315
import { defineComponents } from '../common/definitions/defineComponents.js';
1416
import { first } from '../common/util.js';
@@ -716,6 +718,48 @@ describe('Combo', () => {
716718
expect(combo.open).to.be.true;
717719
});
718720

721+
it('should close the menu by pressing the Tab key', async () => {
722+
await combo.show();
723+
await list.layoutComplete;
724+
725+
simulateKeyboard(options, tabKey, 1);
726+
await elementUpdated(combo);
727+
expect(combo.open).to.be.false;
728+
729+
await combo.show();
730+
simulateKeyboard(searchInput, tabKey, 1);
731+
await elementUpdated(combo);
732+
733+
expect(combo.open).to.be.false;
734+
735+
await combo.show();
736+
simulateKeyboard(input, tabKey, 1);
737+
await elementUpdated(combo);
738+
739+
expect(combo.open).to.be.false;
740+
});
741+
742+
it('should clear the selection by pressing the Escape key when the combo is closed', async () => {
743+
combo.autofocusList = true;
744+
combo.select(['BG01', 'BG02']);
745+
await elementUpdated(combo);
746+
747+
await combo.show();
748+
await list.layoutComplete;
749+
750+
simulateKeyboard(options, escapeKey, 1);
751+
await elementUpdated(combo);
752+
753+
expect(combo.open).to.be.false;
754+
expect(combo.value.length).to.equal(2);
755+
756+
simulateKeyboard(input, escapeKey, 1);
757+
await elementUpdated(combo);
758+
759+
expect(combo.open).to.be.false;
760+
expect(combo.value.length).to.equal(0);
761+
});
762+
719763
it('should select the active item and close the menu by pressing Enter in single selection', async () => {
720764
combo.singleSelect = true;
721765
await elementUpdated(combo);
@@ -750,6 +794,43 @@ describe('Combo', () => {
750794
expect(combo.open).to.be.false;
751795
});
752796

797+
it('should close the menu by pressing the Tab key in single selection', async () => {
798+
await combo.show();
799+
await list.layoutComplete;
800+
801+
simulateKeyboard(options, tabKey, 1);
802+
await elementUpdated(combo);
803+
804+
expect(combo.open).to.be.false;
805+
806+
await combo.show();
807+
simulateKeyboard(input, tabKey, 1);
808+
await elementUpdated(combo);
809+
810+
expect(combo.open).to.be.false;
811+
});
812+
813+
it('should clear the selection by pressing the Escape key in single selection', async () => {
814+
combo.singleSelect = true;
815+
combo.select('BG01');
816+
await elementUpdated(combo);
817+
818+
await combo.show();
819+
await list.layoutComplete;
820+
821+
simulateKeyboard(options, escapeKey, 1);
822+
await elementUpdated(combo);
823+
824+
expect(combo.open).to.be.false;
825+
expect(combo.value.length).to.equal(1);
826+
827+
simulateKeyboard(input, escapeKey, 1);
828+
await elementUpdated(combo);
829+
830+
expect(combo.open).to.be.false;
831+
expect(combo.value.length).to.equal(0);
832+
});
833+
753834
it('should support a single selection variant', async () => {
754835
combo.singleSelect = true;
755836
await elementUpdated(combo);

src/components/combo/combo.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,17 @@ export default class IgcComboComponent<
799799
this.updateValue();
800800
}
801801

802+
/** @hidden @internal */
803+
public clearSelection() {
804+
if (this.singleSelect) {
805+
this.resetSearchTerm();
806+
this.clearSingleSelection();
807+
} else {
808+
this._selection.deselect([], true);
809+
}
810+
this.updateValue();
811+
}
812+
802813
protected clearSingleSelection() {
803814
const _selection = this._selection.asArray;
804815
const selection = first(_selection);
@@ -812,15 +823,7 @@ export default class IgcComboComponent<
812823

813824
protected handleClearIconClick(e: PointerEvent) {
814825
e.stopPropagation();
815-
816-
if (this.singleSelect) {
817-
this.resetSearchTerm();
818-
this.clearSingleSelection();
819-
} else {
820-
this._selection.deselect([], true);
821-
}
822-
823-
this.updateValue();
826+
this.clearSelection();
824827
this._navigation.active = -1;
825828
}
826829

src/components/combo/controllers/navigation.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,19 @@ export class ComboNavigationController<T extends object> {
109109
}
110110
};
111111

112-
private _onTab = async (): Promise<void> => {
112+
private _onTab = async (shiftKey?: boolean): Promise<void> => {
113113
if (this.combo.open) {
114+
if (shiftKey) {
115+
this.combo.focus();
116+
}
114117
await this._hide();
115118
}
116119
};
117120

118121
private _onEscape = async (): Promise<void> => {
122+
if (!this.combo.open) {
123+
this.combo.clearSelection();
124+
}
119125
if (await this._hide()) {
120126
this.input.focus();
121127
}
@@ -207,8 +213,10 @@ export class ComboNavigationController<T extends object> {
207213

208214
// Combo
209215
addKeybindings(this.combo, { skip, bindingDefaults })
210-
.set(tabKey, this._onTab, { preventDefault: false })
211-
.set([shiftKey, tabKey], this._onTab, { preventDefault: false })
216+
.set(tabKey, () => this._onTab(), { preventDefault: false })
217+
.set([shiftKey, tabKey], () => this._onTab(true), {
218+
preventDefault: false,
219+
})
212220
.set(escapeKey, this._onEscape);
213221

214222
// Main input

0 commit comments

Comments
 (0)