react-native-svg: pointerEvents="none" doesn't work for all SVG elements, weird behaviour for the SVG elements touch accessibility

Bug

Scenario 1: pointerEvents="none" doesn’t work with react-native-svg SVG elements. For example, when we have rectangle on top of all elements and want to disable touchable behaviour for it to get an access to inner SVG elements we can’t click on any SVG element, because Rectangle still blocks clicks.

Scenario 2: For example, we are trying to find a workaround for Scenario 1 to run touch events on elements under the top SVG Rectangle, and we just drow 4 Lines to emulate Rectangle. Lines should not block click events, as it is not a complete shape. But 4 Lines still block clicks. Even if we draw 2 Lines (top and right side) we can’t click on SVG element on the top-right area on this SVG element. Looks like 2 Lines block click events on top-right triangle area.

I’m using PanResponder, not just simple onPress events. Both issues are available on iOS/Android. pointerEvents=“box-none” doesn’t work toо and even throws an exception.

Unexpected behavior

react-native init CleanProject
cd CleanProject/
yarn add react-native-svg
cd ios && pod install && cd ..
modify App.js -> run the app

Use this code in App.js:

Scenario 1 with simple onPress callbacks:

    <G>
      <G>
        <Image
          onPress={() => { alert('<Image> onPress'); }}
          x={50}
          y={50}
          width={400}
          height={400}
          href={{ uri: 'https://interactive-examples.mdn.mozilla.net/media/examples/grapefruit-slice-332-332.jpg' }}/>
      </G>
      <G pointerEvents="none">
        <Rect
          pointerEvents="none"
          onPress={() => { alert('<Rect> onPress'); }}
          x={0}
          y={0}
          width={500}
          height={500}
          strokeWidth={10}
          stroke="#ccc"
          fill="transparent"/>
      </G>
    </G>

Scenario 1 with PanResponser callbacks:

  <G>
      <G>
        <Image
          onStartShouldSetResponder={() => true}
          onMoveShouldSetResponder={() => true}
          onMoveShouldSetPanResponderCapture={() => true}
          onStartShouldSetPanResponderCapture={() => true}
          onResponderGrant={() => alert('<Image> Grant')}
          onResponderMove={() => alert('<Image> Move')}
          x={50}
          y={50}
          width={400}
          height={400}
          href={{ uri: 'https://interactive-examples.mdn.mozilla.net/media/examples/grapefruit-slice-332-332.jpg' }}/>
      </G>
      <G pointerEvents="none">
        <Rect
          pointerEvents="none"
          onStartShouldSetResponder={() => false}
          onMoveShouldSetResponder={() => false}
          onResponderGrant={() => alert('<Rect> Grant')}
          onResponderMove={() => alert('<Rect> Move')}
          x={0}
          y={0}
          width={500}
          height={500}
          strokeWidth={10}
          stroke="#ccc"
          fill="transparent"/>
      </G>
    </G>

Scenario 2: (Only bottom-left triangle area on Image is clickable)

   <G>
      <G>
        <Image
          onStartShouldSetResponder={() => true}
          onMoveShouldSetResponder={() => true}
          onMoveShouldSetPanResponderCapture={() => true}
          onStartShouldSetPanResponderCapture={() => true}
          onResponderGrant={() => alert('<Image> Grant')}
          onResponderMove={() => alert('<Image> Move')}
          x={50}
          y={50}
          width={400}
          height={400}
          href={{ uri: 'https://interactive-examples.mdn.mozilla.net/media/examples/grapefruit-slice-332-332.jpg' }}/>
      </G>
      <G pointerEvents="none">
        <Line
          pointerEvents="none"
          x1={0}
          y1={0}
          x2={500}
          y2={0}
          strokeWidth={10}
          stroke="#ccc"/>
        <Line
          pointerEvents="none"
          x1={500}
          y1={0}
          x2={500}
          y2={500}
          strokeWidth={10}
          stroke="#ccc"/>
      </G>
    </G>

Environment info

React native info output:

System:
    OS: macOS 10.15.3
    CPU: (8) x64 Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
    Memory: 1.57 GB / 16.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 12.14.1 - /usr/local/bin/node
    Yarn: 1.21.1 - /usr/local/bin/yarn
    npm: 6.13.4 - /usr/local/bin/npm
    Watchman: 4.9.0 - /usr/local/bin/watchman
  SDKs:
    iOS SDK:
      Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
    Android SDK:
      API Levels: 23, 25, 26, 27, 28
      Build Tools: 27.0.3, 28.0.3
      System Images: android-24 | Google Play Intel x86 Atom, android-25 | Google APIs Intel x86 Atom, android-26 | Google APIs Intel x86 Atom, android-27 | Google APIs Intel x86 Atom, android-27 | Google Play Intel x86 Atom, android-28 | Google APIs Intel x86 Atom, android-28 | Google Play Intel x86 Atom, android-29 | Google APIs Intel x86 Atom
  IDEs:
    Android Studio: 3.5 AI-191.8026.42.35.6010548
    Xcode: 11.3.1/11C504 - /usr/bin/xcodebuild
  npmPackages:
    @react-native-community/cli: 3.0.4 => 3.0.4 
    react: 16.9.0 => 16.9.0 
    react-native: 0.61.5 => 0.61.5 
  npmGlobalPackages:
    react-native-cli: 2.0.1

Library version: 11.0.1

Steps To Reproduce

  1. Click on image on all scenarios.

Describe what you expected to happen:

  1. Image should be clickable in all scenarios with simple onPress or PanResponder callbacks.

@msand Could you please check this issue? I know that pointerEvents issues were added and closed many times, but this is the very important feature on complex SVG panes with dynamic touch interactions with PanResponder mechanism. We have 6 places in our project with workarounds for broken pointerEvents, but now for current case we can’t do anything else. Thanks a lot.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 12
  • Comments: 20

Commits related to this issue

Most upvoted comments

🎉 This issue has been resolved in version 12.0.3 🎉

The release is available on:

Your semantic-release bot 📦🚀

@msand I have checked latest develop code. I’m using PanResponder events system and there is no changes when I apply pointerEvents=“none” or “box-none” on iOS. Just we don’t have error now that “box-none” value us not supported. But <Rect>, <Path>, <G> elements still clickable and blocks clicks on SVG elements on lower layer.

On Android application is crashing when I try to load use pointerEvents property

Is this library still maintained? Looks like no…