feat: finish core impl + tests

This adds new tests for the FocusableTreeTraverser and fixes a number of
issues with the original implementation (one of which required two new
API methods to be added to IFocusableTree). More tests have also been
added for FocusManager, and defocusing tracked nodes/trees has been
fully implemented in FocusManager.
This commit is contained in:
Ben Henning
2025-03-27 21:57:30 +00:00
parent d9beacddb4
commit 516e3af936
6 changed files with 1400 additions and 91 deletions

View File

@@ -40,6 +40,28 @@ export interface IFocusableTree {
*/
getRootFocusableNode(): IFocusableNode;
/**
* Returns all directly nested trees under this tree.
*
* Note that the returned list of trees doesn't need to be stable, however all
* returned trees *do* need to be registered with FocusManager. Additionally,
* this must return actual nested trees as omitting a nested tree will affect
* how focus changes map to a specific node and its tree, potentially leading
* to user confusion.
*/
getNestedTrees(): Array<IFocusableTree>;
/**
* Returns the IFocusableNode corresponding to the specified element ID, or
* null if there's no exact node within this tree with that ID or if the ID
* corresponds to the root of the tree.
*
* This will never match against nested trees.
*
* @param id The ID of the node's focusable HTMLElement or SVGElement.
*/
lookUpFocusableNode(id: string): IFocusableNode | null;
/**
* Returns the IFocusableNode corresponding to the select element, or null if
* the element does not have such a node.
@@ -47,7 +69,11 @@ export interface IFocusableTree {
* The provided element must have a non-null ID that conforms to the contract
* mentioned in IFocusableNode.
*
* This function may match against the root node of the tree.
* This function may match against the root node of the tree. It will also map
* against the nearest node to the provided element if the element does not
* have an exact matching corresponding node. This function filters out
* matches against nested trees, so long as they are represented in the return
* value of getNestedTrees.
*/
findFocusableNodeFor(
element: HTMLElement | SVGElement,