Skip to content

Commit

Permalink
Fix data-focus updating when exit is blocked (#41)
Browse files Browse the repository at this point in the history
* Refactor how data-focus is applied

* New test
  • Loading branch information
Murreey committed Jan 29, 2024
1 parent e24b3e0 commit c40fb1f
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 6 deletions.
11 changes: 6 additions & 5 deletions lib/lrud.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@ export const getNextFocus = (elem, keyOrKeyCode, scope) => {

// Get parent focus container
const parentContainer = getParentContainer(elem);
if (parentContainer && matches(elem, focusableSelector)) {
parentContainer.setAttribute('data-focus', elem.id);
}

let bestCandidate;

Expand All @@ -317,24 +320,22 @@ export const getNextFocus = (elem, keyOrKeyCode, scope) => {
const isNestedContainer = parentContainer?.contains(candidateContainer);
const isAnscestorContainer = candidateContainer?.contains(parentContainer);

const candidateActiveChild = candidateContainer?.getAttribute('data-focus');
parentContainer?.setAttribute('data-focus', elem.id);
candidateContainer?.setAttribute('data-focus', bestCandidate.id);

if (!isCurrentContainer && (!isNestedContainer || isBestCandidateAContainer)) {
const blockedExitDirs = getBlockedExitDirs(parentContainer, candidateContainer);
if (blockedExitDirs.indexOf(exitDir) > -1) return;

if (candidateContainer && !isAnscestorContainer) {
// Ignore active child behaviour when moving into a container that we
// are already nested in
const lastActiveChild = document.getElementById(candidateActiveChild);
const lastActiveChild = document.getElementById(candidateContainer?.getAttribute('data-focus'));

const newFocus = lastActiveChild || getFocusables(candidateContainer)?.[0];
candidateContainer?.setAttribute('data-focus', newFocus?.id);
return newFocus;
}
}

candidateContainer?.setAttribute('data-focus', bestCandidate.id);
}

return bestCandidate;
Expand Down
12 changes: 11 additions & 1 deletion test/lrud.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ describe('LRUD spatial', () => {
let page;
let context;

const getParentContainerDataFocus = (id) => page.evaluate((id) => document.getElementById(id).parentElement.getAttribute('data-focus'), id);

beforeAll(async () => {
try {
await server.listen();
Expand Down Expand Up @@ -688,7 +690,6 @@ describe('LRUD spatial', () => {
});

it('should only store the last active child ID if the child is not inside another container', async () => {
const getParentContainerDataFocus = (id) => page.evaluate((id) => document.getElementById(id).parentElement.getAttribute('data-focus'), id);
await page.goto(`${testPath}/4c-v-5f-nested.html`);
await page.evaluate(() => document.getElementById('item-1').focus());
await page.keyboard.press('ArrowDown');
Expand All @@ -706,5 +707,14 @@ describe('LRUD spatial', () => {
expect(await getParentContainerDataFocus('item-1')).toEqual('item-1');
expect(await getParentContainerDataFocus('item-2')).toEqual('item-2');
});

it('does not update the new active child ID if the exit was blocked', async () => {
await page.goto(`${testPath}/3c-h-6f-blocked-exit.html`);
await page.evaluate(() => document.getElementById('item-2').focus());
await page.keyboard.press('ArrowDown');
expect(await getParentContainerDataFocus('item-2')).toEqual('item-2');
expect(await page.evaluate(() => document.activeElement.id)).toEqual('item-2');
expect(await getParentContainerDataFocus('item-3')).toEqual(null);
});
});
});

0 comments on commit c40fb1f

Please sign in to comment.