import React, { forwardRef, Ref, useCallback, useMemo } from 'react'; import { Platform, Pressable, TouchableOpacity, View } from 'react-native'; import { ContextMenuView, RenderItem, OnPressMenuItemEventObject, MenuState, IconConfig } from 'react-native-ios-context-menu'; import { MenuView, MenuAction, NativeActionEvent } from '@react-native-menu/menu'; import { ToolTipMenuProps, Action } from './types'; const BaseToolTipMenu = (props: ToolTipMenuProps, ref: Ref) => { const { title = '', isMenuPrimaryAction = false, renderPreview, disabled = false, onPress, onMenuWillShow, onMenuWillHide, buttonStyle, onPressMenuItem, children, isButton = false, ...restProps } = props; const mapMenuItemForContextMenuView = useCallback((action: Action) => { return { actionKey: action.id.toString(), actionTitle: action.text, icon: action.icon?.iconValue ? ({ iconType: 'SYSTEM', iconValue: action.icon.iconValue } as IconConfig) : undefined, state: action.menuStateOn ? ('on' as MenuState) : ('off' as MenuState), attributes: action.disabled ? ['disabled'] : [], }; }, []); const mapMenuItemForMenuView = useCallback((action: Action): MenuAction => { return { id: action.id.toString(), title: action.text, image: action.menuStateOn && Platform.OS === 'android' ? 'checkbox_on_background' : action.icon?.iconValue || undefined, state: action.menuStateOn ? ('on' as MenuState) : undefined, attributes: { disabled: action.disabled }, }; }, []); const contextMenuItems = useMemo(() => { const flattenedActions = props.actions.flat(); return flattenedActions.map(mapMenuItemForContextMenuView); }, [props.actions, mapMenuItemForContextMenuView]); const menuViewItemsIOS = useMemo(() => { return props.actions.map(actionGroup => { if (Array.isArray(actionGroup)) { return { id: actionGroup[0].id.toString(), title: '', subactions: actionGroup.map(mapMenuItemForMenuView), displayInline: true, }; } else { return mapMenuItemForMenuView(actionGroup); } }); }, [props.actions, mapMenuItemForMenuView]); const menuViewItemsAndroid = useMemo(() => { const mergedActions = props.actions.flat(); return mergedActions.map(mapMenuItemForMenuView); }, [props.actions, mapMenuItemForMenuView]); const handlePressMenuItemForContextMenuView = useCallback( (event: OnPressMenuItemEventObject) => { onPressMenuItem(event.nativeEvent.actionKey); }, [onPressMenuItem], ); const handlePressMenuItemForMenuView = useCallback( ({ nativeEvent }: NativeActionEvent) => { onPressMenuItem(nativeEvent.event); }, [onPressMenuItem], ); const renderContextMenuView = () => { console.debug('ToolTipMenu.tsx rendering: renderContextMenuView'); return ( {onPress ? ( {children} ) : ( children )} ); }; const renderMenuView = () => { console.debug('ToolTipMenu.tsx rendering: renderMenuView'); return ( {isMenuPrimaryAction || isButton ? ( {children} ) : ( children )} ); }; return Platform.OS === 'ios' && renderPreview ? renderContextMenuView() : renderMenuView(); }; const ToolTipMenu = forwardRef(BaseToolTipMenu); export default ToolTipMenu;