Skip to content

[docs-infra] StackBlitz WebContainer demos #45924

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 19 commits into from
Apr 22, 2025
12 changes: 6 additions & 6 deletions docs/src/modules/sandbox/CodeSandbox.test.js
Original file line number Diff line number Diff line change
@@ -72,7 +72,7 @@ describe('CodeSandbox', () => {
</head>
<body>
<div id="root"></div>
</body>
\n </body>
</html>`,
},
'src/Demo.js': {
@@ -129,12 +129,12 @@ ReactDOM.createRoot(document.querySelector("#root")).render(
'react-dom': 'latest',
'@emotion/react': 'latest',
'@emotion/styled': 'latest',
'@types/react': 'latest',
'@types/react-dom': 'latest',
typescript: 'latest',
},
devDependencies: {
'react-scripts': 'latest',
'@types/react': 'latest',
'@types/react-dom': 'latest',
},
main: 'index.tsx',
scripts: {
@@ -167,7 +167,7 @@ ReactDOM.createRoot(document.querySelector("#root")).render(
</head>
<body>
<div id="root"></div>
</body>
\n </body>
</html>`,
},
'src/Demo.tsx': {
@@ -234,14 +234,14 @@ ReactDOM.createRoot(document.querySelector("#root")!).render(
'@emotion/styled': 'latest',
// #npm-tag-reference
'@mui/material': 'latest',
'@types/react': 'latest',
'@types/react-dom': 'latest',
react: 'latest',
'react-dom': 'latest',
typescript: 'latest',
});
expect(result.devDependencies).to.deep.equal({
'react-scripts': 'latest',
'@types/react': 'latest',
'@types/react-dom': 'latest',
});
});

7 changes: 7 additions & 0 deletions docs/src/modules/sandbox/CodeSandbox.ts
Original file line number Diff line number Diff line change
@@ -7,6 +7,10 @@ import getFileExtension from 'docs/src/modules/sandbox/FileExtension';
import flattenRelativeImports from 'docs/src/modules/sandbox/FlattenRelativeImports';
import { DemoData, CodeVariant, CodeStyling } from 'docs/src/modules/sandbox/types';

const CSB_DEV_DEPENDENCIES = {
'react-scripts': 'latest',
};

function compress(object: any) {
return LZString.compressToBase64(JSON.stringify(object))
.replace(/\+/g, '-') // Convert '+' to '-'
@@ -71,6 +75,7 @@ function createReactApp(demoData: DemoData) {

const { dependencies, devDependencies } = SandboxDependencies(demoData, {
commitRef: process.env.PULL_REQUEST_ID ? process.env.COMMIT_REF : undefined,
devDeps: CSB_DEV_DEPENDENCIES,
});

files['package.json'] = {
@@ -165,6 +170,7 @@ ReactDOM.createRoot(document.querySelector("#root")${type}).render(
},
{
commitRef: process.env.PULL_REQUEST_ID ? process.env.COMMIT_REF : undefined,
devDeps: CSB_DEV_DEPENDENCIES,
},
);

@@ -254,6 +260,7 @@ ReactDOM.createRoot(document.querySelector("#root")${type}).render(
},
{
commitRef: process.env.PULL_REQUEST_ID ? process.env.COMMIT_REF : undefined,
devDeps: CSB_DEV_DEPENDENCIES,
},
);

3 changes: 3 additions & 0 deletions docs/src/modules/sandbox/CreateReactApp.ts
Original file line number Diff line number Diff line change
@@ -5,11 +5,13 @@ export const getHtml = ({
language,
codeStyling,
raw,
main,
}: {
title: string;
language: string;
codeStyling?: 'Tailwind' | 'MUI System';
raw?: string;
main?: string;
}) => {
return `<!DOCTYPE html>
<html lang="${language}">
@@ -84,6 +86,7 @@ export const getHtml = ({
</head>
<body>
<div id="root"></div>
${main ? `<script type="module" src="${main}"></script>` : ''}
</body>
</html>`;
};
16 changes: 10 additions & 6 deletions docs/src/modules/sandbox/Dependencies.test.js
Original file line number Diff line number Diff line change
@@ -138,7 +138,7 @@ import 'exceljs';
});

it('can collect required @types packages', () => {
const { dependencies } = SandboxDependencies({
const { dependencies, devDependencies } = SandboxDependencies({
raw: s1,
codeVariant: 'TS',
});
@@ -153,16 +153,19 @@ import 'exceljs';
// #npm-tag-reference
'@mui/material': 'latest',
'@mui/base': 'latest',
typescript: 'latest',
});

expect(devDependencies).to.deep.equal({
'@types/foo-bar__bip': 'latest',
'@types/prop-types': 'latest',
'@types/react-dom': 'latest',
'@types/react': 'latest',
typescript: 'latest',
});
});

it('should handle @types correctly', () => {
const { dependencies } = SandboxDependencies({
const { dependencies, devDependencies } = SandboxDependencies({
raw: `import utils from '../utils';`,
codeVariant: 'TS',
});
@@ -174,9 +177,12 @@ import 'exceljs';
'@emotion/styled': 'latest',
// #npm-tag-reference
'@mui/material': 'latest',
typescript: 'latest',
});

expect(devDependencies).to.deep.equal({
'@types/react-dom': 'latest',
'@types/react': 'latest',
typescript: 'latest',
});
});

@@ -533,8 +539,6 @@ export default function EmailExample() {
'@mui/joy': 'latest',
'@mui/material': 'latest',
'@mui/system': 'latest',
'@types/react': 'latest',
'@types/react-dom': 'latest',
typescript: 'latest',
});
});
25 changes: 13 additions & 12 deletions docs/src/modules/sandbox/Dependencies.ts
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ const muiNpmOrgs = ['@mui', '@base_ui', '@pigment-css', '@toolpad'];
*
* @param deps - list of dependency as `name => version`
*/
function addTypeDeps(deps: Record<string, string>): void {
function addTypeDeps(deps: Record<string, string>, devDeps: Record<string, string>): void {
const packagesWithDTPackage = Object.keys(deps)
.filter((name) => !packagesWithBundledTypes.includes(name))
// All the MUI packages come with bundled types
@@ -33,14 +33,17 @@ function addTypeDeps(deps: Record<string, string>): void {
resolvedName = name.slice(1).replace('/', '__');
}

deps[`@types/${resolvedName}`] = 'latest';
devDeps[`@types/${resolvedName}`] = 'latest';
});
}

type Demo = Pick<DemoData, 'productId' | 'raw' | 'codeVariant' | 'relativeModules'>;

export default function SandboxDependencies(demo: Demo, options?: { commitRef?: string }) {
const { commitRef } = options || {};
export default function SandboxDependencies(
demo: Demo,
options?: { commitRef?: string; devDeps?: Record<string, string> },
) {
const { commitRef, devDeps = {} } = options || {};

/**
* @param packageName - The name of a package living inside this repository.
@@ -149,11 +152,6 @@ export default function SandboxDependencies(demo: Demo, options?: { commitRef?:

const dependencies = extractDependencies();

if (demo.codeVariant === CODE_VARIANTS.TS) {
addTypeDeps(dependencies);
dependencies.typescript = 'latest';
}

if (!demo.productId && !dependencies['@mui/material']) {
// The `index.js` imports StyledEngineProvider from '@mui/material', so we need to make sure we have it as a dependency
const name = '@mui/material';
@@ -163,9 +161,12 @@ export default function SandboxDependencies(demo: Demo, options?: { commitRef?:
dependencies[name] = versions[name] ? versions[name] : 'latest';
}

const devDependencies = {
'react-scripts': 'latest',
};
const devDependencies: Record<string, string> = { ...devDeps };

if (demo.codeVariant === CODE_VARIANTS.TS) {
addTypeDeps(dependencies, devDependencies);
dependencies.typescript = 'latest';
}

return { dependencies, devDependencies };
}
Loading