import { extractOverflowButtonData, overflowMenuPressHandlerDropdownMenu, defaultOnOverflowMenuPress, type OnOverflowMenuPressParams, } from './overflowMenuPressHandlers'; import { OVERFLOW_TOP, useOverflowMenu } from './OverflowMenuContext'; import { View, StyleSheet, type ColorValue } from 'react-native'; import { HeaderButton, type HeaderButtonProps } from '../HeaderButton'; import { ButtonsWrapper, ButtonsWrapperProps } from '../ButtonsWrapper'; import { Children, ComponentType, isValidElement, useCallback, useRef, type ReactElement, } from 'react'; import * as React from 'react'; import { OVERFLOW_BUTTON_TEST_ID } from '../e2e'; export type OverflowMenuProps = Omit< HeaderButtonProps, 'onPress' | 'title' | 'renderButton' > & Pick & { OverflowIcon: ReactElement | ComponentType<{ color: ColorValue }>; onPress?: (params: OnOverflowMenuPressParams) => any; }; export const OverflowMenu = ({ children, OverflowIcon = , accessibilityLabel = 'More options', testID = OVERFLOW_BUTTON_TEST_ID, onPress = defaultOnOverflowMenuPress, left = false, // this is needed only when OverflowMenu is rendered without HeaderButtons, preset, ...other }: OverflowMenuProps) => { const presentationCalls = useOverflowMenu(); const btnRef = useRef(null); const renderButtonElement = useCallback( ({ color }: { color: ColorValue }) => { return isValidElement(OverflowIcon) ? ( OverflowIcon ) : ( ); }, [OverflowIcon] ); const presentOverflowMenu = useCallback(() => { const titlesAndOnPresses = onPress === overflowMenuPressHandlerDropdownMenu ? [] : extractOverflowButtonData(children); onPress({ children, hiddenButtons: titlesAndOnPresses, overflowButtonRef: btnRef.current, ...presentationCalls, }); }, [children, onPress, presentationCalls]); const validChildren = Children.toArray(children).filter(isValidElement); if (validChildren.length === 0) { return null; } return ( ); }; const styles = StyleSheet.create({ wrapper: { columnGap: 0, }, overflowMenuAnchor: { // these are really just needed bcs of the native android popup menu position: 'absolute', top: -OVERFLOW_TOP, // TODO android actually has a little gap on the right of the menu right: -15, backgroundColor: 'transparent', width: 1, height: 1, }, });