Skip to content

Commit d62ccd1

Browse files
authored
fix(select): Tab key behaviour with open dropdown (#1367)
Pressing Tab in a select with open dropdown when the active item matches the current selection now correctly moves the focus back on the select after closing the dropdown.
1 parent 556bad3 commit d62ccd1

File tree

3 files changed

+28
-11
lines changed

3 files changed

+28
-11
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](http://keepachangelog.com/)
55
and this project adheres to [Semantic Versioning](http://semver.org/).
66

7+
## [Unreleased]
8+
### Fixed
9+
- Select - pressing Tab key in an opened Select now correctly returns focus back to the component after closing the dropdown
10+
711
## [5.0.0] - 2024-08-27
812
### Added
913
- Icon Registry [#1304](https://github.com/IgniteUI/igniteui-webcomponents/issues/1304)

src/components/select/select.spec.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
import { defineComponents } from '../common/definitions/defineComponents.js';
2323
import {
2424
FormAssociatedTestBed,
25+
isFocused,
2526
simulateClick,
2627
simulateKeyboard,
2728
} from '../common/utils.spec.js';
@@ -831,6 +832,22 @@ describe('Select', () => {
831832
expect(select.open).to.be.false;
832833
});
833834

835+
it('pressing Tab while the active item is the current selected item moves focus back to the component', async () => {
836+
select.value = 'spec';
837+
await openSelect();
838+
839+
simulateKeyboard(select, tabKey);
840+
await elementUpdated(select);
841+
842+
const item = select.items[0];
843+
844+
checkItemState(item, { active: true, selected: true });
845+
expect(select.selectedItem).to.equal(item);
846+
expect(select.value).to.equal(item.value);
847+
expect(select.open).to.be.false;
848+
expect(isFocused(select)).to.be.true;
849+
});
850+
834851
// Search selection
835852

836853
it('does not select disabled items when searching (closed state)', async () => {
@@ -1038,7 +1055,6 @@ describe('Select', () => {
10381055
expect(select.selectedItem).to.be.null;
10391056
});
10401057

1041-
// TODO
10421058
it('ArrowUp (closed state)', async () => {
10431059
const eventSpy = spy(select, 'emitEvent');
10441060
const activeItems = Items.filter((item) => !item.disabled).reverse();

src/components/select/select.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ export default class IgcSelectComponent extends FormAssociatedRequiredMixin(
426426
private onTabKey(event: KeyboardEvent) {
427427
if (this.open) {
428428
event.preventDefault();
429-
this._selectItem(this._activeItem);
429+
this._selectItem(this._activeItem ?? this._selectedItem);
430430
this._hide(true);
431431
}
432432
}
@@ -472,13 +472,11 @@ export default class IgcSelectComponent extends FormAssociatedRequiredMixin(
472472
return null;
473473
}
474474

475-
const items = this.items;
476-
const [previous, current] = [
477-
items.indexOf(this._selectedItem!),
478-
items.indexOf(item),
479-
];
475+
const shouldFocus = emit && this.open;
476+
const shouldHide = emit && !this.keepOpenOnSelect;
480477

481-
if (previous === current) {
478+
if (this._selectedItem === item) {
479+
if (shouldFocus) this.input.focus();
482480
return this._selectedItem;
483481
}
484482

@@ -487,8 +485,8 @@ export default class IgcSelectComponent extends FormAssociatedRequiredMixin(
487485
this._updateValue(newItem.value);
488486

489487
if (emit) this.handleChange(newItem);
490-
if (emit && this.open) this.input.focus();
491-
if (emit && !this.keepOpenOnSelect) this._hide(true);
488+
if (shouldFocus) this.input.focus();
489+
if (shouldHide) this._hide(true);
492490

493491
return this._selectedItem;
494492
}
@@ -534,7 +532,6 @@ export default class IgcSelectComponent extends FormAssociatedRequiredMixin(
534532
/** Removes focus from the component. */
535533
public override blur() {
536534
this.input.blur();
537-
super.blur();
538535
}
539536

540537
/** Checks the validity of the control and moves the focus to it if it is not valid. */

0 commit comments

Comments
 (0)