import React, { useMemo } from "react"; import { ImageStyle } from "react-native"; import { Focusable } from "@applicaster/zapp-react-native-ui-components/Components/Focusable"; import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions"; import { getXray } from "@applicaster/zapp-react-native-utils/logger"; import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils"; const { Logger } = getXray(); import { recursiveCloneElementsWithState, getFocusedButtonId, } from "../../utils"; const logger = new Logger("plugin", "plugins/navigation-action"); type Props = Record & { style: ImageStyle; }; const getFocusableId = (prefixId, suffixId) => `${prefixId}___${suffixId}`; export function FocusableView({ style, children, item, ...otherProps }: Props) { const { groupId, prefixId, suffixId, wrapperRef, focusedButtonId, normalStyles, focusedStyles, pluginIdentifier, preferredFocus, } = otherProps; const focusableId = getFocusableId(prefixId, suffixId); const focused = focusableId === focusedButtonId || toBooleanWithDefaultFalse(otherProps.focused); const additionalStyles = focused ? focusedStyles : normalStyles; const actionContext = useActions(pluginIdentifier); const onPress = (event) => { event?.preventDefault?.(); if (!actionContext) { logger.warning( `Cannot resolve action context for ${pluginIdentifier} - please make sure the plugin is installed and up to date` ); return; } actionContext?.invokeAction?.(item); }; const handleFocus = (focusable) => { const focusedButtonId = getFocusedButtonId(focusable); otherProps?.onToggleFocus?.({ focusable: wrapperRef.current, focusedButtonId, mouse: focusable.mouse, }); }; const handleBlur = (_focusable, _direction) => { otherProps?.onToggleFocus?.({ focusedButtonId: undefined }); }; const styles = useMemo( () => ({ ...style, ...additionalStyles }), [additionalStyles, style] ); return ( {(isFocused) => recursiveCloneElementsWithState(isFocused, children)} ); }