From 11123051118a46e1c3bbb2730d3e811da6226302 Mon Sep 17 00:00:00 2001 From: MonikaKirkova Date: Fri, 29 Aug 2025 18:51:17 +0300 Subject: [PATCH 1/2] fix(focus-trap): filter the hidden elements in getFocusableElements --- .../focus-trap/focus-trap.directive.spec.ts | 41 ++++++++++++++++++- .../focus-trap/focus-trap.directive.ts | 2 +- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/projects/igniteui-angular/src/lib/directives/focus-trap/focus-trap.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/focus-trap/focus-trap.directive.spec.ts index 8f0e8c5385b..098148d15ee 100644 --- a/projects/igniteui-angular/src/lib/directives/focus-trap/focus-trap.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/focus-trap/focus-trap.directive.spec.ts @@ -5,6 +5,7 @@ import { IgxFocusTrapDirective } from './focus-trap.directive'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { UIInteractions } from '../../test-utils/ui-interactions.spec'; +import { IgxTimePickerComponent } from 'igniteui-angular'; describe('igxFocusTrap', () => { beforeEach(waitForAsync(() => { @@ -161,6 +162,39 @@ describe('igxFocusTrap', () => { fix.detectChanges(); expect(document.activeElement).toEqual(button.nativeElement); })); + + it('should focus only visible focusable elements on Tab key pressed', () => { + const fix = TestBed.createComponent(TrapFocusTestComponent); + fix.detectChanges(); + + fix.componentInstance.showTimePicker = true; + fix.detectChanges(); + + const focusTrap = fix.debugElement.query(By.directive(IgxFocusTrapDirective)); + const buttons = fix.debugElement.queryAll(By.css('button')); + const inputs = fix.debugElement.queryAll(By.css('input')); + const timePickerInput = fix.debugElement.query(By.css('.igx-input-group__input')); + + UIInteractions.triggerEventHandlerKeyDown('Tab', focusTrap); + fix.detectChanges(); + expect(document.activeElement).toEqual(inputs[0].nativeElement); + + UIInteractions.triggerEventHandlerKeyDown('Tab', focusTrap); + fix.detectChanges(); + expect(document.activeElement).toEqual(inputs[1].nativeElement); + + UIInteractions.triggerEventHandlerKeyDown('Tab', focusTrap); + fix.detectChanges(); + expect(document.activeElement).toEqual(timePickerInput.nativeElement); + + UIInteractions.triggerEventHandlerKeyDown('Tab', focusTrap); + fix.detectChanges(); + expect(document.activeElement).toEqual(buttons[buttons.length - 1].nativeElement); + + UIInteractions.triggerEventHandlerKeyDown('Tab', focusTrap); + fix.detectChanges(); + expect(document.activeElement).toEqual(inputs[0].nativeElement); + }); }); @@ -177,14 +211,19 @@ describe('igxFocusTrap', () => { }
+ @if (showTimePicker) { + + } +
@if (showButton) { } `, - imports: [IgxFocusTrapDirective] + imports: [IgxFocusTrapDirective, IgxTimePickerComponent] }) class TrapFocusTestComponent { public showInput = true; public showButton = true; public focusTrap = true; + public showTimePicker = false; } diff --git a/projects/igniteui-angular/src/lib/directives/focus-trap/focus-trap.directive.ts b/projects/igniteui-angular/src/lib/directives/focus-trap/focus-trap.directive.ts index 254a75f3dcf..e27c900c449 100644 --- a/projects/igniteui-angular/src/lib/directives/focus-trap/focus-trap.directive.ts +++ b/projects/igniteui-angular/src/lib/directives/focus-trap/focus-trap.directive.ts @@ -80,7 +80,7 @@ export class IgxFocusTrapDirective implements AfterViewInit, OnDestroy { private getFocusableElements(element: Element) { return Array.from(element.querySelectorAll( 'a[href], button, input, textarea, select, details,[tabindex]:not([tabindex="-1"])' - )).filter(el => !el.hasAttribute('disabled') && !el.getAttribute('aria-hidden')); + )).filter(el => !el.hasAttribute('disabled') && !el.closest('[aria-hidden="true"]')); } private getFocusedElement(): HTMLElement | null { From 9f614bbb034cf8a793cfe1daf42f882d16de95f5 Mon Sep 17 00:00:00 2001 From: MonikaKirkova Date: Fri, 29 Aug 2025 19:19:01 +0300 Subject: [PATCH 2/2] chore(*): fix import in .spec file --- .../src/lib/directives/focus-trap/focus-trap.directive.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/igniteui-angular/src/lib/directives/focus-trap/focus-trap.directive.spec.ts b/projects/igniteui-angular/src/lib/directives/focus-trap/focus-trap.directive.spec.ts index 098148d15ee..d0f810ce20d 100644 --- a/projects/igniteui-angular/src/lib/directives/focus-trap/focus-trap.directive.spec.ts +++ b/projects/igniteui-angular/src/lib/directives/focus-trap/focus-trap.directive.spec.ts @@ -5,7 +5,7 @@ import { IgxFocusTrapDirective } from './focus-trap.directive'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { UIInteractions } from '../../test-utils/ui-interactions.spec'; -import { IgxTimePickerComponent } from 'igniteui-angular'; +import { IgxTimePickerComponent } from '../../time-picker/time-picker.component'; describe('igxFocusTrap', () => { beforeEach(waitForAsync(() => {