diff --git a/projects/cdk/directives/focus-trap/focus-trap.directive.ts b/projects/cdk/directives/focus-trap/focus-trap.directive.ts index 4914e1b5186a..9ade3846d180 100644 --- a/projects/cdk/directives/focus-trap/focus-trap.directive.ts +++ b/projects/cdk/directives/focus-trap/focus-trap.directive.ts @@ -62,9 +62,11 @@ export class TuiFocusTrap implements OnDestroy { } protected onFocusIn(node: Node): void { - if (!tuiContainsOrAfter(this.el, node)) { + const firstElementChild = this.el.firstElementChild; + + if (!tuiContainsOrAfter(this.el, node) && firstElementChild) { tuiGetClosestFocusable({ - initial: this.el, + initial: firstElementChild, root: this.el, })?.focus(); } diff --git a/projects/cdk/utils/focus/get-closest-focusable.ts b/projects/cdk/utils/focus/get-closest-focusable.ts index cb10b2a24463..db960badd785 100644 --- a/projects/cdk/utils/focus/get-closest-focusable.ts +++ b/projects/cdk/utils/focus/get-closest-focusable.ts @@ -53,7 +53,7 @@ export function tuiGetClosestFocusable({ treeWalker.currentNode = initial; - while (previous ? treeWalker.previousNode() : treeWalker.nextNode()) { + do { if (tuiIsHTMLElement(treeWalker.currentNode)) { initial = treeWalker.currentNode; } @@ -61,7 +61,7 @@ export function tuiGetClosestFocusable({ if (tuiIsHTMLElement(initial) && check(initial)) { return initial; } - } + } while (previous ? treeWalker.previousNode() : treeWalker.nextNode()); return null; } diff --git a/projects/demo-playwright/tests/core/data-list/data-list.pw.spec.ts b/projects/demo-playwright/tests/core/data-list/data-list.pw.spec.ts index f2816d552fa9..8a6401ad9834 100644 --- a/projects/demo-playwright/tests/core/data-list/data-list.pw.spec.ts +++ b/projects/demo-playwright/tests/core/data-list/data-list.pw.spec.ts @@ -36,37 +36,50 @@ test.describe('DataList', () => { const example = documentationPagePO.getExample('#submenu'); await example.scrollIntoViewIfNeeded(); - await example.locator('button').click(); await documentationPagePO.prepareBeforeScreenshot(); + + await example.locator('button').click(); await page.keyboard.down('ArrowDown'); await page.keyboard.down('ArrowDown'); + + await expect(page).toHaveScreenshot('03-1-data-list.png'); + await page.waitForTimeout(100); await page.keyboard.down('Enter'); await page.waitForTimeout(100); - await expect(page).toHaveScreenshot('03-1-data-list.png'); + await expect(page).toHaveScreenshot('03-2-data-list.png'); await page.keyboard.down('ArrowRight'); + + await expect(page).toHaveScreenshot('03-3-data-list.png'); + await page.keyboard.down('ArrowDown'); await page.keyboard.down('ArrowDown'); await page.keyboard.down('ArrowDown'); + + await expect(page).toHaveScreenshot('03-4-data-list.png'); + await page.waitForTimeout(100); await page.keyboard.down('Enter'); await page.waitForTimeout(100); - await expect(page).toHaveScreenshot('03-2-data-list.png'); + await expect(page).toHaveScreenshot('03-5-data-list.png'); await page.keyboard.down('ArrowRight'); + + await expect(page).toHaveScreenshot('03-6-data-list.png'); + await page.keyboard.down('ArrowDown'); await page.keyboard.down('ArrowDown'); - await expect(page).toHaveScreenshot('03-3-data-list.png'); + await expect(page).toHaveScreenshot('03-7-data-list.png'); await page.waitForTimeout(100); await page.keyboard.down('Enter'); await page.waitForTimeout(100); - await expect(page).toHaveScreenshot('03-4-data-list.png'); + await expect(page).toHaveScreenshot('03-8-data-list.png'); }); test('Form control', async ({page}) => { diff --git a/projects/kit/directives/data-list-dropdown-manager/data-list-dropdown-manager.directive.ts b/projects/kit/directives/data-list-dropdown-manager/data-list-dropdown-manager.directive.ts index f43b62f4bebe..183be4d03693 100644 --- a/projects/kit/directives/data-list-dropdown-manager/data-list-dropdown-manager.directive.ts +++ b/projects/kit/directives/data-list-dropdown-manager/data-list-dropdown-manager.directive.ts @@ -163,8 +163,6 @@ export class TuiDataListDropdownManager implements AfterViewInit { root: content, }); - if (item) { - item.focus(); - } + item?.focus(); } }