diff --git a/lib/lrud.js b/lib/lrud.js index 09065a8..df81f24 100644 --- a/lib/lrud.js +++ b/lib/lrud.js @@ -317,6 +317,8 @@ export const getNextFocus = (elem, keyOrKeyCode, scope) => { const isNestedContainer = parentContainer?.contains(candidateContainer); const isAnscestorContainer = candidateContainer?.contains(parentContainer); + if (elem.id) parentContainer?.setAttribute('data-focus', elem.id); + if (!isCurrentContainer && (!isNestedContainer || isBestCandidateAContainer)) { const blockedExitDirs = getBlockedExitDirs(parentContainer, candidateContainer); if (blockedExitDirs.indexOf(exitDir) > -1) return; @@ -324,8 +326,6 @@ export const getNextFocus = (elem, keyOrKeyCode, scope) => { if (candidateContainer && !isAnscestorContainer) { // Ignore active child behaviour when moving into a container that we // are already nested in - if (elem.id) parentContainer?.setAttribute('data-focus', elem.id); - const lastActiveChild = document.getElementById(candidateContainer.getAttribute('data-focus')); return lastActiveChild || getFocusables(candidateContainer)?.[0]; @@ -333,6 +333,7 @@ export const getNextFocus = (elem, keyOrKeyCode, scope) => { } } + if (bestCandidate?.id) parentContainer?.setAttribute('data-focus', bestCandidate.id); return bestCandidate; }; diff --git a/test/lrud.test.js b/test/lrud.test.js index cdef3b1..8193686 100644 --- a/test/lrud.test.js +++ b/test/lrud.test.js @@ -667,5 +667,16 @@ describe('LRUD spatial', () => { await page.keyboard.press('ArrowUp'); expect(await page.evaluate(() => document.activeElement.id)).toEqual('item-1'); }); + + it('should still remember last active child if focus is manually moved from a container', async () => { + await page.evaluate(() => document.getElementById('item-1').focus()); + await page.keyboard.press('ArrowDown'); + await page.keyboard.press('ArrowRight'); + expect(await page.evaluate(() => document.activeElement.id)).toEqual('item-6'); + await page.evaluate(() => document.getElementById('item-8').focus()); + + await page.keyboard.press('ArrowUp'); + expect(await page.evaluate(() => document.activeElement.id)).toEqual('item-6'); + }); }); });