import React from 'react'; import { Platform, Pressable as ReactNativePressable, type PressableStateCallbackType, } from 'react-native'; import { useResponsiveRuntime } from '../../../../core/responsive'; import { resolveFocusRingStyles, resolveInteractiveState } from '../../../../internal/resolvers'; import type { InteractionState, PressableProps } from '../../../../types/pressable'; import { resolveViewStyles } from '../../../../utils/resolveViewStyles'; import { useTheme } from '../../../theme/runtime'; /*** Renders the token-aware Surface adapter for React Native Pressable. */ export function Pressable({ children, disabled = false, interactionPolicy = 'enabled', onPress, onLongPress, accessibilityLabel, accessibilityRole = 'button', accessibilityState, style, testID, ...props }: PressableProps) { const { theme } = useTheme(); const { breakpoint } = useResponsiveRuntime(); const [hovered, setHovered] = React.useState(false); const [focused, setFocused] = React.useState(false); const isWeb = Platform.OS === 'web'; const resolvedViewStyles = resolveViewStyles(theme, breakpoint, props); const pressHandlers = resolvePressHandlers(interactionPolicy, onPress, onLongPress); return ( setFocused(false)} onFocus={() => { if (isWeb) setFocused(true); }} onHoverIn={isWeb ? () => setHovered(true) : undefined} onHoverOut={isWeb ? () => setHovered(false) : undefined} style={(pressableState) => { const state = resolveInteractionState(pressableState, hovered, focused, disabled); return [ resolvedViewStyles, resolveFocusRingStyles(theme.semantics.border.focus, state.focused, isWeb), style, ]; }} testID={testID} > {(pressableState) => { const state = resolveInteractionState(pressableState, hovered, focused, disabled); return typeof children === 'function' ? children(state) : children; }} ); } /*** Resolves press handlers according to the shared interaction policy. */ function resolvePressHandlers( interactionPolicy: PressableProps['interactionPolicy'], onPress: PressableProps['onPress'], onLongPress: PressableProps['onLongPress'], ) { return interactionPolicy === 'passive' ? { onLongPress: undefined, onPress: undefined } : { onLongPress, onPress }; } /*** Resolves one native Pressable state into the canonical Surface interaction state. */ function resolveInteractionState( pressableState: PressableStateCallbackType, hovered: boolean, focused: boolean, disabled: boolean, ): InteractionState { return resolveInteractiveState({ pressed: pressableState.pressed, hovered, focused, disabled, }); }