diff --git a/docs/data/joy/customization/right-to-left/RtlDemo.js b/docs/data/joy/customization/right-to-left/RtlDemo.js
index 9351c09ae0bc67..5a52b24595b61e 100644
--- a/docs/data/joy/customization/right-to-left/RtlDemo.js
+++ b/docs/data/joy/customization/right-to-left/RtlDemo.js
@@ -1,5 +1,5 @@
import * as React from 'react';
-import rtlPlugin from 'stylis-plugin-rtl';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
import { prefixer } from 'stylis';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
diff --git a/docs/data/joy/customization/right-to-left/RtlDemo.tsx b/docs/data/joy/customization/right-to-left/RtlDemo.tsx
index 9351c09ae0bc67..5a52b24595b61e 100644
--- a/docs/data/joy/customization/right-to-left/RtlDemo.tsx
+++ b/docs/data/joy/customization/right-to-left/RtlDemo.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import rtlPlugin from 'stylis-plugin-rtl';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
import { prefixer } from 'stylis';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
diff --git a/docs/data/joy/customization/right-to-left/RtlOptOut.js b/docs/data/joy/customization/right-to-left/RtlOptOut.js
index bfb37e3009c1c4..fa26a7685c43a0 100644
--- a/docs/data/joy/customization/right-to-left/RtlOptOut.js
+++ b/docs/data/joy/customization/right-to-left/RtlOptOut.js
@@ -1,6 +1,6 @@
import * as React from 'react';
import { prefixer } from 'stylis';
-import rtlPlugin from 'stylis-plugin-rtl';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import { styled } from '@mui/joy/styles';
diff --git a/docs/data/joy/customization/right-to-left/RtlOptOut.tsx b/docs/data/joy/customization/right-to-left/RtlOptOut.tsx
index bfb37e3009c1c4..fa26a7685c43a0 100644
--- a/docs/data/joy/customization/right-to-left/RtlOptOut.tsx
+++ b/docs/data/joy/customization/right-to-left/RtlOptOut.tsx
@@ -1,6 +1,6 @@
import * as React from 'react';
import { prefixer } from 'stylis';
-import rtlPlugin from 'stylis-plugin-rtl';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import { styled } from '@mui/joy/styles';
diff --git a/docs/data/joy/customization/right-to-left/right-to-left.md b/docs/data/joy/customization/right-to-left/right-to-left.md
index 5c2090a0d7fc6b..4a6ce3363be10d 100644
--- a/docs/data/joy/customization/right-to-left/right-to-left.md
+++ b/docs/data/joy/customization/right-to-left/right-to-left.md
@@ -60,33 +60,33 @@ const theme = extendTheme({
### 3. Configure RTL style plugin
-Install the [`stylis-plugin-rtl`](https://github.com/styled-components/stylis-plugin-rtl) using one of the commands below:
+Install the `@mui/stylis-plugin-rtl` using one of the commands below:
```bash npm
-npm install stylis stylis-plugin-rtl
+npm install stylis @mui/stylis-plugin-rtl
```
```bash pnpm
-pnpm add stylis stylis-plugin-rtl
+pnpm add stylis @mui/stylis-plugin-rtl
```
```bash yarn
-yarn add stylis stylis-plugin-rtl
+yarn add stylis @mui/stylis-plugin-rtl
```
#### With Emotion
-If you're using Emotion, use the [CacheProvider](https://emotion.sh/docs/cache-provider) to create a new cache instance that uses `rtlPlugin` from `stylis-plugin-rtl` and add that to the top of your application tree:
+If you're using Emotion, use the [CacheProvider](https://emotion.sh/docs/cache-provider) to create a new cache instance that uses `rtlPlugin` from `@mui/stylis-plugin-rtl` and add that to the top of your application tree:
```jsx
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import { prefixer } from 'stylis';
-import rtlPlugin from 'stylis-plugin-rtl';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
// Create rtl cache
const cacheRtl = createCache({
@@ -105,7 +105,7 @@ If you're using styled-components, use the [StyleSheetManager](https://styled-co
```jsx
import { StyleSheetManager } from 'styled-components';
-import rtlPlugin from 'stylis-plugin-rtl';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
function Rtl(props) {
return (
diff --git a/docs/data/material/customization/right-to-left/RtlDemo.js b/docs/data/material/customization/right-to-left/RtlDemo.js
index 56dc4d2e1d7a12..cc8176da729d72 100644
--- a/docs/data/material/customization/right-to-left/RtlDemo.js
+++ b/docs/data/material/customization/right-to-left/RtlDemo.js
@@ -1,7 +1,7 @@
import * as React from 'react';
import { createTheme, ThemeProvider } from '@mui/material/styles';
import TextField from '@mui/material/TextField';
-import rtlPlugin from 'stylis-plugin-rtl';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
import { prefixer } from 'stylis';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
diff --git a/docs/data/material/customization/right-to-left/RtlDemo.tsx b/docs/data/material/customization/right-to-left/RtlDemo.tsx
index ed38bcc18cdb34..7dfa888606fb1b 100644
--- a/docs/data/material/customization/right-to-left/RtlDemo.tsx
+++ b/docs/data/material/customization/right-to-left/RtlDemo.tsx
@@ -1,7 +1,7 @@
import * as React from 'react';
import { createTheme, ThemeProvider, Theme } from '@mui/material/styles';
import TextField from '@mui/material/TextField';
-import rtlPlugin from 'stylis-plugin-rtl';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
import { prefixer } from 'stylis';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
diff --git a/docs/data/material/customization/right-to-left/RtlOptOut.js b/docs/data/material/customization/right-to-left/RtlOptOut.js
index a97d3ab6a27863..a574ea5b4bab2b 100644
--- a/docs/data/material/customization/right-to-left/RtlOptOut.js
+++ b/docs/data/material/customization/right-to-left/RtlOptOut.js
@@ -1,6 +1,6 @@
import * as React from 'react';
import { prefixer } from 'stylis';
-import rtlPlugin from 'stylis-plugin-rtl';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import { styled } from '@mui/material/styles';
diff --git a/docs/data/material/customization/right-to-left/RtlOptOut.tsx b/docs/data/material/customization/right-to-left/RtlOptOut.tsx
index a97d3ab6a27863..a574ea5b4bab2b 100644
--- a/docs/data/material/customization/right-to-left/RtlOptOut.tsx
+++ b/docs/data/material/customization/right-to-left/RtlOptOut.tsx
@@ -1,6 +1,6 @@
import * as React from 'react';
import { prefixer } from 'stylis';
-import rtlPlugin from 'stylis-plugin-rtl';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import { styled } from '@mui/material/styles';
diff --git a/docs/data/material/customization/right-to-left/right-to-left.md b/docs/data/material/customization/right-to-left/right-to-left.md
index 4669ea35b7342b..9ce718716aa7ff 100644
--- a/docs/data/material/customization/right-to-left/right-to-left.md
+++ b/docs/data/material/customization/right-to-left/right-to-left.md
@@ -60,33 +60,33 @@ const theme = createTheme({
### 3. Configure RTL style plugin
-Install the [`stylis-plugin-rtl`](https://github.com/styled-components/stylis-plugin-rtl) using one of the commands below:
+Install the `@mui/stylis-plugin-rtl` using one of the commands below:
```bash npm
-npm install stylis stylis-plugin-rtl
+npm install stylis @mui/stylis-plugin-rtl
```
```bash pnpm
-pnpm add stylis stylis-plugin-rtl
+pnpm add stylis @mui/stylis-plugin-rtl
```
```bash yarn
-yarn add stylis stylis-plugin-rtl
+yarn add stylis @mui/stylis-plugin-rtl
```
#### With Emotion
-If you're using Emotion, use the [CacheProvider](https://emotion.sh/docs/cache-provider) to create a new cache instance that uses `rtlPlugin` from `stylis-plugin-rtl` and add that to the top of your application tree:
+If you're using Emotion, use the [CacheProvider](https://emotion.sh/docs/cache-provider) to create a new cache instance that uses `rtlPlugin` from `@mui/stylis-plugin-rtl` and add that to the top of your application tree:
```jsx
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import { prefixer } from 'stylis';
-import rtlPlugin from 'stylis-plugin-rtl';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
// Create rtl cache
const rtlCache = createCache({
@@ -105,7 +105,7 @@ If you're using styled-components, use the [StyleSheetManager](https://styled-co
```jsx
import { StyleSheetManager } from 'styled-components';
-import rtlPlugin from 'stylis-plugin-rtl';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
function Rtl(props) {
return (
diff --git a/docs/package.json b/docs/package.json
index 66767799354bea..4f98637c20bf0b 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -40,6 +40,7 @@
"@mui/system": "workspace:^",
"@mui/types": "workspace:^",
"@mui/utils": "workspace:^",
+ "@mui/stylis-plugin-rtl": "workspace:^",
"@mui/x-charts": "8.3.1",
"@mui/x-data-grid": "8.3.1",
"@mui/x-data-grid-generator": "8.3.1",
@@ -105,7 +106,6 @@
"rimraf": "^6.0.1",
"styled-components": "^6.1.18",
"stylis": "4.2.0",
- "stylis-plugin-rtl": "^2.1.1",
"use-count-up": "^3.0.1",
"webpack-bundle-analyzer": "^4.10.2"
},
diff --git a/docs/src/BrandingCssVarsProvider.tsx b/docs/src/BrandingCssVarsProvider.tsx
index 995747409a2f8c..cb5e731d886cde 100644
--- a/docs/src/BrandingCssVarsProvider.tsx
+++ b/docs/src/BrandingCssVarsProvider.tsx
@@ -150,6 +150,19 @@ export default function BrandingCssVarsProvider(props: {
setDocsColors(nextPaletteColors.primary, nextPaletteColors.secondary);
}
}, []);
+ useEnhancedEffect(() => {
+ // This is required to ensure that the layer order is declared first in the head
+ // because when the direction is RTL on the client, emotion reinserts the RTL styles back to the top of the insertion point.
+ if (direction === 'rtl') {
+ const head = document.querySelector('head');
+ if (head) {
+ const style = document.createElement('style');
+ style.textContent =
+ '@layer theme, docsearch, mui, mui.global, mui.default, mui.theme, mui.custom, mui.sx, utilities;';
+ head.prepend(style);
+ }
+ }
+ }, [direction]);
return (
({
overflowY: 'auto',
paddingTop: theme.spacing(4),
paddingBottom: theme.spacing(7),
- paddingRight: theme.spacing(4), // We can't use `padding` as stylis-plugin-rtl doesn't swap it
+ paddingRight: theme.spacing(4), // We can't use `padding` as @mui/stylis-plugin-rtl doesn't swap it
display: 'none',
scrollbarWidth: 'thin',
[theme.breakpoints.up('md')]: {
diff --git a/docs/src/modules/components/DemoSandbox.js b/docs/src/modules/components/DemoSandbox.js
index 074c6a2643f035..179a87c9f74ce3 100644
--- a/docs/src/modules/components/DemoSandbox.js
+++ b/docs/src/modules/components/DemoSandbox.js
@@ -2,7 +2,7 @@ import * as React from 'react';
import * as ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import { prefixer } from 'stylis';
-import rtlPlugin from 'stylis-plugin-rtl';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
import createCache from '@emotion/cache';
import { CacheProvider } from '@emotion/react';
import { StyleSheetManager } from 'styled-components';
diff --git a/docs/src/modules/utils/StyledEngineProvider.js b/docs/src/modules/utils/StyledEngineProvider.js
index 2026843c6712db..24f7b11831a81a 100644
--- a/docs/src/modules/utils/StyledEngineProvider.js
+++ b/docs/src/modules/utils/StyledEngineProvider.js
@@ -4,7 +4,7 @@ import { StyleSheetManager } from 'styled-components';
import { CacheProvider } from '@emotion/react';
import { createEmotionCache as createCache } from '@mui/material-nextjs/v15-pagesRouter';
import { prefixer } from 'stylis';
-import rtlPlugin from 'stylis-plugin-rtl';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
import GlobalStyles from '@mui/material/GlobalStyles';
import { ThemeOptionsContext } from 'docs/src/modules/components/ThemeContext';
import globalSelector from './globalSelector';
diff --git a/packages/mui-stylis-plugin-rtl/README.md b/packages/mui-stylis-plugin-rtl/README.md
new file mode 100644
index 00000000000000..508c6a28c1155f
--- /dev/null
+++ b/packages/mui-stylis-plugin-rtl/README.md
@@ -0,0 +1,51 @@
+# @mui/stylis-plugin-rtl
+
+Stylis RTL plugin for Material UI.
+
+> Note: this is a fork of [stylis-plugin-rtl](https://github.com/styled-components/stylis-plugin-rtl) to fix issues with CSS layers and to support the latest version of Stylis.
+
+## Installation
+
+```bash
+npm install @mui/stylis-plugin-rtl @emotion/cache stylis
+```
+
+## Usage
+
+```js
+import * as React from 'react';
+import { createTheme, ThemeProvider } from '@mui/material/styles';
+import TextField from '@mui/material/TextField';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
+import { prefixer } from 'stylis';
+import { CacheProvider } from '@emotion/react';
+import createCache from '@emotion/cache';
+
+const theme = createTheme({
+ direction: 'rtl',
+});
+
+const cacheRtl = createCache({
+ key: 'muirtl',
+ stylisPlugins: [prefixer, rtlPlugin],
+});
+
+export default function RtlDemo() {
+ return (
+
+
+
+
+
+
+
+ );
+}
+```
+
+For more information, see the [RTL documentation](https://mui.com/material-ui/guides/right-to-left/).
diff --git a/packages/mui-stylis-plugin-rtl/package.json b/packages/mui-stylis-plugin-rtl/package.json
new file mode 100644
index 00000000000000..dd67326e6d2910
--- /dev/null
+++ b/packages/mui-stylis-plugin-rtl/package.json
@@ -0,0 +1,65 @@
+{
+ "name": "@mui/stylis-plugin-rtl",
+ "version": "7.1.0",
+ "author": "MUI Team",
+ "description": "A plugin for Material UI that provides RTL (right-to-left) support.",
+ "main": "./src/index.ts",
+ "keywords": [
+ "react",
+ "react-component",
+ "mui",
+ "rtl"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/mui/material-ui.git",
+ "directory": "packages/mui-stylis-plugin-rtl"
+ },
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/mui/material-ui/issues"
+ },
+ "homepage": "https://github.com/mui/material-ui/tree/master/packages/mui-utils",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mui-org"
+ },
+ "scripts": {
+ "build": "pnpm build:node && pnpm build:stable && pnpm build:types && pnpm build:copy-files",
+ "build:node": "node ../../scripts/build.mjs node",
+ "build:stable": "node ../../scripts/build.mjs stable",
+ "build:copy-files": "node ../../scripts/copyFiles.mjs",
+ "build:types": "tsx ../../scripts/buildTypes.mts",
+ "prebuild": "rimraf build tsconfig.build.tsbuildinfo",
+ "release": "pnpm build && pnpm publish",
+ "test": "cd ../../ && cross-env NODE_ENV=test mocha 'packages/mui-utils/**/*.test.?(c|m)[jt]s?(x)'",
+ "typescript": "tsc -p tsconfig.json",
+ "attw": "attw --pack ./build --exclude-entrypoints esm modern"
+ },
+ "dependencies": {
+ "@babel/runtime": "^7.27.1",
+ "cssjanus": "^2.0.1"
+ },
+ "devDependencies": {
+ "@mui/internal-test-utils": "workspace:^",
+ "@types/chai": "^4.3.20",
+ "@types/mocha": "^10.0.10",
+ "@types/node": "^20.17.50",
+ "@types/sinon": "^17.0.4",
+ "@types/stylis": "4.2.7",
+ "chai": "^4.5.0",
+ "sinon": "^19.0.5",
+ "stylis": "4.3.6"
+ },
+ "peerDependencies": {
+ "stylis": "4.x"
+ },
+ "sideEffects": false,
+ "publishConfig": {
+ "access": "public",
+ "directory": "build"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+}
diff --git a/packages/mui-stylis-plugin-rtl/src/index.test.ts b/packages/mui-stylis-plugin-rtl/src/index.test.ts
new file mode 100644
index 00000000000000..5b5858feb8aa11
--- /dev/null
+++ b/packages/mui-stylis-plugin-rtl/src/index.test.ts
@@ -0,0 +1,173 @@
+import { expect } from 'chai';
+import { compile, Middleware, middleware, prefixer, serialize, stringify } from 'stylis';
+import muiRtlPlugin from '@mui/stylis-plugin-rtl';
+
+const stylis = (css: string, extraPlugins: Middleware[] = []) =>
+ serialize(compile(css), middleware([...extraPlugins, muiRtlPlugin, stringify]));
+
+describe('integration test with stylis', () => {
+ it('flips simple rules', () => {
+ expect(
+ stylis(
+ `.a {
+ padding-left: 5px;
+ margin-right: 5px;
+ border-left: 1px solid red;
+ }
+ `,
+ ),
+ ).to.equal(`.a{padding-right:5px;margin-left:5px;border-right:1px solid red;}`);
+ });
+
+ it('flips shorthands', () => {
+ expect(
+ stylis(
+ `.a {
+ padding: 0 5px 0 0;
+ margin: 0 0 0 5px;
+ }
+ `,
+ ),
+ ).to.equal(`.a{padding:0 0 0 5px;margin:0 5px 0 0;}`);
+ });
+
+ it('handles noflip directives', () => {
+ expect(
+ stylis(
+ `
+ .a {
+ /* @noflip */
+ padding: 0 5px 0 0;
+ margin: 0 0 0 5px;
+ }
+ `,
+ ),
+ ).to.equal(`.a{padding:0 5px 0 0;margin:0 5px 0 0;}`);
+ });
+
+ it('flips keyframes', () => {
+ expect(
+ stylis(
+ `@keyframes a {
+ 0% { left: 0px; }
+ 100% { left: 100px; }
+ }
+ `,
+ ),
+ ).to.equal(`@keyframes a{0%{right:0px;}100%{right:100px;}}`);
+ });
+
+ it('flips media queries', () => {
+ expect(
+ stylis(
+ `@media (min-width: 500px) {
+ .a {
+ padding-left: 5px;
+ margin-right: 5px;
+ border-left: 1px solid red;
+ }
+ }
+ `,
+ ),
+ ).to.equal(
+ `@media (min-width: 500px){.a{padding-right:5px;margin-left:5px;border-right:1px solid red;}}`,
+ );
+ });
+
+ it('flips supports queries', () => {
+ expect(
+ stylis(
+ `@supports (display: flex) {
+ .a {
+ padding-left: 5px;
+ margin-right: 5px;
+ border-left: 1px solid red;
+ }
+ }
+ `,
+ ),
+ ).to.equal(
+ `@supports (display: flex){.a{padding-right:5px;margin-left:5px;border-right:1px solid red;}}`,
+ );
+ });
+
+ it('works in tandem with prefixer', () => {
+ expect(
+ stylis(
+ `@keyframes a {
+ 0% { left: 0px; }
+ 100% { left: 100px; }
+ }
+ `,
+ [prefixer],
+ ),
+ ).to.equal(
+ `@-webkit-keyframes a{0%{right:0px;}100%{right:100px;}}@keyframes a{0%{right:0px;}100%{right:100px;}}`,
+ );
+ });
+
+ it("doesn't crash on empty rules", () => {
+ // this generates nodes for:
+ // .cls{}
+ // .cls .nested{color:hotpink;}
+ expect(
+ stylis(`
+ .cls {
+ & .nested {
+ color:hotpink;
+ }
+ }
+ `),
+ ).to.equal(`.cls .nested{color:hotpink;}`);
+ });
+
+ it('works for nested rules', () => {
+ expect(
+ stylis(`
+ .cls {
+ margin-right: 32px;
+ & .first-child {
+ margin-right: 32px;
+ }
+ }
+ `),
+ ).to.equal(`.cls{margin-left:32px;}.cls .first-child{margin-left:32px;}`);
+ });
+
+ it('works for layer rules', () => {
+ expect(
+ stylis(`
+ @layer default {
+ .cls {
+ margin-right: 32px;
+ & .first-child {
+ margin-right: 32px;
+ }
+ }
+ }
+ `),
+ ).to.equal(`@layer default{.cls{margin-left:32px;}.cls .first-child{margin-left:32px;}}`);
+ });
+
+ it('works for nested layer rules', () => {
+ expect(
+ stylis(`
+ @layer root {
+ .foo {
+ margin-right: 32px;
+ }
+ @layer default {
+ .cls {
+ margin-right: 32px;
+ & .first-child {
+ margin-right: 32px;
+ }
+ }
+ }
+ }
+ `),
+ ).to.equal(
+ `@layer root{.foo{margin-left:32px;}@layer default{.cls{margin-left:32px;}.cls .first-child{margin-left:32px;}}}`,
+ );
+ });
+});
diff --git a/packages/mui-stylis-plugin-rtl/src/index.ts b/packages/mui-stylis-plugin-rtl/src/index.ts
new file mode 100644
index 00000000000000..5cad0ad98878f7
--- /dev/null
+++ b/packages/mui-stylis-plugin-rtl/src/index.ts
@@ -0,0 +1,85 @@
+/* eslint-disable default-case, no-return-assign, curly, prefer-template, @typescript-eslint/no-unused-vars */
+
+/**
+ * Copied from https://github.com/styled-components/stylis-plugin-rtl/blob/main/src/stylis-rtl.ts
+ * with a modification at line 67 to handle layer rules.
+ */
+
+// @ts-nocheck
+import cssjanus from 'cssjanus';
+import {
+ COMMENT,
+ compile,
+ DECLARATION,
+ IMPORT,
+ RULESET,
+ serialize,
+ strlen,
+ Middleware,
+ KEYFRAMES,
+ MEDIA,
+ SUPPORTS,
+ LAYER,
+} from 'stylis';
+
+type MiddlewareParams = Parameters;
+
+function stringifyPreserveComments(
+ element: MiddlewareParams[0],
+ index: MiddlewareParams[1],
+ children: MiddlewareParams[2],
+): string {
+ switch (element.type) {
+ case IMPORT:
+ case DECLARATION:
+ case COMMENT:
+ return (element.return = element.return || element.value);
+ case RULESET: {
+ element.value = Array.isArray(element.props) ? element.props.join(',') : element.props;
+
+ if (Array.isArray(element.children)) {
+ element.children.forEach((x) => {
+ if (x.type === COMMENT) x.children = x.value;
+ });
+ }
+ }
+ }
+
+ const serializedChildren = serialize(
+ Array.prototype.concat(element.children),
+ stringifyPreserveComments,
+ );
+
+ return strlen(serializedChildren)
+ ? (element.return = element.value + '{' + serializedChildren + '}')
+ : '';
+}
+
+function stylisRTLPlugin(
+ element: MiddlewareParams[0],
+ index: MiddlewareParams[1],
+ children: MiddlewareParams[2],
+ callback: MiddlewareParams[3],
+): string | void {
+ if (
+ element.type === KEYFRAMES ||
+ element.type === SUPPORTS ||
+ (element.type === RULESET &&
+ (!element.parent ||
+ element.parent.type === MEDIA ||
+ element.parent.type === RULESET ||
+ element.parent.type === LAYER))
+ ) {
+ const stringified = cssjanus.transform(stringifyPreserveComments(element, index, children));
+
+ element.children = stringified ? compile(stringified)[0].children : [];
+
+ element.return = '';
+ }
+}
+
+// stable identifier that will not be dropped by minification unless the whole module
+// is unused
+Object.defineProperty(stylisRTLPlugin, 'name', { value: 'stylisRTLPlugin' });
+
+export default stylisRTLPlugin;
diff --git a/packages/mui-stylis-plugin-rtl/tsconfig.build.json b/packages/mui-stylis-plugin-rtl/tsconfig.build.json
new file mode 100644
index 00000000000000..26edb3c2b1ea91
--- /dev/null
+++ b/packages/mui-stylis-plugin-rtl/tsconfig.build.json
@@ -0,0 +1,16 @@
+{
+ // This config is for emitting declarations (.d.ts) only
+ // Actual .ts source files are transpiled via babel
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "composite": true,
+ "declaration": true,
+ "noEmit": false,
+ "emitDeclarationOnly": true,
+ "outDir": "build/esm",
+ "rootDir": "./src",
+ "types": ["react", "node"]
+ },
+ "include": ["src/**/*.ts"],
+ "exclude": ["src/**/*.test.ts*", "src/**/*.spec.ts*"]
+}
diff --git a/packages/mui-stylis-plugin-rtl/tsconfig.json b/packages/mui-stylis-plugin-rtl/tsconfig.json
new file mode 100644
index 00000000000000..7775630eb4802c
--- /dev/null
+++ b/packages/mui-stylis-plugin-rtl/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "extends": "../../tsconfig.json",
+ "compilerOptions": {
+ "allowJs": false,
+ "types": ["react", "mocha", "node"]
+ },
+ "include": ["src/**/*"]
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 00c1f696b2a8df..d4bd5395d0fc9c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -396,7 +396,7 @@ importers:
version: link:../../packages/mui-utils/build
next:
specifier: latest
- version: 15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ version: 15.3.3(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
react:
specifier: ^19.1.0
version: 19.1.0
@@ -406,7 +406,7 @@ importers:
devDependencies:
'@pigment-css/nextjs-plugin':
specifier: 0.0.30
- version: 0.0.30(@types/react@19.1.6)(next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(webpack-sources@3.2.3)
+ version: 0.0.30(@types/react@19.1.6)(next@15.3.3(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(webpack-sources@3.2.3)
'@types/node':
specifier: ^20.17.50
version: 20.17.50
@@ -451,7 +451,7 @@ importers:
version: link:../../packages/mui-utils/build
next:
specifier: latest
- version: 15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ version: 15.3.3(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
react:
specifier: ^19.1.0
version: 19.1.0
@@ -461,7 +461,7 @@ importers:
devDependencies:
'@pigment-css/nextjs-plugin':
specifier: 0.0.30
- version: 0.0.30(@types/react@19.1.6)(next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(webpack-sources@3.2.3)
+ version: 0.0.30(@types/react@19.1.6)(next@15.3.3(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(webpack-sources@3.2.3)
'@types/node':
specifier: ^20.17.50
version: 20.17.50
@@ -622,6 +622,9 @@ importers:
'@mui/styled-engine-sc':
specifier: workspace:^
version: link:../packages/mui-styled-engine-sc/build
+ '@mui/stylis-plugin-rtl':
+ specifier: workspace:^
+ version: link:../packages/mui-stylis-plugin-rtl/build
'@mui/system':
specifier: workspace:^
version: link:../packages/mui-system/build
@@ -669,7 +672,7 @@ importers:
version: 4.1.7
'@toolpad/core':
specifier: ^0.15.0
- version: 0.15.0(@emotion/cache@11.14.0)(@emotion/react@11.13.5(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(@mui/icons-material@packages+mui-icons-material+build)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@19.1.6)(date-fns@2.30.0)(luxon@3.6.1)(next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react-router@7.5.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(vite@6.0.15(@types/node@20.17.50)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(tsx@4.19.4)(yaml@2.7.1))
+ version: 0.15.0(@emotion/cache@11.14.0)(@emotion/react@11.13.5(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(@mui/icons-material@packages+mui-icons-material+build)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@19.1.6)(date-fns@2.30.0)(luxon@3.6.1)(next@15.3.3(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react-router@7.5.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(vite@6.0.15(@types/node@20.17.50)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(tsx@4.19.4)(yaml@2.7.1))
autoprefixer:
specifier: ^10.4.21
version: 10.4.21(postcss@8.5.3)
@@ -753,7 +756,7 @@ importers:
version: 5.3.6(@mui/material@packages+mui-material+build)(@types/react@19.1.6)(react@19.1.0)
next:
specifier: ^15.3.2
- version: 15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ version: 15.3.3(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
notistack:
specifier: 3.0.2
version: 3.0.2(csstype@3.1.3)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
@@ -826,9 +829,6 @@ importers:
stylis:
specifier: 4.2.0
version: 4.2.0
- stylis-plugin-rtl:
- specifier: ^2.1.1
- version: 2.1.1(stylis@4.2.0)
use-count-up:
specifier: ^3.0.1
version: 3.0.1(react@19.1.0)
@@ -904,7 +904,7 @@ importers:
version: 1.8.8
'@types/stylis':
specifier: ^4.2.0
- version: 4.2.5
+ version: 4.2.7
chai:
specifier: ^4.5.0
version: 4.5.0
@@ -1371,7 +1371,7 @@ importers:
version: 19.1.6
next:
specifier: ^15.3.2
- version: 15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ version: 15.3.3(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
react:
specifier: ^19.1.0
version: 19.1.0
@@ -1545,7 +1545,7 @@ importers:
version: 4.17.21
next:
specifier: ^15.3.2
- version: 15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ version: 15.3.3(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
react:
specifier: ^19.1.0
version: 19.1.0
@@ -1743,7 +1743,7 @@ importers:
version: 19.1.6
next:
specifier: ^15.3.2
- version: 15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ version: 15.3.3(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
react:
specifier: ^19.1.0
version: 19.1.0
@@ -1879,6 +1879,44 @@ importers:
version: 6.1.18(patch_hash=383c648dfdb5dfc82fbe414d54027d8c982a01c6320370f0ecfdb387e753c09f)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
publishDirectory: build
+ packages/mui-stylis-plugin-rtl:
+ dependencies:
+ '@babel/runtime':
+ specifier: ^7.27.1
+ version: 7.27.1
+ cssjanus:
+ specifier: ^2.0.1
+ version: 2.1.0
+ devDependencies:
+ '@mui/internal-test-utils':
+ specifier: workspace:^
+ version: link:../../packages-internal/test-utils
+ '@types/chai':
+ specifier: ^4.3.20
+ version: 4.3.20
+ '@types/mocha':
+ specifier: ^10.0.10
+ version: 10.0.10
+ '@types/node':
+ specifier: ^20.17.50
+ version: 20.17.50
+ '@types/sinon':
+ specifier: ^17.0.4
+ version: 17.0.4
+ '@types/stylis':
+ specifier: 4.2.7
+ version: 4.2.7
+ chai:
+ specifier: ^4.5.0
+ version: 4.5.0
+ sinon:
+ specifier: ^19.0.5
+ version: 19.0.5
+ stylis:
+ specifier: 4.3.6
+ version: 4.3.6
+ publishDirectory: build
+
packages/mui-system:
dependencies:
'@babel/runtime':
@@ -2094,6 +2132,9 @@ importers:
'@mui/material':
specifier: workspace:^
version: link:../packages/mui-material/build
+ '@mui/stylis-plugin-rtl':
+ specifier: workspace:^
+ version: link:../packages/mui-stylis-plugin-rtl/build
'@mui/system':
specifier: workspace:^
version: link:../packages/mui-system/build
@@ -2163,9 +2204,6 @@ importers:
stylis:
specifier: 4.2.0
version: 4.2.0
- stylis-plugin-rtl:
- specifier: ^2.1.1
- version: 2.1.1(stylis@4.2.0)
webfontloader:
specifier: ^1.6.28
version: 1.6.28
@@ -4627,56 +4665,56 @@ packages:
engines: {node: '>=18.14.0'}
hasBin: true
- '@next/env@15.3.2':
- resolution: {integrity: sha512-xURk++7P7qR9JG1jJtLzPzf0qEvqCN0A/T3DXf8IPMKo9/6FfjxtEffRJIIew/bIL4T3C2jLLqBor8B/zVlx6g==}
+ '@next/env@15.3.3':
+ resolution: {integrity: sha512-OdiMrzCl2Xi0VTjiQQUK0Xh7bJHnOuET2s+3V+Y40WJBAXrJeGA3f+I8MZJ/YQ3mVGi5XGR1L66oFlgqXhQ4Vw==}
'@next/eslint-plugin-next@15.3.2':
resolution: {integrity: sha512-ijVRTXBgnHT33aWnDtmlG+LJD+5vhc9AKTJPquGG5NKXjpKNjc62woIhFtrAcWdBobt8kqjCoaJ0q6sDQoX7aQ==}
- '@next/swc-darwin-arm64@15.3.2':
- resolution: {integrity: sha512-2DR6kY/OGcokbnCsjHpNeQblqCZ85/1j6njYSkzRdpLn5At7OkSdmk7WyAmB9G0k25+VgqVZ/u356OSoQZ3z0g==}
+ '@next/swc-darwin-arm64@15.3.3':
+ resolution: {integrity: sha512-WRJERLuH+O3oYB4yZNVahSVFmtxRNjNF1I1c34tYMoJb0Pve+7/RaLAJJizyYiFhjYNGHRAE1Ri2Fd23zgDqhg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
- '@next/swc-darwin-x64@15.3.2':
- resolution: {integrity: sha512-ro/fdqaZWL6k1S/5CLv1I0DaZfDVJkWNaUU3un8Lg6m0YENWlDulmIWzV96Iou2wEYyEsZq51mwV8+XQXqMp3w==}
+ '@next/swc-darwin-x64@15.3.3':
+ resolution: {integrity: sha512-XHdzH/yBc55lu78k/XwtuFR/ZXUTcflpRXcsu0nKmF45U96jt1tsOZhVrn5YH+paw66zOANpOnFQ9i6/j+UYvw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
- '@next/swc-linux-arm64-gnu@15.3.2':
- resolution: {integrity: sha512-covwwtZYhlbRWK2HlYX9835qXum4xYZ3E2Mra1mdQ+0ICGoMiw1+nVAn4d9Bo7R3JqSmK1grMq/va+0cdh7bJA==}
+ '@next/swc-linux-arm64-gnu@15.3.3':
+ resolution: {integrity: sha512-VZ3sYL2LXB8znNGcjhocikEkag/8xiLgnvQts41tq6i+wql63SMS1Q6N8RVXHw5pEUjiof+II3HkDd7GFcgkzw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
- '@next/swc-linux-arm64-musl@15.3.2':
- resolution: {integrity: sha512-KQkMEillvlW5Qk5mtGA/3Yz0/tzpNlSw6/3/ttsV1lNtMuOHcGii3zVeXZyi4EJmmLDKYcTcByV2wVsOhDt/zg==}
+ '@next/swc-linux-arm64-musl@15.3.3':
+ resolution: {integrity: sha512-h6Y1fLU4RWAp1HPNJWDYBQ+e3G7sLckyBXhmH9ajn8l/RSMnhbuPBV/fXmy3muMcVwoJdHL+UtzRzs0nXOf9SA==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
- '@next/swc-linux-x64-gnu@15.3.2':
- resolution: {integrity: sha512-uRBo6THWei0chz+Y5j37qzx+BtoDRFIkDzZjlpCItBRXyMPIg079eIkOCl3aqr2tkxL4HFyJ4GHDes7W8HuAUg==}
+ '@next/swc-linux-x64-gnu@15.3.3':
+ resolution: {integrity: sha512-jJ8HRiF3N8Zw6hGlytCj5BiHyG/K+fnTKVDEKvUCyiQ/0r5tgwO7OgaRiOjjRoIx2vwLR+Rz8hQoPrnmFbJdfw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
- '@next/swc-linux-x64-musl@15.3.2':
- resolution: {integrity: sha512-+uxFlPuCNx/T9PdMClOqeE8USKzj8tVz37KflT3Kdbx/LOlZBRI2yxuIcmx1mPNK8DwSOMNCr4ureSet7eyC0w==}
+ '@next/swc-linux-x64-musl@15.3.3':
+ resolution: {integrity: sha512-HrUcTr4N+RgiiGn3jjeT6Oo208UT/7BuTr7K0mdKRBtTbT4v9zJqCDKO97DUqqoBK1qyzP1RwvrWTvU6EPh/Cw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
- '@next/swc-win32-arm64-msvc@15.3.2':
- resolution: {integrity: sha512-LLTKmaI5cfD8dVzh5Vt7+OMo+AIOClEdIU/TSKbXXT2iScUTSxOGoBhfuv+FU8R9MLmrkIL1e2fBMkEEjYAtPQ==}
+ '@next/swc-win32-arm64-msvc@15.3.3':
+ resolution: {integrity: sha512-SxorONgi6K7ZUysMtRF3mIeHC5aA3IQLmKFQzU0OuhuUYwpOBc1ypaLJLP5Bf3M9k53KUUUj4vTPwzGvl/NwlQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
- '@next/swc-win32-x64-msvc@15.3.2':
- resolution: {integrity: sha512-aW5B8wOPioJ4mBdMDXkt5f3j8pUr9W8AnlX0Df35uRWNT1Y6RIybxjnSUe+PhM+M1bwgyY8PHLmXZC6zT1o5tA==}
+ '@next/swc-win32-x64-msvc@15.3.3':
+ resolution: {integrity: sha512-4QZG6F8enl9/S2+yIiOiju0iCTFd93d8VC1q9LZS4p/Xuk81W2QDjCFeoogmrWWkAD59z8ZxepBQap2dKS5ruw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
@@ -5781,6 +5819,9 @@ packages:
'@types/stylis@4.2.5':
resolution: {integrity: sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==}
+ '@types/stylis@4.2.7':
+ resolution: {integrity: sha512-VgDNokpBoKF+wrdvhAAfS55OMQpL6QRglwTwNC3kIgBrzZxA4WsFj+2eLfEA/uMUDzBcEhYmjSbwQakn/i3ajA==}
+
'@types/tough-cookie@4.0.5':
resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==}
@@ -10735,8 +10776,8 @@ packages:
resolution: {integrity: sha512-Nc3loyVASW59W+8fLDZT1lncpG7llffyZ2o0UQLx/Fr20i7P8oP+lE7+TEcFvXj9IUWU6LjB9P3BH+iFGyp+mg==}
engines: {node: ^14.16.0 || >=16.0.0}
- next@15.3.2:
- resolution: {integrity: sha512-CA3BatMyHkxZ48sgOCLdVHjFU36N7TF1HhqAHLFOkV6buwZnvMI84Cug8xD56B9mCuKrqXnLn94417GrZ/jjCQ==}
+ next@15.3.3:
+ resolution: {integrity: sha512-JqNj29hHNmCLtNvd090SyRbXJiivQ+58XjCcrC50Crb5g5u2zi7Y2YivbsEfzk6AtVI80akdOQbaMZwWB1Hthw==}
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
hasBin: true
peerDependencies:
@@ -12852,8 +12893,8 @@ packages:
stylis@4.3.2:
resolution: {integrity: sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==}
- stylis@4.3.4:
- resolution: {integrity: sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==}
+ stylis@4.3.6:
+ resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==}
sucrase@3.35.0:
resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
@@ -16684,34 +16725,34 @@ snapshots:
- rollup
- supports-color
- '@next/env@15.3.2': {}
+ '@next/env@15.3.3': {}
'@next/eslint-plugin-next@15.3.2':
dependencies:
fast-glob: 3.3.1
- '@next/swc-darwin-arm64@15.3.2':
+ '@next/swc-darwin-arm64@15.3.3':
optional: true
- '@next/swc-darwin-x64@15.3.2':
+ '@next/swc-darwin-x64@15.3.3':
optional: true
- '@next/swc-linux-arm64-gnu@15.3.2':
+ '@next/swc-linux-arm64-gnu@15.3.3':
optional: true
- '@next/swc-linux-arm64-musl@15.3.2':
+ '@next/swc-linux-arm64-musl@15.3.3':
optional: true
- '@next/swc-linux-x64-gnu@15.3.2':
+ '@next/swc-linux-x64-gnu@15.3.3':
optional: true
- '@next/swc-linux-x64-musl@15.3.2':
+ '@next/swc-linux-x64-musl@15.3.3':
optional: true
- '@next/swc-win32-arm64-msvc@15.3.2':
+ '@next/swc-win32-arm64-msvc@15.3.3':
optional: true
- '@next/swc-win32-x64-msvc@15.3.2':
+ '@next/swc-win32-x64-msvc@15.3.3':
optional: true
'@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3':
@@ -17044,10 +17085,10 @@ snapshots:
'@opentelemetry/api@1.8.0':
optional: true
- '@pigment-css/nextjs-plugin@0.0.30(@types/react@19.1.6)(next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(webpack-sources@3.2.3)':
+ '@pigment-css/nextjs-plugin@0.0.30(@types/react@19.1.6)(next@15.3.3(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(typescript@5.8.3)(webpack-sources@3.2.3)':
dependencies:
'@pigment-css/unplugin': 0.0.30(@types/react@19.1.6)(react@19.1.0)(typescript@5.8.3)(webpack-sources@3.2.3)
- next: 15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ next: 15.3.3(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
transitivePeerDependencies:
- '@types/react'
- react
@@ -17078,8 +17119,8 @@ snapshots:
lodash: 4.17.21
prop-types: 15.8.1
react: 19.1.0
- stylis: 4.3.4
- stylis-plugin-rtl: 2.1.1(stylis@4.3.4)
+ stylis: 4.3.6
+ stylis-plugin-rtl: 2.1.1(stylis@4.3.6)
transitivePeerDependencies:
- '@types/react'
- supports-color
@@ -17810,7 +17851,7 @@ snapshots:
dependencies:
'@testing-library/dom': 10.4.0
- '@toolpad/core@0.15.0(@emotion/cache@11.14.0)(@emotion/react@11.13.5(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(@mui/icons-material@packages+mui-icons-material+build)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@19.1.6)(date-fns@2.30.0)(luxon@3.6.1)(next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react-router@7.5.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(vite@6.0.15(@types/node@20.17.50)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(tsx@4.19.4)(yaml@2.7.1))':
+ '@toolpad/core@0.15.0(@emotion/cache@11.14.0)(@emotion/react@11.13.5(@types/react@19.1.6)(react@19.1.0))(@emotion/styled@11.13.5(@emotion/react@11.13.5(@types/react@19.1.6)(react@19.1.0))(@types/react@19.1.6)(react@19.1.0))(@mui/icons-material@packages+mui-icons-material+build)(@mui/material@packages+mui-material+build)(@mui/system@packages+mui-system+build)(@types/react@19.1.6)(date-fns@2.30.0)(luxon@3.6.1)(next@15.3.3(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react-router@7.5.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react@19.1.0)(vite@6.0.15(@types/node@20.17.50)(jiti@2.4.2)(lightningcss@1.30.1)(terser@5.39.0)(tsx@4.19.4)(yaml@2.7.1))':
dependencies:
'@babel/runtime': 7.27.1
'@emotion/cache': 11.14.0
@@ -17831,7 +17872,7 @@ snapshots:
react: 19.1.0
react-dom: 19.1.0(react@19.1.0)
optionalDependencies:
- next: 15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ next: 15.3.3(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
react-router: 7.5.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
transitivePeerDependencies:
- '@emotion/styled'
@@ -18127,6 +18168,8 @@ snapshots:
'@types/stylis@4.2.5': {}
+ '@types/stylis@4.2.7': {}
+
'@types/tough-cookie@4.0.5':
optional: true
@@ -18576,7 +18619,7 @@ snapshots:
cosmiconfig: 8.3.6(typescript@5.8.3)
happy-dom: 15.11.6
source-map: 0.7.4
- stylis: 4.3.4
+ stylis: 4.3.6
ts-invariant: 0.10.3
transitivePeerDependencies:
- supports-color
@@ -24391,9 +24434,9 @@ snapshots:
p-wait-for: 5.0.2
qs: 6.13.0
- next@15.3.2(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
+ next@15.3.3(@babel/core@7.27.1)(@opentelemetry/api@1.8.0)(@playwright/test@1.52.0)(babel-plugin-macros@3.1.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
dependencies:
- '@next/env': 15.3.2
+ '@next/env': 15.3.3
'@swc/counter': 0.1.3
'@swc/helpers': 0.5.15
busboy: 1.6.0
@@ -24403,14 +24446,14 @@ snapshots:
react-dom: 19.1.0(react@19.1.0)
styled-jsx: 5.1.6(@babel/core@7.27.1)(babel-plugin-macros@3.1.0)(react@19.1.0)
optionalDependencies:
- '@next/swc-darwin-arm64': 15.3.2
- '@next/swc-darwin-x64': 15.3.2
- '@next/swc-linux-arm64-gnu': 15.3.2
- '@next/swc-linux-arm64-musl': 15.3.2
- '@next/swc-linux-x64-gnu': 15.3.2
- '@next/swc-linux-x64-musl': 15.3.2
- '@next/swc-win32-arm64-msvc': 15.3.2
- '@next/swc-win32-x64-msvc': 15.3.2
+ '@next/swc-darwin-arm64': 15.3.3
+ '@next/swc-darwin-x64': 15.3.3
+ '@next/swc-linux-arm64-gnu': 15.3.3
+ '@next/swc-linux-arm64-musl': 15.3.3
+ '@next/swc-linux-x64-gnu': 15.3.3
+ '@next/swc-linux-x64-musl': 15.3.3
+ '@next/swc-win32-arm64-msvc': 15.3.3
+ '@next/swc-win32-x64-msvc': 15.3.3
'@opentelemetry/api': 1.8.0
'@playwright/test': 1.52.0
sharp: 0.34.1
@@ -26978,21 +27021,16 @@ snapshots:
- supports-color
- typescript
- stylis-plugin-rtl@2.1.1(stylis@4.2.0):
- dependencies:
- cssjanus: 2.1.0
- stylis: 4.2.0
-
- stylis-plugin-rtl@2.1.1(stylis@4.3.4):
+ stylis-plugin-rtl@2.1.1(stylis@4.3.6):
dependencies:
cssjanus: 2.1.0
- stylis: 4.3.4
+ stylis: 4.3.6
stylis@4.2.0: {}
stylis@4.3.2: {}
- stylis@4.3.4: {}
+ stylis@4.3.6: {}
sucrase@3.35.0:
dependencies:
diff --git a/test/package.json b/test/package.json
index 1e1b5bf82d5a1c..2485f893432f6c 100644
--- a/test/package.json
+++ b/test/package.json
@@ -16,6 +16,7 @@
"@mui/material": "workspace:^",
"@mui/system": "workspace:^",
"@mui/utils": "workspace:^",
+ "@mui/stylis-plugin-rtl": "workspace:^",
"@playwright/test": "1.52.0",
"@testing-library/dom": "^10.4.0",
"@types/chai": "^4.3.20",
@@ -37,7 +38,6 @@
"sinon": "^19.0.5",
"styled-components": "^6.1.18",
"stylis": "4.2.0",
- "stylis-plugin-rtl": "^2.1.1",
"webfontloader": "^1.6.28",
"webpack": "^5.99.9",
"yargs": "^17.7.2"
diff --git a/test/regressions/fixtures/Snackbar/PositionedSnackbarRtl.js b/test/regressions/fixtures/Snackbar/PositionedSnackbarRtl.js
index 679c340cd56b16..418ff9081ded05 100644
--- a/test/regressions/fixtures/Snackbar/PositionedSnackbarRtl.js
+++ b/test/regressions/fixtures/Snackbar/PositionedSnackbarRtl.js
@@ -1,7 +1,7 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import { prefixer } from 'stylis';
-import rtlPlugin from 'stylis-plugin-rtl';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
import { StyleSheetManager } from 'styled-components';
import { CacheProvider } from '@emotion/react';
import { createTheme, ThemeProvider } from '@mui/material/styles';
diff --git a/test/regressions/fixtures/Tabs/RTLVerticalTabs.js b/test/regressions/fixtures/Tabs/RTLVerticalTabs.js
index 5676770bcb0b43..dbeda7ce096e53 100644
--- a/test/regressions/fixtures/Tabs/RTLVerticalTabs.js
+++ b/test/regressions/fixtures/Tabs/RTLVerticalTabs.js
@@ -1,6 +1,6 @@
import * as React from 'react';
import { prefixer } from 'stylis';
-import rtlPlugin from 'stylis-plugin-rtl';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import { StyleSheetManager } from 'styled-components';
diff --git a/test/regressions/fixtures/Tooltip/PositionedTooltipsRtl.js b/test/regressions/fixtures/Tooltip/PositionedTooltipsRtl.js
index f3ac6c0424fc16..8fa5f4a0626e3b 100644
--- a/test/regressions/fixtures/Tooltip/PositionedTooltipsRtl.js
+++ b/test/regressions/fixtures/Tooltip/PositionedTooltipsRtl.js
@@ -4,7 +4,7 @@ import Grid from '@mui/material/Grid';
import Button from '@mui/material/Button';
import Tooltip from '@mui/material/Tooltip';
import { prefixer } from 'stylis';
-import rtlPlugin from 'stylis-plugin-rtl';
+import rtlPlugin from '@mui/stylis-plugin-rtl';
import { StyleSheetManager } from 'styled-components';
import { CacheProvider } from '@emotion/react';
import { createTheme, ThemeProvider } from '@mui/material/styles';
diff --git a/test/regressions/vite.config.mts b/test/regressions/vite.config.mts
index 4c3c9e546b046c..73a7f6581ecd98 100644
--- a/test/regressions/vite.config.mts
+++ b/test/regressions/vite.config.mts
@@ -53,6 +53,10 @@ export default defineConfig({
'@mui/utils': path.resolve(WORKSPACE_ROOT, './packages/mui-utils/src'),
'@mui/material-nextjs': path.resolve(WORKSPACE_ROOT, './packages/mui-material-nextjs/src'),
'@mui/joy': path.resolve(WORKSPACE_ROOT, './packages/mui-joy/src'),
+ '@mui/stylis-plugin-rtl': path.resolve(
+ WORKSPACE_ROOT,
+ './packages/mui-stylis-plugin-rtl/src',
+ ),
'@mui/internal-docs-utils': path.resolve(
WORKSPACE_ROOT,
'./packages-internal/docs-utils/src',
diff --git a/tsconfig.json b/tsconfig.json
index dcbd9c147e1f58..676b002f9dbf7b 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -48,6 +48,8 @@
],
"@mui/internal-test-utils": ["./packages-internal/test-utils/src"],
"@mui/internal-test-utils/*": ["./packages-internal/test-utils/src/*"],
+ "@mui/stylis-plugin-rtl": ["./packages/mui-stylis-plugin-rtl/src"],
+ "@mui/stylis-plugin-rtl/*": ["./packages/mui-stylis-plugin-rtl/src/*"],
"docs/*": ["./docs/*"]
},
// Otherwise we get react-native typings which conflict with dom.lib.