diff --git a/packages/react-native-babel-plugin/src/libraries/react-native-svg/index.ts b/packages/react-native-babel-plugin/src/libraries/react-native-svg/index.ts index 325f9f2d9..1d3fed1ab 100644 --- a/packages/react-native-babel-plugin/src/libraries/react-native-svg/index.ts +++ b/packages/react-native-babel-plugin/src/libraries/react-native-svg/index.ts @@ -315,7 +315,6 @@ export class ReactNativeSVG { * width, * height * }} - * style={{ flexShrink: 1 }} * > * {originalElement} * @@ -345,18 +344,6 @@ export class ReactNativeSVG { __wrappedForSR: true }; - const styleProp = t.jsxAttribute( - t.jsxIdentifier('style'), - t.jsxExpressionContainer( - t.objectExpression([ - t.objectProperty( - t.identifier('flexShrink'), - t.numericLiteral(1) - ) - ]) - ) - ); - const props = [ t.objectProperty(t.identifier('type'), t.stringLiteral('svg')), t.objectProperty(t.identifier('hash'), t.stringLiteral(hash)) @@ -394,8 +381,7 @@ export class ReactNativeSVG { t.jsxIdentifier('pointerEvents'), t.stringLiteral('box-none') ), - attributeProp, - styleProp + attributeProp ]; const viewWrapper = t.jsxElement( diff --git a/packages/react-native-babel-plugin/test/__snapshots__/react-native-svg.test.ts.snap b/packages/react-native-babel-plugin/test/__snapshots__/react-native-svg.test.ts.snap new file mode 100644 index 000000000..51f0db13d --- /dev/null +++ b/packages/react-native-babel-plugin/test/__snapshots__/react-native-svg.test.ts.snap @@ -0,0 +1,43 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`SessionReplayView.Privacy SVG Wrapper should wrap an SVG without explicit dimensions 1`] = ` +"import { SessionReplayView } from "@datadog/mobile-react-native-session-replay"; +/*#__PURE__*/React.createElement(SessionReplayView.Privacy, { + nativeID: "00000000-0000-0000-0000-000000000000", + collapsable: false, + pointerEvents: "box-none", + attributes: { + type: "svg", + hash: "fd87d9136a0280917b215dfeeef27092" + } +}, /*#__PURE__*/React.createElement(Svg, { + viewBox: "0 0 100 100" +}, /*#__PURE__*/React.createElement(Circle, { + cx: "50", + cy: "50", + r: "40", + fill: "blue" +})));" +`; + +exports[`SessionReplayView.Privacy SVG Wrapper should wrap an inline SVG with the correct props 1`] = ` +"import { SessionReplayView } from "@datadog/mobile-react-native-session-replay"; +globalThis.__DD_RN_BABEL_PLUGIN_ENABLED__ = true; +/*#__PURE__*/React.createElement(SessionReplayView.Privacy, { + nativeID: "00000000-0000-0000-0000-000000000000", + collapsable: false, + pointerEvents: "box-none", + attributes: { + type: "svg", + hash: "5682723a5f88d4aa4e8c946f82eef34b", + width: "24", + height: "24" + } +}, /*#__PURE__*/React.createElement(Svg, { + width: "24", + height: "24" +}, /*#__PURE__*/React.createElement(Path, { + d: "M12 2L2 12h10z", + fill: "black" +})));" +`; diff --git a/packages/react-native-babel-plugin/test/react-native-svg.test.ts b/packages/react-native-babel-plugin/test/react-native-svg.test.ts index c57542a82..5427e9d76 100644 --- a/packages/react-native-babel-plugin/test/react-native-svg.test.ts +++ b/packages/react-native-babel-plugin/test/react-native-svg.test.ts @@ -5,11 +5,17 @@ */ /* eslint quotes: ["off"] */ +import { transform } from '@babel/core'; import * as parser from '@babel/parser'; import traverse from '@babel/traverse'; import * as t from '@babel/types'; +import fs from 'fs'; +import os from 'os'; +import path from 'path'; +import plugin from '../src/index'; import { RNSvgHandler } from '../src/libraries/react-native-svg/handlers/RNSvgHandler'; +import { ReactNativeSVG } from '../src/libraries/react-native-svg'; /** * Helper function to test SVG transformation @@ -23,12 +29,12 @@ function transformSvg(code: string): string | undefined { let result: string | undefined; traverse(ast, { - JSXElement(path) { - if (t.isJSXIdentifier(path.node.openingElement.name)) { - const name = path.node.openingElement.name.name; + JSXElement(nodePath) { + if (t.isJSXIdentifier(nodePath.node.openingElement.name)) { + const name = nodePath.node.openingElement.name.name; if (name === 'Svg') { const dimensions: Record = {}; - const handler = new RNSvgHandler(t, path, name); + const handler = new RNSvgHandler(t, nodePath, name); result = handler.transformSvgNode(dimensions); } } @@ -756,3 +762,68 @@ describe('React Native SVG Processing - RNSvgHandler', () => { }); }); }); + +jest.mock('uuid', () => ({ + v4: () => '00000000-0000-0000-0000-000000000000' +})); + +/** + * Helper to run the full babel plugin with SVG tracking enabled. + * Returns the transformed code string. + */ +function transformWithSvgTracking(code: string): string | undefined { + const tmpDir = path.join(os.tmpdir(), 'dd-svg-test-assets'); + const reactNativeSVG = new ReactNativeSVG(process.cwd(), tmpDir); + + return transform(code, { + filename: 'file.tsx', + presets: ['@babel/preset-react', '@babel/preset-typescript'], + plugins: [ + [ + plugin, + { + sessionReplay: { svgTracking: true }, + __internal_reactNativeSVG: reactNativeSVG + } + ] + ], + configFile: false + })?.code as string | undefined; +} + +describe('SessionReplayView.Privacy SVG Wrapper', () => { + const tmpDir = path.join(os.tmpdir(), 'dd-svg-test-assets'); + + afterAll(() => { + try { + fs.rmSync(tmpDir, { recursive: true, force: true }); + } catch { + /* ignore cleanup errors */ + } + }); + + it('should wrap an inline SVG with the correct props', () => { + const input = + ''; + const output = transformWithSvgTracking(input); + + expect(output).toMatchSnapshot(); + }); + + it('should wrap an SVG without explicit dimensions', () => { + const input = + ''; + const output = transformWithSvgTracking(input); + + expect(output).toMatchSnapshot(); + }); + + it('should not set a style prop on the wrapper', () => { + const input = + ''; + const output = transformWithSvgTracking(input); + + expect(output).not.toContain('flexShrink'); + expect(output).not.toContain('style'); + }); +});