From 0e944215b662fa4b6108634aee3455c673909c36 Mon Sep 17 00:00:00 2001 From: Muhammad Suleman <53903082+MuhammadSuleman97@users.noreply.github.com> Date: Sun, 7 Jun 2026 00:33:56 +1000 Subject: [PATCH] fix: apply x/y props on nested Svg elements as translate transform When an Svg is nested inside another Svg, the x and y props were not being applied. On the web, nested SVG elements respect x/y for positioning within their parent SVG. This fix extracts x and y from the Svg element props and converts them to a translate transform that gets merged with any existing transform prop, matching the behavior of standard SVG elements. Fixes #1283 --- src/elements/Svg.tsx | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/elements/Svg.tsx b/src/elements/Svg.tsx index 7ec207c0e..e818106c6 100644 --- a/src/elements/Svg.tsx +++ b/src/elements/Svg.tsx @@ -111,6 +111,8 @@ export default class Svg extends Shape { height, focusable, transform, + x, + y, // Inherited G properties font, @@ -136,6 +138,8 @@ export default class Svg extends Shape { } const props: extractedProps = extracted as extractedProps; + delete (props as Record).x; + delete (props as Record).y; props.focusable = Boolean(focusable) && focusable !== 'false'; const rootStyles: StyleProp[] = [defaultStyle]; @@ -178,13 +182,29 @@ export default class Svg extends Shape { extractResponder(props, props, this as ResponderInstanceProps); const gStyle = Object.assign({}, StyleSheet.flatten(style)); - if (transform) { + if (transform || x != null || y != null) { if (gStyle.transform) { props.transform = gStyle.transform; gStyle.transform = undefined; } // eslint-disable-next-line @typescript-eslint/no-explicit-any - props.transform = extractTransformSvgView(props as any); + const svgTransform = extractTransformSvgView(props as any); + if (x != null || y != null) { + const translateX = x != null ? parseFloat(String(x)) : 0; + const translateY = y != null ? parseFloat(String(y)) : 0; + const translateTransform = [ + { translateX }, + { translateY }, + ]; + props.transform = svgTransform + ? [ + ...(Array.isArray(svgTransform) ? svgTransform : [svgTransform]), + ...translateTransform, + ] + : translateTransform; + } else { + props.transform = svgTransform; + } } const RNSVGSvg = Platform.OS === 'android' ? RNSVGSvgAndroid : RNSVGSvgIOS; @@ -210,10 +230,9 @@ export default class Svg extends Shape { strokeLinecap, strokeLinejoin, strokeMiterlimit, - onLayout, }} /> ); } -} +} \ No newline at end of file