From f2ec8cf22f8cf3416fcae572e2af548634a6d77c Mon Sep 17 00:00:00 2001 From: Zelys Date: Wed, 1 Apr 2026 16:57:30 -0500 Subject: [PATCH] Add transform-box SVG attribute alias and fix mask-type warning alias --- .../src/shared/getAttributeAlias.js | 1 + .../src/shared/possibleStandardNames.js | 3 + .../src/__tests__/ReactDOMComponent-test.js | 65 +++++++++++++++++++ 3 files changed, 69 insertions(+) diff --git a/packages/react-dom-bindings/src/shared/getAttributeAlias.js b/packages/react-dom-bindings/src/shared/getAttributeAlias.js index 31ce02f5d560..2cae4d55b4df 100644 --- a/packages/react-dom-bindings/src/shared/getAttributeAlias.js +++ b/packages/react-dom-bindings/src/shared/getAttributeAlias.js @@ -72,6 +72,7 @@ const aliases = new Map([ ['textAnchor', 'text-anchor'], ['textDecoration', 'text-decoration'], ['textRendering', 'text-rendering'], + ['transformBox', 'transform-box'], ['transformOrigin', 'transform-origin'], ['underlinePosition', 'underline-position'], ['underlineThickness', 'underline-thickness'], diff --git a/packages/react-dom-bindings/src/shared/possibleStandardNames.js b/packages/react-dom-bindings/src/shared/possibleStandardNames.js index b237d116e43e..d484b4614301 100644 --- a/packages/react-dom-bindings/src/shared/possibleStandardNames.js +++ b/packages/react-dom-bindings/src/shared/possibleStandardNames.js @@ -315,6 +315,7 @@ const possibleStandardNames = { mask: 'mask', maskcontentunits: 'maskContentUnits', masktype: 'maskType', + 'mask-type': 'maskType', maskunits: 'maskUnits', mathematical: 'mathematical', mode: 'mode', @@ -426,6 +427,8 @@ const possibleStandardNames = { 'text-rendering': 'textRendering', to: 'to', transform: 'transform', + transformbox: 'transformBox', + 'transform-box': 'transformBox', transformorigin: 'transformOrigin', 'transform-origin': 'transformOrigin', typeof: 'typeof', diff --git a/packages/react-dom/src/__tests__/ReactDOMComponent-test.js b/packages/react-dom/src/__tests__/ReactDOMComponent-test.js index 0f0986dde8e3..7da0092199b5 100644 --- a/packages/react-dom/src/__tests__/ReactDOMComponent-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMComponent-test.js @@ -813,6 +813,54 @@ describe('ReactDOMComponent', () => { expect(node.hasAttribute('arabicForm')).toBe(false); }); + it('should apply React-specific aliases to SVG elements for transformBox', async () => { + const container = document.createElement('div'); + const root = ReactDOMClient.createRoot(container); + await act(() => { + root.render(); + }); + const node = container.firstChild; + // Test attribute initialization. + expect(node.getAttribute('transform-box')).toBe('fill-box'); + expect(node.hasAttribute('transformBox')).toBe(false); + // Test attribute update. + await act(() => { + root.render(); + }); + expect(node.getAttribute('transform-box')).toBe('stroke-box'); + expect(node.hasAttribute('transformBox')).toBe(false); + // Test attribute removal by setting to null. + await act(() => { + root.render(); + }); + expect(node.hasAttribute('transform-box')).toBe(false); + expect(node.hasAttribute('transformBox')).toBe(false); + // Restore. + await act(() => { + root.render(); + }); + expect(node.getAttribute('transform-box')).toBe('fill-box'); + expect(node.hasAttribute('transformBox')).toBe(false); + // Test attribute removal by setting to undefined. + await act(() => { + root.render(); + }); + expect(node.hasAttribute('transform-box')).toBe(false); + expect(node.hasAttribute('transformBox')).toBe(false); + // Restore. + await act(() => { + root.render(); + }); + expect(node.getAttribute('transform-box')).toBe('fill-box'); + expect(node.hasAttribute('transformBox')).toBe(false); + // Test attribute removal. + await act(() => { + root.render(); + }); + expect(node.hasAttribute('transform-box')).toBe(false); + expect(node.hasAttribute('transformBox')).toBe(false); + }); + it('should properly update custom attributes on custom elements', async () => { const container = document.createElement('div'); const root = ReactDOMClient.createRoot(container); @@ -2678,6 +2726,23 @@ describe('ReactDOMComponent', () => { ]); }); + it('should warn about incorrect casing on SVG properties (ssr)', () => { + ReactDOMServer.renderToString( + React.createElement('mask', {'mask-type': 'luminance'}), + ); + assertConsoleErrorDev([ + 'Invalid DOM property `mask-type`. Did you mean `maskType`?\n' + + ' in mask (at **)', + ]); + ReactDOMServer.renderToString( + React.createElement('svg', {'transform-box': 'fill-box'}), + ); + assertConsoleErrorDev([ + 'Invalid DOM property `transform-box`. Did you mean `transformBox`?\n' + + ' in svg (at **)', + ]); + }); + it('should warn about incorrect casing on event handlers (ssr)', () => { ReactDOMServer.renderToString( React.createElement('input', {type: 'text', oninput: '1'}),