@applicaster/zapp-react-native-utils
Version:
Applicaster Zapp React Native utilities package
77 lines (59 loc) • 2.02 kB
text/typescript
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
import { find, path } from "ramda";
import {
waitForActiveScreen,
waitForContent,
getContentNode,
getNavbarNode,
} from "./utils";
import { coreLogger } from "../../logger";
const logger = coreLogger.addSubsystem("focusManagerAux");
export async function setFocusOnMenu(currentRoute: string) {
const { setFocus, focusableTree } = focusManager;
try {
await waitForActiveScreen(currentRoute, focusableTree);
const navbar = getNavbarNode(focusableTree);
const selectedMenuItemId = find(
(child) => child.component.props.selected,
navbar.children
)?.id;
if (selectedMenuItemId) {
// set focus on selected menu item
setFocus(selectedMenuItemId);
return;
}
const firstMenuItemId = path(["children", 0, "id"], navbar);
if (firstMenuItemId) {
// set focus on first menu item
setFocus(firstMenuItemId);
}
} catch (error) {
logger.log({
message: "setFocusOnMenu – failed to put focus on top-menu",
data: {
currentRoute,
error,
},
});
}
}
export async function setFocusOnContent(currentRoute: string) {
// we need to put focus on content here
// For doing it we have to wait registration of first focusable node into focusableTree
// we wait until content node starts having children
const { setInitialFocus, focusableTree } = focusManager;
try {
await waitForActiveScreen(currentRoute, focusableTree);
await waitForContent(focusableTree);
const content = getContentNode(focusableTree);
const { success } = setInitialFocus(content);
if (!success) {
// we've failed to put initial focus on content, re-run "setFocusOnContent" again as a fallback
throw Error(
"we've failed to put initial focus on content, re-run 'setFocusOnContent' again as a fallback"
);
}
} catch (error) {
setFocusOnContent(currentRoute);
}
}