@@ -3,6 +3,8 @@ import { findNodeHandle, Platform } from 'react-native';
33
44import { Wrap } from '../../../handlers/gestures/GestureDetector/Wrap' ;
55import { tagMessage } from '../../../utils' ;
6+ import { NATIVE_GESTURE_ROLE_ATTRIBUTE } from '../../../web/constants' ;
7+ import { NativeGestureRole } from '../../../web/interfaces' ;
68import { isComposedGesture } from '../../hooks/utils/relationUtils' ;
79import type { DetectorCallbacks , VirtualChild } from '../../types' ;
810import type { VirtualDetectorProps } from '../common' ;
@@ -36,7 +38,7 @@ export function VirtualDetector<
3638 const { register, unregister, setMode } =
3739 useRequiredInterceptingDetectorContext ( ) ;
3840
39- const viewRef = useRef ( null ) ;
41+ const viewRef = useRef < HTMLElement | null > ( null ) ;
4042 const [ viewTag , setViewTag ] = useState < number > ( - 1 ) ;
4143
4244 const handleRef = useCallback (
@@ -54,6 +56,34 @@ export function VirtualDetector<
5456 [ props . children ]
5557 ) ;
5658
59+ useEffect ( ( ) => {
60+ if ( Platform . OS !== 'web' || ! viewRef . current ) {
61+ return ;
62+ }
63+
64+ // @ts -ignore This exists on React.ReactNode
65+ const displayName = props . children ?. type ?. displayName as string ;
66+ // On web we need to use `firstChild` as `current` will refer to `Wrap`
67+ const element = viewRef . current . firstChild as HTMLElement ;
68+
69+ if ( displayName === 'ScrollView' ) {
70+ element . setAttribute (
71+ NATIVE_GESTURE_ROLE_ATTRIBUTE ,
72+ NativeGestureRole . ScrollView
73+ ) ;
74+ } else if ( displayName === 'Switch' ) {
75+ element . setAttribute (
76+ NATIVE_GESTURE_ROLE_ATTRIBUTE ,
77+ NativeGestureRole . Switch
78+ ) ;
79+ } else if ( displayName === 'Button' ) {
80+ element . setAttribute (
81+ NATIVE_GESTURE_ROLE_ATTRIBUTE ,
82+ NativeGestureRole . Button
83+ ) ;
84+ }
85+ } , [ props . children , viewTag ] ) ;
86+
5787 useEffect ( ( ) => {
5888 if ( viewTag === - 1 ) {
5989 return ;
0 commit comments