|
1 |
| -import {FocusKeys, FocusZoneSettings, focusZone} from '../focus-zone.js' |
| 1 | +import { |
| 2 | + FocusKeys, |
| 3 | + FocusZoneSettings, |
| 4 | + activeDescendantActivatedDirectly, |
| 5 | + focusZone, |
| 6 | + isActiveDescendantAttribute, |
| 7 | +} from '../focus-zone.js' |
2 | 8 | import {fireEvent, render} from '@testing-library/react'
|
3 |
| -import React from 'react' |
| 9 | +import React, {act} from 'react' |
4 | 10 | import userEvent from '@testing-library/user-event'
|
5 | 11 |
|
6 | 12 | async function nextTick() {
|
@@ -431,6 +437,41 @@ it('Should focus-in to the first element if the last-focused element is removed'
|
431 | 437 | controller.abort()
|
432 | 438 | })
|
433 | 439 |
|
| 440 | +it('Should clear all active descendants when focus moves outside the zone', async () => { |
| 441 | + const {container} = render( |
| 442 | + <div> |
| 443 | + <button tabIndex={0} id="outside"> |
| 444 | + Bad Apple |
| 445 | + </button> |
| 446 | + <input type="text" id="input" tabIndex={0} /> |
| 447 | + <div id="focusZone"> |
| 448 | + <button tabIndex={0}>Apple</button> |
| 449 | + <button tabIndex={0}>Banana</button> |
| 450 | + <button tabIndex={0}>Cantaloupe</button> |
| 451 | + </div> |
| 452 | + </div>, |
| 453 | + ) |
| 454 | + |
| 455 | + const focusZoneContainer = container.querySelector<HTMLElement>('#focusZone')! |
| 456 | + const control = container.querySelector<HTMLInputElement>('#input')! |
| 457 | + const [firstButton, secondButton] = focusZoneContainer.querySelectorAll('button') |
| 458 | + const outsideButton = container.querySelector<HTMLElement>('#outside')! |
| 459 | + const controller = focusZone(focusZoneContainer, {activeDescendantControl: control}) |
| 460 | + |
| 461 | + control.focus() |
| 462 | + const allActiveDescendants = focusZoneContainer.querySelectorAll(`[${isActiveDescendantAttribute}]`) |
| 463 | + expect(allActiveDescendants.length).toEqual(1) |
| 464 | + expect(allActiveDescendants[0]).toEqual(firstButton) |
| 465 | + |
| 466 | + secondButton.setAttribute(isActiveDescendantAttribute, activeDescendantActivatedDirectly) |
| 467 | + expect(focusZoneContainer.querySelectorAll(`[${isActiveDescendantAttribute}]`).length).toEqual(2) |
| 468 | + |
| 469 | + outsideButton.focus() |
| 470 | + expect(focusZoneContainer.querySelectorAll(`[${isActiveDescendantAttribute}]`).length).toEqual(0) |
| 471 | + |
| 472 | + controller.abort() |
| 473 | +}) |
| 474 | + |
434 | 475 | it('Should call onActiveDescendantChanged properly', async () => {
|
435 | 476 | const user = userEvent.setup()
|
436 | 477 | const {container} = render(
|
@@ -625,7 +666,7 @@ it('Should ignore hidden elements if strict', async () => {
|
625 | 666 | controller.abort()
|
626 | 667 | })
|
627 | 668 |
|
628 |
| -it('Shoud move to tabbable elements if onlyTabbable', async () => { |
| 669 | +it('Should move to tabbable elements if onlyTabbable', async () => { |
629 | 670 | const user = userEvent.setup()
|
630 | 671 | const {container} = render(
|
631 | 672 | <div id="focusZone">
|
|
0 commit comments