Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,73 @@
:::info
**Versions compatibility**: To ensure compatibility, it's essential to align the major version of `@mui/styled-engine-sc` with that of the `styled-components` package you're using. For instance, if you opt for `styled-components` version 5, it's necessary to use `@mui/styled-engine-sc` version 5. Similarly, if your preference is `styled-components` version 6, you'll need to upgrade `@mui/styled-engine-sc` to its version 6, which is currently in an alpha state.
:::

## Vite/Vitest configuration

When using Material-UI with styled-components and Vite/Vitest, you may encounter ESM/CJS compatibility issues. Here are the recommended configurations:

### Option 1: Using fallbackCJS (Recommended)

Add the following to your `vite.config.ts`:

```ts title="vite.config.ts"
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
test: {
environment: 'jsdom',
globals: true,
server: {
deps: {
fallbackCJS: true,
},
},
},
plugins: [react()],
});
```

### Option 2: Using inline dependencies

Alternatively, you can inline the MUI packages:

Check warning on line 127 in docs/data/material/integrations/styled-components/styled-components.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [MUI.NoCompanyName] We avoid referencing the company name 'MUI packages'. Instead you can reference a product or the team. Raw Output: {"message": "[MUI.NoCompanyName] We avoid referencing the company name 'MUI packages'. Instead you can reference a product or the team.", "location": {"path": "docs/data/material/integrations/styled-components/styled-components.md", "range": {"start": {"line": 127, "column": 35}}}, "severity": "WARNING"}

```ts title="vite.config.ts"
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
test: {
environment: 'jsdom',
globals: true,
server: {
deps: {
inline: [
'@mui/material',
'@mui/system',
'@mui/styled-engine',
'@mui/icons-material',
// Add other MUI packages you're using
'@mui/x-date-pickers',
],
},
},
},
plugins: [react()],
});
```

### Package.json configuration

When using Vite, you must also override the styled-engine in your `package.json`:

```json title="package.json"
{
"dependencies": {
"@mui/styled-engine": "npm:@mui/styled-engine-sc@latest"
},
"resolutions": {
"@mui/styled-engine": "npm:@mui/styled-engine-sc@latest"
}
}
```
24 changes: 24 additions & 0 deletions packages/mui-styled-engine-sc/package.test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "@mui/styled-engine-sc-vite-test",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"test": "vitest",
"test:ui": "vitest --ui",
"test:coverage": "vitest --coverage"
},
"dependencies": {
"@mui/styled-engine-sc": "workspace:*",
"styled-components": "^6.0.0"
},
"devDependencies": {
"@vitejs/plugin-react": "^4.0.0",
"@vitest/ui": "^1.0.0",
"vitest": "^1.0.0",
"jsdom": "^23.0.0"
},
"overrides": {
"@mui/styled-engine": "npm:@mui/styled-engine-sc@latest"
}
}
3 changes: 1 addition & 2 deletions packages/mui-styled-engine-sc/src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import scStyled from 'styled-components';

import { styled as scStyled } from 'styled-components';
export default function styled(tag, options) {
let stylesFactory;

Expand Down
91 changes: 91 additions & 0 deletions packages/mui-styled-engine-sc/src/vite-vitest.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import * as React from 'react';
import { expect } from 'chai';
import { createRenderer } from '@mui/internal-test-utils';
import styled from '@mui/styled-engine-sc';

describe('Vite/Vitest compatibility', () => {
const { render } = createRenderer();

it('should work with named import from styled-components (Vite/Vitest fix)', () => {
// This test verifies that the fix for Vite/Vitest compatibility works
// The issue was that styled-components v6+ changed to named exports
// but mui-styled-engine-sc was using default import
const StyledComponent = styled('div')({
color: 'red',
padding: '10px',
});

const { container } = render(<StyledComponent>Test Content</StyledComponent>);

expect(container.firstChild).not.to.equal(null);
expect(container.firstChild.tagName).to.equal('DIV');
expect(container.firstChild.textContent).to.equal('Test Content');
});

it('should work with complex styled components in Vite/Vitest', () => {
const ComplexStyledComponent = styled('button')(({ theme }) => ({
backgroundColor: 'blue',
color: 'white',
padding: '8px 16px',
border: 'none',
borderRadius: '4px',
cursor: 'pointer',
'&:hover': {
backgroundColor: 'darkblue',
},
}));

const { container } = render(<ComplexStyledComponent>Click me</ComplexStyledComponent>);

expect(container.firstChild).not.to.equal(null);
expect(container.firstChild.tagName).to.equal('BUTTON');
expect(container.firstChild.textContent).to.equal('Click me');
});

it('should handle styled-components options correctly in Vite/Vitest', () => {
const StyledWithOptions = styled('span', {
shouldForwardProp: (prop) => prop !== 'customColor',
label: 'ViteTestComponent',
})(({ customColor }) => ({
color: customColor || 'black',
}));

const { container } = render(<StyledWithOptions customColor="blue">Styled Text</StyledWithOptions>);

expect(container.firstChild).not.to.equal(null);
expect(container.firstChild.tagName).to.equal('SPAN');
expect(container.firstChild.textContent).to.equal('Styled Text');
// The customColor prop should not be forwarded to the DOM
expect(container.firstChild).not.to.have.attribute('customColor');
});

it('should support ThemeContext from styled-components in Vite/Vitest', async () => {
const { ThemeContext } = await import('@mui/styled-engine-sc');
expect(ThemeContext).not.to.equal(undefined);
expect(typeof ThemeContext).to.equal('object');
});

it('should support keyframes from styled-components in Vite/Vitest', async () => {
const { keyframes } = await import('@mui/styled-engine-sc');
expect(keyframes).not.to.equal(undefined);
expect(typeof keyframes).to.equal('function');

const animation = keyframes`
from { opacity: 0; }
to { opacity: 1; }
`;
expect(animation).not.to.equal(undefined);
});

it('should support css from styled-components in Vite/Vitest', async () => {
const { css } = await import('@mui/styled-engine-sc');
expect(css).not.to.equal(undefined);
expect(typeof css).to.equal('function');

const styles = css`
color: red;
padding: 10px;
`;
expect(styles).not.to.equal(undefined);
});
});
32 changes: 32 additions & 0 deletions packages/mui-styled-engine-sc/vite.config.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

// Vite configuration for testing MUI styled-components compatibility
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
globals: true,
// Test both with and without fallbackCJS to ensure the fix works
server: {
deps: {
// Uncomment to test with fallbackCJS (should work with both)
// fallbackCJS: true,

// Alternative: inline MUI packages (should work with both)
// inline: [
// '@mui/material',
// '@mui/system',
// '@mui/styled-engine',
// '@mui/styled-engine-sc',
// ],
},
},
},
resolve: {
alias: {
// Ensure we're using the styled-engine-sc version
'@mui/styled-engine': '@mui/styled-engine-sc',
},
},
});
Loading