react-native-svg icon indicating copy to clipboard operation
react-native-svg copied to clipboard

[BUG] onPress on G only work for first child (Android Only)

Open soroushm opened this issue 5 years ago • 24 comments

the problem is in android onPress on G element working only for first child but in IOS working very well that means in bellow image only for big square top left working Screen Shot 2020-03-24 at 09 47 39

Each square is like this

import * as React from 'react'
import { G, Rect, ClipPath } from 'react-native-svg'
import { View, Platform } from 'react-native'
import { Typography } from 'src/theme'
import { NodeProps } from './NodeProps'
import { NodeState } from './NodeState'

class Node extends React.Component<NodeProps, NodeState> {
  render() {
    const {
      x0,
      x1,
      y0,
      y1,
      xScaleFactor,
      yScaleFactor,
      xScaleFunction,
      yScaleFunction,
      zoomEnabled,
      url,
      treemapId,
      bgColor,
      onClick,
      id,
      label,
      depth,
    } = this.props
    const xTranslated = zoomEnabled === true ? xScaleFunction(x0) : x0
    const yTranslated = zoomEnabled === true ? yScaleFunction(y0) : y0
    const width = xScaleFactor * (x1 - x0)
    const height = yScaleFactor * (y1 - y0)
    const fSize = width < 60 ? 6.5 : width < 80 ? 8 : width < 120 ? 10 : 12
    if (depth === 0) {
      return null
    }
    const pointerEvents = Platform.OS === 'android' ? { pointerEvents: 'box-none' } : null
    return (
      <G
        // transform={`translate(${xTranslated},${yTranslated})`}
        id={id.toString()}
        x={xTranslated}
        y={yTranslated}
        onPress={(e) => {
          onClick(e, this.props)
        }}
      >
        <Rect id={'rect-' + id} width={width} height={height} rx={2} fill={bgColor} {...pointerEvents} />
        <ClipPath id={'clip-'.concat(treemapId, '-', id.toString())} {...pointerEvents}>
          <Rect width={Math.max(0, width - 5)} height={height} {...pointerEvents} />
        </ClipPath>
        <View
          style={{ width, height, alignContent: 'center', justifyContent: 'center', zIndex: 2, overflow: 'hidden' }}
          {...pointerEvents}
        >
          {width <= 20 ? null : (
            <Typography
              style={{ width, fontSize: fSize }}
              color="initial"
              align={'center'}
              text={label}
              {...pointerEvents}
            />
          )}
        </View>
      </G>
    )
  }
}

export default Node

"react-native-svg": "^11.0.1", "react-native": "0.61.5",

soroushm avatar Mar 24 '20 06:03 soroushm

device info

System:
    OS: macOS 10.15.3
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 998.20 MB / 16.00 GB
    Shell: 5.7.1 - /bin/zsh
  Binaries:
    Node: 12.16.1 - /usr/local/bin/node
    Yarn: 1.19.2 - /usr/local/bin/yarn
    npm: 6.13.7 - /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: 28, 29
      Build Tools: 28.0.3, 29.0.2
      System Images: android-29 | Google Play Intel x86 Atom
  IDEs:
    Android Studio: 3.5 AI-191.8026.42.35.5977832
    Xcode: 11.3/11C29 - /usr/bin/xcodebuild
  npmPackages:
    react: 16.9.0 => 16.9.0 
    react-native: 0.61.5 => 0.61.5 
  npmGlobalPackages:
    create-react-native-web-app: 0.1.14

soroushm avatar Mar 24 '20 08:03 soroushm

@msand give me a favor and take a look at this

soroushm avatar Mar 25 '20 23:03 soroushm

Can you provide a full repro / https://snack.expo.io/ ?

msand avatar Mar 26 '20 00:03 msand

@msand yup sure it's the repo expo example on ios and web working very well also on expo android emulator working fin, but in actual device first one only working (use expo app on android)

soroushm avatar Mar 28 '20 04:03 soroushm

@msand bro can you check it, please

soroushm avatar Mar 29 '20 09:03 soroushm

That's quite a large reproduction, could you make it minimal / as small as possible while still demonstrating the issue? http://sscce.org/

msand avatar Mar 29 '20 10:03 msand

@msand it's a short version 🍡 as possible with treeMap almost 3 components I will cut the treemap and. notify you here

soroushm avatar Mar 29 '20 11:03 soroushm

@msand so i cut the shit out on same snack its pre much react-native-SVG is left still the bug alive and the difference is bug below up and completely onPress networking https://snack.expo.io/@soroush_co/svg-tree thank you so much for the support

soroushm avatar Mar 30 '20 03:03 soroushm

Just to make sure. Have you tried this in a plain react-native project using the latest version of react-native-svg?

msand avatar Mar 30 '20 11:03 msand

@msand yes it's "react-native-svg": "^12.0.3", look like expo haven't latest version

soroushm avatar Apr 04 '20 05:04 soroushm

@msand any update?

soroushm avatar Apr 22 '20 08:04 soroushm

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. You may also mark this issue as a "discussion" and I will leave this open.

stale[bot] avatar Jun 21 '20 08:06 stale[bot]

Hey guys! Could you take a look at this issue?

egorshulga avatar Jul 31 '20 10:07 egorshulga

I can reproduce the same issue on iOS. When G elements are nested onPress is only working on the top level one.

Elijen avatar Sep 15 '20 00:09 Elijen

need someone to take job done! the community needs to grow up, I just migrate to View and Text

soroushm avatar Sep 15 '20 00:09 soroushm

Anyone found a workaround for this? We switched to using SVG to render a complex graphic and this is a release blocker.

@msand do you anticipate having time any time soon to work on this?

georgiosd avatar Sep 29 '20 07:09 georgiosd

@georgiosd Workaround is to not use nested G elements. Instead apply all the props directly to children.

Elijen avatar Sep 29 '20 18:09 Elijen

another instance of the same bug can be found in this one #1460

iAmShakil avatar Oct 03 '20 17:10 iAmShakil

For me worked by wrapping pie chart into Svg tag

mohity777 avatar Mar 11 '21 18:03 mohity777

It seems that viewBox size affects the touchable surface size on some Android devices, even if width and height is '100%'. Essential PH-1 - works, LG G5, Samsung S21. - doesn't (only middle top part of the SVG works) Android Emulator kinda works as the touchable surface is about 90% shorter on width and height in my case (left to right, top to bottom) iOS - works perfectly.

import Svg, { G, Image as SVGImage } from "react-native-svg";
<Svg
        width="100%"
        height="100%"
        viewBox="0 0 10240 7680"
        onPress={() => console.log("SVG press")}
      >
        <G>
          <SVGImage
            x="0"
            y="0"
            width="100%"
            height="100%"
            href={"some image url"}
            onPress={() => console.log("SVGImage press")}
          />
      </G>
</Svg>

SVG press - has no issues with touches on the entire surface. SVGImage press - has issues described above.

Symyon avatar Dec 29 '21 21:12 Symyon

Solution: use onPressIn instead of onPress.

maxoschepkov avatar Feb 01 '23 14:02 maxoschepkov

onPressIn does not work for our use case because the user needs to be able to scroll, and onPressIn fires the event instead of scrolling.

vccoffey avatar May 08 '25 07:05 vccoffey

onPressIn does not work for our use case because the user needs to be able to scroll, and onPressIn fires the event instead of scrolling.

If you need the same onPress behavior, use this:

function usePanResponderOnPress(onPress?: () => void) {
  return useRef(
    PanResponder.create({
      onStartShouldSetPanResponder: () => true,
      onPanResponderRelease: (evt, gestureState) => {
        if (Math.abs(gestureState.dx) < 5 && Math.abs(gestureState.dy) < 5) {
          onPress?.();
        }
      },
    }),
  ).current;
}


function App() {
  const panResponder = usePanResponderOnPress(() => alert("Hello"));

  return (
    <G {...panResponder.panHandlers}>
      {/* ... */}
    </G>
  )
}

rayronvictor avatar Jul 26 '25 03:07 rayronvictor

Hi @soroushm, Thanks for reporting the issue!

I've examined this issue and I've tested it with the snack example provided using react-native versions '0.81.4' and '0.80.0', as well as react-native-svg version '15.13.0' for both. It seems like everything is working fine now and the onPress issue on the G element is not present anymore.

https://github.com/user-attachments/assets/7f84c304-f0fe-4710-8f0a-850544d57307

kacperzolkiewski avatar Sep 25 '25 11:09 kacperzolkiewski