import { useMemo, ReactNode, forwardRef } from 'react' import { Pressable } from 'react-native' import type { View } from 'react-native' import { useSharedValue, runOnJS, useDerivedValue, } from 'react-native-reanimated' import { View as MotiView } from '../../components/view' import { MotiPressableContext, useMotiPressableContext, INTERACTION_CONTAINER_ID, } from './context' import { Hoverable } from './hoverable' import type { MotiPressableInteractionState, MotiPressableProps } from './types' export const MotiPressable = forwardRef( function MotiPressable(props, ref) { const { animate, from, exit, children, exitTransition, transition: transitionProp, style, onPressOut, onPressIn, onHoverIn, onHoverOut, onKeyDown, onKeyUp, onPress, onLongPress, hitSlop, disabled, containerStyle, dangerouslySilenceDuplicateIdsWarning = false, id, hoveredValue, pressedValue, onLayout, onContainerLayout, // Accessibility props accessibilityActions, accessibilityElementsHidden, accessibilityHint, accessibilityIgnoresInvertColors, accessibilityLabel, accessibilityLiveRegion, accessibilityRole, accessibilityState, accessibilityValue, accessibilityViewIsModal, accessible, onAccessibilityTap, onAccessibilityAction, onAccessibilityEscape, importantForAccessibility, onFocus, onBlur, href, testID, } = props const _hovered = useSharedValue(false) const _pressed = useSharedValue(false) const hovered = hoveredValue || _hovered const pressed = pressedValue || _pressed const interaction = useDerivedValue( () => ({ hovered: hovered.value, pressed: pressed.value, }), [hovered, pressed] ) const transition = useDerivedValue(() => { if (typeof transitionProp === 'function') { return transitionProp(interaction.value) } return transitionProp || {} }, [transitionProp, interaction]) const __state = useDerivedValue(() => { if (typeof animate === 'function') { return animate(interaction.value) } return animate }, [animate, interaction]) const state = useMemo(() => ({ __state }), [__state]) const updateInteraction = ( event: keyof MotiPressableInteractionState, enabled: boolean, callback?: () => void ) => () => { 'worklet' if (event === 'hovered') { hovered.value = enabled } else if (event === 'pressed') { pressed.value = enabled } if (callback) { runOnJS(callback)() } } const child = ( { // 'worklet' // if (typeof animate === 'function') { // return animate(interaction.value) // } // return animate // }, [])} style={style} onLayout={onLayout} > {/* @ts-ignore */} {typeof children == 'function' ? children(interaction) : children} ) let node: ReactNode // if (Platform.OS === 'web' || Platform.OS === 'android') { node = ( {child} ) // } // else { // node = ( // // {child} // // ) // } const context = useMotiPressableContext() if ( !dangerouslySilenceDuplicateIdsWarning && id && context?.containers && id in context.containers ) { console.error( `[MotiPressable] Duplicate id ${id} used. This means that you incorrectly placed a component inside another one with the same id. To silence this warning without solving the actual issue, you can use the dangerouslySilenceDuplicateIdsWarning prop. But you should probably refactor your code instead.` ) } return ( { const interactions = { containers: { ...context?.containers, [INTERACTION_CONTAINER_ID]: interaction, }, } if (id) { interactions.containers[id] = interaction } return interactions }, [context?.containers, id, interaction])} > {node} ) } )