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'}),