@applicaster/zapp-react-native-utils
Version:
Applicaster Zapp React Native utilities package
87 lines (69 loc) • 2.12 kB
text/typescript
import { isString } from "../stringUtils";
import { TreeNode } from "./TreeNode";
import { getFocusableId } from "./utils";
export class Tree {
private tree: TreeNode[];
constructor(focusManagerTree: TreeNode[] = []) {
this.tree = focusManagerTree;
}
add(component, parentFocusable, isFocusableCell) {
const focusableId = getFocusableId(component);
const parentId = getFocusableId(parentFocusable);
const focusableComponentInTree = this.find(focusableId);
// update node if it already exists
if (focusableComponentInTree) {
focusableComponentInTree.updateNode(component);
}
if (parentFocusable?.current) {
if (!this.find(parentId)) {
this.tree.push(new TreeNode(null, parentId, null, isFocusableCell));
}
const parentNode = this.find(parentId);
if (parentNode) {
if (focusableComponentInTree) {
focusableComponentInTree.isFocusableCell = isFocusableCell;
focusableComponentInTree.parentId = parentNode.id;
parentNode.addChild(focusableComponentInTree);
// remove root object from the list
this.tree = this.tree.filter(
(node) => node !== focusableComponentInTree
);
} else {
parentNode.addChild(component, focusableId, isFocusableCell);
}
}
}
}
remove(focusableId: string) {
this.tree = this.tree.reduce((acc: TreeNode[], node: TreeNode) => {
if (node.id === focusableId) {
return acc;
} else {
node.children = node.removeNode(focusableId);
acc.push(node);
return acc;
}
}, []);
}
find(id: string) {
for (const node of this.tree) {
const foundNode = node.findNode(id);
if (foundNode) {
return foundNode;
}
}
return null;
}
findNode(component) {
return this.find(
isString(component) ? component : getFocusableId(component)
);
}
findParent(id: string) {
const node = this.find(id);
if (node && node.parentId) {
return this.find(node.parentId);
}
return null;
}
}