import { forwardRef, memo, ReactNode, useCallback, useContext, useMemo } from 'react'; import { StyleProp, Text, View, ViewStyle, type GestureResponderEvent, type TextProps, } from 'react-native'; import type { WithElements } from '../../types'; import { TouchableRipple, type TouchableRippleProps } from '../TouchableRipple'; import { StateLayer, type StateLayerProps } from '../StateLayer'; import { MenuContext } from './Menu'; import { resolveStateVariant } from '../../utils'; import { menuItemStyles } from './utils'; import { useActionState } from '../../hooks'; export type Props = TouchableRippleProps & WithElements & { size?: 'default' | 'dense'; stateLayerProps?: StateLayerProps; textProps?: Omit; leftElementStyle?: StyleProp; rightElementStyle?: StyleProp; }; const emptyObj = {}; const _MenuItem = ( { onPress, left, right, children, disabled = false, size = 'default', style, testID, stateLayerProps, textProps = emptyObj, leftElementStyle: _leftElementStyle, rightElementStyle: _rightElementStyle, ...rest }: Props, ref: any, ) => { const { hovered, actionsRef } = useActionState({ ref, actionsToListen: ['hover'] }); const { closeOnSelect, onClose } = useContext(MenuContext); const state = resolveStateVariant({ disabled, hovered, }); menuItemStyles.useVariants({ size: size as any, state: state as any, }); const onPressItem = useCallback( (e: GestureResponderEvent) => { if (closeOnSelect) onClose(); onPress?.(e); }, [closeOnSelect, onClose, onPress], ); const { containerStyle, leftElementStyle, rightElementStyle, textStyle, stateLayerStyle } = useMemo(() => { const { text, leftElement, rightElement, stateLayer } = menuItemStyles; return { containerStyle: [menuItemStyles.root, style], textStyle: [text, textProps?.style], leftElementStyle: [leftElement, _leftElementStyle], rightElementStyle: [rightElement, _rightElementStyle], stateLayerStyle: stateLayer, }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [_leftElementStyle, _rightElementStyle, style, textProps?.style, state, size]); return ( <> {left ? ( {left} ) : null} {children} {right ? ( {right} ) : null} ); }; const MenuItem = memo(forwardRef(_MenuItem)); MenuItem.displayName = 'Menu_Item'; export default MenuItem;