software-mansion / react-native-svg

SVG library for React Native, React Native Web, and plain React web projects.
MIT License
7.51k stars 1.13k forks source link

Text element onLayout gives wrong dimensions on iOS with New Achitecture RN 0.76 #2544

Open esbenvb opened 4 days ago

esbenvb commented 4 days ago

Description

I use the <Text> element and add an onLayout callback, and get a width which is the entire available space, not the dimensions of the text itself.

With new architecture - reports wrong width

Screenshot 2024-11-19 at 19 45 41

Without new architecture - reports correct width

image

Steps to reproduce

Clone the repo, or try yourself with this code:

import React, {FC, useCallback, useState} from 'react';
import {G, Text, Rect} from 'react-native-svg';
import {LayoutChangeEvent} from 'react-native';

export const separatorLineLabelHeight = 20;
export const separatorLineLabelBorderWidth = 2;

export type Props = {
  color: string;
  label: string;
  labelColor: string;
};
const MyLabel: FC<Props> = ({color, label, labelColor}) => {
  const horizontalLabelPadding = 12;

  const [textWidth, setTextWidth] = useState(0);
  const handleTextLayout = useCallback((event: LayoutChangeEvent) => {
    const {layout} = event.nativeEvent;
    setTextWidth(layout.width);
  }, []);
return (
  <G y={-separatorLineLabelHeight / 2}>
    <Rect
          height={separatorLineLabelHeight}
          width={textWidth + horizontalLabelPadding * 2}
          strokeWidth={separatorLineLabelBorderWidth}
          stroke={color}
          fill={color === labelColor ? '#FFFFFF' : color}
          ry={separatorLineLabelHeight / 2}
          rx={separatorLineLabelHeight / 2}
        />
     <Text
          x={0}
          textAnchor={'start'}
          y={0}
          fontFamily="Chivo"
          fontSize={13}
          fill={labelColor}
          strokeWidth="0"
          fontWeight="400"
          onLayout={handleTextLayout}>
         {label}
    </Text>
  </G>
)

Snack or a link to a repository

https://github.com/esbenvb/rn-font-weight-issue

SVG version

15.9.0.

React Native version

0.76.2

Platforms

iOS

JavaScript runtime

Hermes

Workflow

React Native

Architecture

Fabric (New Architecture)

Build type

Debug app & dev bundle

Device

iOS simulator

Device model

No response

Acknowledgements

Yes

cheolhow commented 4 days ago

I had the same problem on React Native New Architecture iOS. Measuring a <Text/> in the onLayout event returned the <Svg/> size, not the <Text/> size, and the onLayout event never fired again.

cheolhow commented 4 days ago
<View
  style={{
    width: textSize ? textSize.width : 0,
    height: textSize.height ? textSize.height : 0,
    opacity: textSize ? 1 : 0,
    borderWidth: 4,
    borderColor: red,
  }}
  ...
>
  <Svg width="150" height="14">
    <Text
      dx={1 + 10}
      dy={10}
      fontSize={12}
      fontWeight="800"
      fontFamily="Onest-SemiBold"
      textAnchor="start"
      stroke="rgba(0, 0, 0, 1)"
      strokeWidth={2}
      strokeOpacity={0.75}
      onLayout={(e) => {
        // same e.nativeEvent.layout
        e.target.measure((x, y, width, height) => {
          setTextSize({ width, height });
        });
      }}
    >
      {props.text}
    </Text>
    ...
  </Svg>
</View>

width: 150, height: 0

esbenvb commented 4 hours ago
      onLayout={(e) => {
        // same e.nativeEvent.layout
        e.target.measure((x, y, width, height) => {
          setTextSize({ width, height });
        });
      }}

Same result, I get the width of the container here instead of the Text element