import React, { useRef } from 'react'; import type { ViewStyle } from 'react-native'; import { Animated, Platform, StyleSheet } from 'react-native'; import GestureHandlerButton from '../../components/GestureHandlerButton'; import { getTVProps } from '../../components/utils'; import createNativeWrapper from '../createNativeWrapper'; import type { NativeHandlerData } from '../hooks/gestures/native/NativeTypes'; import type { GestureEndEvent, GestureEvent } from '../types'; import type { BaseButtonProps, BorderlessButtonProps, RawButtonProps, RectButtonProps, } from './GestureButtonsProps'; type CallbackEventType = GestureEvent; type EndCallbackEventType = GestureEndEvent; type RawButtonInnerProps = RawButtonProps & { needsOffscreenAlphaCompositing?: boolean | undefined; }; const RawButtonInner = createNativeWrapper< React.ComponentRef, RawButtonInnerProps >(GestureHandlerButton as React.ComponentType, { shouldCancelWhenOutside: false, shouldActivateOnStart: false, }); /** * @deprecated `RawButton` is deprecated, use `Touchable` instead */ export const RawButton = (props: RawButtonProps) => ( ); /** * @deprecated `BaseButton` is deprecated, use `Touchable` instead */ export const BaseButton = (props: BaseButtonProps) => { const longPressDetected = useRef(false); const longPressTimeout = useRef | undefined>( undefined ); const delayLongPress = props.delayLongPress ?? 600; const { onLongPress, onPress, onActiveStateChange, ...rest } = props; const wrappedLongPress = () => { longPressDetected.current = true; onLongPress?.(); }; const onBegin = (e: CallbackEventType) => { if (!e.pointerInside) { return; } onActiveStateChange?.(true); longPressDetected.current = false; if (onLongPress) { longPressTimeout.current = setTimeout(wrappedLongPress, delayLongPress); } props.onBegin?.(e); }; const onActivate = (e: CallbackEventType) => { if (!e.pointerInside && longPressTimeout.current !== undefined) { clearTimeout(longPressTimeout.current); longPressTimeout.current = undefined; } props.onActivate?.(e); }; const onDeactivate = (e: EndCallbackEventType) => { props.onDeactivate?.(e); }; const onFinalize = (e: EndCallbackEventType) => { onActiveStateChange?.(false); if (!e.canceled && !longPressDetected.current) { onPress?.(e.pointerInside); } if (longPressTimeout.current !== undefined) { clearTimeout(longPressTimeout.current); longPressTimeout.current = undefined; } props.onFinalize?.(e); }; const tvProps = getTVProps(rest); return ( ); }; const AnimatedBaseButton = Animated.createAnimatedComponent(BaseButton); const btnStyles = StyleSheet.create({ underlay: { position: 'absolute', left: 0, right: 0, bottom: 0, top: 0, }, }); /** * @deprecated `RectButton` is deprecated, use `Touchable` with `activeUnderlayOpacity={0.7}` instead */ export const RectButton = (props: RectButtonProps) => { const { children, style, activeOpacity = 0.105, underlayColor = 'black', ...rest } = props; const opacity = useRef(new Animated.Value(0)).current; const onActiveStateChange = (active: boolean) => { if (Platform.OS !== 'android') { opacity.setValue(active ? activeOpacity : 0); } props.onActiveStateChange?.(active); }; const resolvedStyle = StyleSheet.flatten(style ?? {}); return ( {children} ); }; /** * @deprecated `BorderlessButton` is deprecated, use `Touchable` with `activeOpacity={0.3}` instead */ export const BorderlessButton = (props: BorderlessButtonProps) => { const activeOpacity = props.activeOpacity ?? 0.3; const opacity = useRef(new Animated.Value(1)).current; const onActiveStateChange = (active: boolean) => { if (Platform.OS === 'ios') { opacity.setValue(active ? activeOpacity : 1); } props.onActiveStateChange?.(active); }; const { children, style, ref, ...rest } = props; return ( {children} ); }; export { default as PureNativeButton } from '../../components/GestureHandlerButton';