import React, { forwardRef, useRef } from 'react'; import type { StyleProp, ViewStyle } from 'react-native'; import { Animated, Modal, Platform } from 'react-native'; import { useDeprecation } from '../../../utils/hooks'; import Box from '../../Box'; import type { IconName } from '../../Icon'; import Portal from '../../Portal'; import type { FABHandles } from '../FAB'; import type { ActionItemProps } from './ActionItem'; import ActionItem from './ActionItem'; import { StyledActionGroupContainer, StyledBackdrop, StyledBackdropPressable, StyledContainer, StyledContainerInModal, StyledFAB, } from './StyledActionGroup'; export type ActionGroupHandles = { showFAB: () => void; collapseFAB: () => void; hideFAB: () => void; }; export interface ActionGroupProps { /** * @deprecated FAB.ActionGroup's `headerTitle` prop will be removed in the next major release. Please remove it. * * Title of the action group header. */ headerTitle?: string; /** * This function is called on pressing the FAB button. * */ onPress?: () => void; /** * This function is called on pressing the FAB backdrop. * */ onBackdropPress?: () => void; /** * Specify if the FAB button is in active state and the action group is shown. * */ active?: boolean; /** * Title of the floating action button */ fabTitle?: string; /** * Icon name of the floating action button */ fabIcon?: IconName; /** * Additional style. */ style?: StyleProp; /** * Action items of the action group. * */ items?: Array; /** * Testing id of the component. */ testID?: string; /** * Supported orientations for the ActionGroup modal, iOS only. */ supportedOrientations?: ('portrait' | 'landscape')[]; } const ActionGroup = forwardRef( ( { headerTitle, onPress, active, style, items, testID, fabTitle, onBackdropPress, fabIcon = 'add', supportedOrientations = ['portrait'], }, ref ) => { useDeprecation( `FAB.ActionGroup's headerTitle prop will be removed in the next major release. Please remove it.`, headerTitle !== undefined ); const fabRef = useRef(null); const animatedValue = useRef( new Animated.Value(active ? 1 : 0) ); React.useImperativeHandle( ref, () => ({ showFAB: () => fabRef.current?.show(), collapseFAB: () => fabRef.current?.collapse(), hideFAB: () => fabRef.current?.hide(), }), [fabRef] ); React.useEffect(() => { Animated.spring(animatedValue.current, { toValue: active ? 1 : 0, useNativeDriver: Platform.OS !== 'web', }).start(); if (active) { fabRef.current?.collapse(true, () => { fabRef.current?.hide(false); }); } else { fabRef.current?.collapse(false); fabRef.current?.show(); } }, [active]); const actionGroupOpacity = animatedValue.current.interpolate({ inputRange: [0, 1], outputRange: [0, 1], }); return ( {active && ( )} {items?.map((itemProp, index) => ( ))} {active && ( )} ); } ); ActionGroup.displayName = 'FAB.ActionGroup'; export default ActionGroup;