diff --git a/docs/data/joy/getting-started/templates/TemplateCollection.js b/docs/data/joy/getting-started/templates/TemplateCollection.js
index 64532dffa42ffd..c772a260b3300b 100644
--- a/docs/data/joy/getting-started/templates/TemplateCollection.js
+++ b/docs/data/joy/getting-started/templates/TemplateCollection.js
@@ -10,11 +10,11 @@ import Link from '@mui/joy/Link';
import List from '@mui/joy/List';
import Button from '@mui/joy/Button';
import Typography from '@mui/joy/Typography';
-import SvgIcon from '@mui/joy/SvgIcon';
import Visibility from '@mui/icons-material/Visibility';
import CodeRoundedIcon from '@mui/icons-material/CodeRounded';
-import codeSandbox from 'docs/src/modules/sandbox/CodeSandbox';
+import stackBlitz from 'docs/src/modules/sandbox/StackBlitz';
import sourceJoyTemplates from 'docs/src/modules/joy/sourceJoyTemplates';
+import SandboxIcon from 'docs/src/modules/components/SandboxIcon';
/**
* To display a template on the site:
@@ -269,17 +269,13 @@ export default function TemplateCollection() {
variant="outlined"
color="neutral"
fullWidth
- startDecorator={
-
-
-
- }
- aria-label="CodeSandbox playground"
+ startDecorator={}
+ aria-label="Open sandbox"
data-ga-event-category="joy-template"
data-ga-event-label={template.name}
- data-ga-event-action="codesandbox"
+ data-ga-event-action="stackblitz"
onClick={() =>
- codeSandbox
+ stackBlitz
.createJoyTemplate({
...item,
title: `${startCase(template.name)} Template - Joy UI`,
@@ -289,11 +285,11 @@ export default function TemplateCollection() {
item.codeVariant === 'TS' ? 'tsx' : 'js'
}`,
})
- .openSandbox()
+ .openStackBlitz()
}
sx={{ fontFamily: 'IBM Plex Sans' }}
>
- CodeSandbox
+ Open sandbox
diff --git a/docs/data/material/getting-started/templates/dashboard/theme/customizations/dataGrid.js b/docs/data/material/getting-started/templates/dashboard/theme/customizations/dataGrid.js
index ed33816d0fc681..b98c96ea81fa7e 100644
--- a/docs/data/material/getting-started/templates/dashboard/theme/customizations/dataGrid.js
+++ b/docs/data/material/getting-started/templates/dashboard/theme/customizations/dataGrid.js
@@ -1,6 +1,5 @@
import { paperClasses } from '@mui/material/Paper';
import { alpha } from '@mui/material/styles';
-
import { menuItemClasses } from '@mui/material/MenuItem';
import { listItemIconClasses } from '@mui/material/ListItemIcon';
import { iconButtonClasses } from '@mui/material/IconButton';
@@ -8,6 +7,7 @@ import { checkboxClasses } from '@mui/material/Checkbox';
import { listClasses } from '@mui/material/List';
import { gridClasses } from '@mui/x-data-grid';
import { tablePaginationClasses } from '@mui/material/TablePagination';
+
import { gray } from '../../../shared-theme/themePrimitives';
/* eslint-disable import/prefer-default-export */
diff --git a/docs/data/material/getting-started/templates/dashboard/theme/customizations/dataGrid.ts b/docs/data/material/getting-started/templates/dashboard/theme/customizations/dataGrid.ts
new file mode 100644
index 00000000000000..13e6b338f583d4
--- /dev/null
+++ b/docs/data/material/getting-started/templates/dashboard/theme/customizations/dataGrid.ts
@@ -0,0 +1,142 @@
+import { paperClasses } from '@mui/material/Paper';
+import { alpha } from '@mui/material/styles';
+import { menuItemClasses } from '@mui/material/MenuItem';
+import { listItemIconClasses } from '@mui/material/ListItemIcon';
+import { iconButtonClasses } from '@mui/material/IconButton';
+import { checkboxClasses } from '@mui/material/Checkbox';
+import { listClasses } from '@mui/material/List';
+import { gridClasses } from '@mui/x-data-grid';
+import { tablePaginationClasses } from '@mui/material/TablePagination';
+import type { ComponentsOverrides, ComponentsProps, Theme } from '@mui/material/styles';
+
+import { gray } from '../../../shared-theme/themePrimitives';
+
+interface DataGridComponents {
+ MuiDataGrid?: {
+ defaultProps?: ComponentsProps['MuiDataGrid'];
+ styleOverrides?: ComponentsOverrides['MuiDataGrid'];
+ };
+}
+
+/* eslint-disable import/prefer-default-export */
+export const dataGridCustomizations: DataGridComponents = {
+ MuiDataGrid: {
+ styleOverrides: {
+ root: ({ theme }) => ({
+ '--DataGrid-overlayHeight': '300px',
+ overflow: 'clip',
+ borderColor: (theme.vars || theme).palette.divider,
+ backgroundColor: (theme.vars || theme).palette.background.default,
+ [`& .${gridClasses.columnHeader}`]: {
+ backgroundColor: (theme.vars || theme).palette.background.paper,
+ },
+ [`& .${gridClasses.footerContainer}`]: {
+ backgroundColor: (theme.vars || theme).palette.background.paper,
+ },
+ [`& .${checkboxClasses.root}`]: {
+ padding: theme.spacing(0.5),
+ '& > svg': {
+ fontSize: '1rem',
+ },
+ },
+ [`& .${tablePaginationClasses.root}`]: {
+ marginRight: theme.spacing(1),
+ '& .MuiIconButton-root': {
+ maxHeight: 32,
+ maxWidth: 32,
+ '& > svg': {
+ fontSize: '1rem',
+ },
+ },
+ },
+ }),
+ cell: ({ theme }) => ({
+ borderTopColor: (theme.vars || theme).palette.divider,
+ }),
+ menu: ({ theme }) => ({
+ borderRadius: theme.shape.borderRadius,
+ backgroundImage: 'none',
+ [`& .${paperClasses.root}`]: {
+ border: `1px solid ${(theme.vars || theme).palette.divider}`,
+ },
+ [`& .${menuItemClasses.root}`]: {
+ margin: '0 4px',
+ },
+ [`& .${listItemIconClasses.root}`]: {
+ marginRight: 0,
+ },
+ [`& .${listClasses.root}`]: {
+ paddingLeft: 0,
+ paddingRight: 0,
+ },
+ }),
+ row: ({ theme }) => ({
+ '&:last-of-type': {
+ borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`,
+ },
+ '&:hover': {
+ backgroundColor: (theme.vars || theme).palette.action.hover,
+ },
+ '&.Mui-selected': {
+ background: (theme.vars || theme).palette.action.selected,
+ '&:hover': {
+ backgroundColor: (theme.vars || theme).palette.action.hover,
+ },
+ },
+ }),
+ iconButtonContainer: ({ theme }) => ({
+ [`& .${iconButtonClasses.root}`]: {
+ border: 'none',
+ backgroundColor: 'transparent',
+ '&:hover': {
+ backgroundColor: alpha(theme.palette.action.selected, 0.3),
+ },
+ '&:active': {
+ backgroundColor: gray[200],
+ },
+ ...theme.applyStyles('dark', {
+ color: gray[50],
+ '&:hover': {
+ backgroundColor: gray[800],
+ },
+ '&:active': {
+ backgroundColor: gray[900],
+ },
+ }),
+ },
+ }),
+ menuIconButton: ({ theme }) => ({
+ border: 'none',
+ backgroundColor: 'transparent',
+ '&:hover': {
+ backgroundColor: gray[100],
+ },
+ '&:active': {
+ backgroundColor: gray[200],
+ },
+ ...theme.applyStyles('dark', {
+ color: gray[50],
+ '&:hover': {
+ backgroundColor: gray[800],
+ },
+ '&:active': {
+ backgroundColor: gray[900],
+ },
+ }),
+ }),
+ filterForm: ({ theme }) => ({
+ gap: theme.spacing(1),
+ alignItems: 'flex-end',
+ }),
+ columnsManagementHeader: ({ theme }) => ({
+ paddingRight: theme.spacing(3),
+ paddingLeft: theme.spacing(3),
+ }),
+ columnHeaderTitleContainer: {
+ flexGrow: 1,
+ justifyContent: 'space-between',
+ },
+ columnHeaderDraggableContainer: { paddingRight: 2 },
+ },
+ },
+};
diff --git a/docs/src/modules/components/DemoToolbar.js b/docs/src/modules/components/DemoToolbar.js
index d3c78d6f9b50e1..317ba91248553f 100644
--- a/docs/src/modules/components/DemoToolbar.js
+++ b/docs/src/modules/components/DemoToolbar.js
@@ -8,7 +8,6 @@ import MDButton from '@mui/material/Button';
import Box from '@mui/material/Box';
import MDToggleButton from '@mui/material/ToggleButton';
import MDToggleButtonGroup, { toggleButtonGroupClasses } from '@mui/material/ToggleButtonGroup';
-import SvgIcon from '@mui/material/SvgIcon';
import Snackbar from '@mui/material/Snackbar';
import Menu from '@mui/material/Menu';
import MDMenuItem, { menuItemClasses } from '@mui/material/MenuItem';
@@ -23,7 +22,7 @@ import { useSetCodeVariant } from 'docs/src/modules/utils/codeVariant';
import { useTranslate } from '@mui/docs/i18n';
import OpenMuiChat from 'docs/src/modules/components/OpenMuiChat';
import stylingSolutionMapping from 'docs/src/modules/utils/stylingSolutionMapping';
-import codeSandbox from '../sandbox/CodeSandbox';
+import SandboxIcon from './SandboxIcon';
import stackBlitz from '../sandbox/StackBlitz';
const Root = styled('div')(({ theme }) => [
@@ -356,7 +355,6 @@ export default function DemoToolbar(props) {
React.useRef(null),
React.useRef(null),
React.useRef(null),
- React.useRef(null),
];
// if the code is not open we hide the language controls
const isFocusableControl = React.useCallback(
@@ -492,36 +490,18 @@ export default function DemoToolbar(props) {
{showCodeLabel}
{demoOptions.hideEditButton ? null : (
-
-
- stackBlitz.createReactApp(demoData).openSandbox()}
- {...getControlProps(4)}
- sx={{ borderRadius: 1 }}
- >
-
-
-
-
-
-
- codeSandbox.createReactApp(demoData).openSandbox()}
- {...getControlProps(5)}
- sx={{ borderRadius: 1 }}
- >
-
-
-
-
-
-
+
+ stackBlitz.createReactApp(demoData).openSandbox()}
+ {...getControlProps(4)}
+ sx={{ borderRadius: 1 }}
+ >
+
+
+
)}
{copyIcon}
@@ -541,7 +521,7 @@ export default function DemoToolbar(props) {
data-ga-event-label={demo.gaLabel}
data-ga-event-action="reset-focus"
onClick={handleResetFocusClick}
- {...getControlProps(7)}
+ {...getControlProps(6)}
sx={{ borderRadius: 1 }}
>
@@ -554,7 +534,7 @@ export default function DemoToolbar(props) {
data-ga-event-label={demo.gaLabel}
data-ga-event-action="reset"
onClick={onResetDemoClick}
- {...getControlProps(8)}
+ {...getControlProps(7)}
sx={{ borderRadius: 1 }}
>
@@ -565,7 +545,7 @@ export default function DemoToolbar(props) {
aria-label={t('seeMore')}
aria-owns={anchorEl ? 'demo-menu-more' : undefined}
aria-haspopup="true"
- {...getControlProps(9)}
+ {...getControlProps(8)}
sx={{ borderRadius: 1 }}
>
diff --git a/docs/src/modules/components/JoyThemeBuilder.tsx b/docs/src/modules/components/JoyThemeBuilder.tsx
index 4b7c81a4fe1fec..00480ab7c13ac9 100644
--- a/docs/src/modules/components/JoyThemeBuilder.tsx
+++ b/docs/src/modules/components/JoyThemeBuilder.tsx
@@ -21,6 +21,7 @@ import Box from '@mui/joy/Box';
import Button from '@mui/joy/Button';
import Checkbox from '@mui/joy/Checkbox';
import Card from '@mui/joy/Card';
+import Tooltip from '@mui/joy/Tooltip';
import CardCover from '@mui/joy/CardCover';
import Divider from '@mui/joy/Divider';
import FormControl from '@mui/joy/FormControl';
@@ -62,12 +63,13 @@ import DarkMode from '@mui/icons-material/DarkMode';
import LightMode from '@mui/icons-material/LightMode';
import { HighlightedCode } from '@mui/docs/HighlightedCode';
import { BrandingProvider } from '@mui/docs/branding';
-import codeSandbox from 'docs/src/modules/sandbox/CodeSandbox';
+import stackBlitz from 'docs/src/modules/sandbox/StackBlitz';
import sourceJoyTemplates, { TemplateData } from 'docs/src/modules/joy/sourceJoyTemplates';
import extractTemplates from 'docs/src/modules/utils/extractTemplates';
import generateThemeAugmentation from 'docs/src/modules/joy/generateThemeAugmentation';
import literalToObject from 'docs/src/modules/joy/literalToObject';
import getMinimalJoyTemplate from 'docs/src/modules/joy/getMinimalJoyTemplate';
+import SandboxIcon from './SandboxIcon';
const tailwindColors = {
slate: {
@@ -1323,7 +1325,7 @@ function TemplatesDialog({
textColor="#fff"
overlay
onClick={() => {
- codeSandbox
+ stackBlitz
.createJoyTemplate({
...item,
files: newFiles,
@@ -1331,7 +1333,7 @@ function TemplatesDialog({
title: `Joy UI - Custom theme`,
codeVariant: 'TS',
})
- .openSandbox();
+ .openStackBlitz();
}}
endDecorator={}
sx={{ fontSize: 'xl', fontWeight: 'xl' }}
@@ -1401,14 +1403,14 @@ function TemplatesDialog({
'./result/App.tsx': getMinimalJoyTemplate(),
'./result/theme.ts': generateThemeCode(data),
});
- codeSandbox
+ stackBlitz
.createJoyTemplate({
...result,
codeVariant: 'TS',
githubLocation: '',
title: `Joy UI - Minimal template`,
})
- .openSandbox();
+ .openStackBlitz();
}}
endDecorator={}
sx={{ fontSize: 'lg', fontWeight: 'lg' }}
@@ -1528,11 +1530,11 @@ export default function JoyThemeBuilder() {
-
-
-
-
-
+
+
+
+
+
)}
diff --git a/docs/src/modules/components/MaterialFreeTemplatesCollection.js b/docs/src/modules/components/MaterialFreeTemplatesCollection.js
index 77f88a66c8fd4b..92c3cc9ce5bba2 100644
--- a/docs/src/modules/components/MaterialFreeTemplatesCollection.js
+++ b/docs/src/modules/components/MaterialFreeTemplatesCollection.js
@@ -7,15 +7,14 @@ import IconButton from '@mui/material/IconButton';
import Link from '@mui/material/Link';
import Tooltip from '@mui/material/Tooltip';
import Typography from '@mui/material/Typography';
-import SvgIcon from '@mui/material/SvgIcon';
import Visibility from '@mui/icons-material/Visibility';
import CodeRoundedIcon from '@mui/icons-material/CodeRounded';
import OpenInNewRoundedIcon from '@mui/icons-material/OpenInNewRounded';
import { useTranslate } from '@mui/docs/i18n';
import { pascalCase } from 'docs/src/modules/utils/helpers';
import sourceMaterialTemplates from 'docs/src/modules/material/sourceMaterialTemplates';
-import codeSandbox from 'docs/src/modules/sandbox/CodeSandbox';
import stackBlitz from 'docs/src/modules/sandbox/StackBlitz';
+import SandboxIcon from './SandboxIcon';
const sourcePrefix = `${process.env.SOURCE_CODE_REPO}/tree/v${process.env.LIB_VERSION}`;
@@ -179,11 +178,11 @@ export default function MaterialFreeTemplatesCollection() {
gap: 1,
}}
>
-
+
-
-
-
-
-
-
-
- codeSandbox
- .createMaterialTemplate({
- ...item,
- files: { ...item.files, ...materialTemplates.sharedTheme?.files },
- title: `${templateName} Template - Material UI`,
- githubLocation: `${process.env.SOURCE_CODE_REPO}/blob/v${
- process.env.LIB_VERSION
- }/docs/data/material/templates/${templateId}/${templateName}.${
- item.codeVariant === 'TS' ? 'tsx' : 'js'
- }`,
- })
- .replaceContent((content) => {
- if (typeof content === 'string') {
- return content
- .replace(/\.\.\/shared-theme\//g, './theme/')
- .replace('./App', `./${templateName}`);
- }
- return content;
- })
- .openSandbox(`/${templateName}`)
- }
- >
-
-
-
+
diff --git a/docs/src/modules/components/SandboxIcon.ts b/docs/src/modules/components/SandboxIcon.ts
new file mode 100644
index 00000000000000..3c0cce0b49fd9f
--- /dev/null
+++ b/docs/src/modules/components/SandboxIcon.ts
@@ -0,0 +1 @@
+export { default } from '@mui/icons-material/Launch';
diff --git a/docs/src/modules/components/TemplateFrame.js b/docs/src/modules/components/TemplateFrame.js
index e80048af50e3f2..17de0c251fc80d 100644
--- a/docs/src/modules/components/TemplateFrame.js
+++ b/docs/src/modules/components/TemplateFrame.js
@@ -16,15 +16,14 @@ import Box from '@mui/material/Box';
import Select from '@mui/material/Select';
import AppBar from '@mui/material/AppBar';
import Toolbar from '@mui/material/Toolbar';
-import SvgIcon from '@mui/material/SvgIcon';
import ArrowBackRoundedIcon from '@mui/icons-material/ArrowBackRounded';
import LightModeIcon from '@mui/icons-material/LightModeOutlined';
import DarkModeIcon from '@mui/icons-material/DarkModeOutlined';
import PaletteIcon from '@mui/icons-material/PaletteOutlined';
-import codeSandbox from 'docs/src/modules/sandbox/CodeSandbox';
import stackBlitz from 'docs/src/modules/sandbox/StackBlitz';
import sourceMaterialTemplates from 'docs/src/modules/material/sourceMaterialTemplates';
import { pascalCase } from 'docs/src/modules/utils/helpers';
+import SandboxIcon from './SandboxIcon';
const StyledAppBar = styled(AppBar)(({ theme }) => ({
position: 'relative',
@@ -272,12 +271,12 @@ export default function TemplateFrame({ children }) {
'& > *': { flexShrink: 0 },
}}
>
-
+
-
-
-
-
-
-
-
- codeSandbox
- .createMaterialTemplate({
- ...item,
- files: { ...item.files, ...materialTemplates.sharedTheme?.files },
- title: `${templateName} Template - Material UI`,
- githubLocation: `${process.env.SOURCE_CODE_REPO}/blob/v${
- process.env.LIB_VERSION
- }/docs/data/material/templates/${templateId}/${templateName}.${
- item.codeVariant === 'TS' ? 'tsx' : 'js'
- }`,
- })
- .replaceContent((content) => {
- if (typeof content === 'string') {
- return content
- .replace(/\.\.\/shared-theme\//g, './theme/')
- .replace('./App', `./${templateName}`);
- }
- return content;
- })
- .openSandbox(`/${templateName}`)
- }
- sx={{ alignSelf: 'center', borderRadius: 1 }}
- >
-
-
-
+
diff --git a/docs/src/modules/sandbox/CodeSandbox.test.js b/docs/src/modules/sandbox/CodeSandbox.test.js
deleted file mode 100644
index d81146413d57f3..00000000000000
--- a/docs/src/modules/sandbox/CodeSandbox.test.js
+++ /dev/null
@@ -1,267 +0,0 @@
-import { expect } from 'chai';
-import CodeSandbox from './CodeSandbox';
-
-const testCase = `import * as React from 'react';
-import Stack from '@mui/material/Stack';
-import Button from '@mui/material/Button';
-
-export default function BasicButtons() {
- return (
-
-
-
-
-
- );
-}
-`;
-
-describe('CodeSandbox', () => {
- it('generate the correct JavaScript result', () => {
- const result = CodeSandbox.createReactApp({
- title: 'BasicButtons Material Demo',
- githubLocation:
- 'https://github.com/mui/material-ui/blob/v5.7.0/docs/data/material/components/buttons/BasicButtons.js',
- codeVariant: 'JS',
- language: 'en',
- raw: testCase,
- });
- expect(result.files).to.deep.equal({
- 'package.json': {
- content: {
- private: true,
- description:
- 'https://github.com/mui/material-ui/blob/v5.7.0/docs/data/material/components/buttons/BasicButtons.js',
- dependencies: {
- react: 'latest',
- // #npm-tag-reference
- '@mui/material': 'latest',
- 'react-dom': 'latest',
- '@emotion/react': 'latest',
- '@emotion/styled': 'latest',
- },
- devDependencies: {
- 'react-scripts': 'latest',
- },
- scripts: {
- start: 'react-scripts start',
- build: 'react-scripts build',
- test: 'react-scripts test',
- eject: 'react-scripts eject',
- },
- },
- },
- 'public/index.html': {
- content: `
-
-
-
- BasicButtons Material Demo
-
-
-
-
-
-
-
-
-
-
- \n
-`,
- },
- 'src/Demo.js': {
- content: `import * as React from 'react';
-import Stack from '@mui/material/Stack';
-import Button from '@mui/material/Button';
-
-export default function BasicButtons() {
- return (
-
-
-
-
-
- );
-}
-`,
- },
- 'src/index.js': {
- content: `import * as React from 'react';
-import * as ReactDOM from 'react-dom/client';
-import { StyledEngineProvider } from '@mui/material/styles';
-import Demo from './Demo';
-
-ReactDOM.createRoot(document.querySelector("#root")).render(
-
-
-
-
-
-);`,
- },
- });
- });
-
- it('generate the correct TypeScript result', () => {
- const result = CodeSandbox.createReactApp({
- title: 'BasicButtons Material Demo',
- githubLocation:
- 'https://github.com/mui/material-ui/blob/v5.7.0/docs/data/material/components/buttons/BasicButtons.tsx',
- codeVariant: 'TS',
- language: 'en',
- raw: testCase,
- });
- expect(result.files).to.deep.equal({
- 'package.json': {
- content: {
- private: true,
- description:
- 'https://github.com/mui/material-ui/blob/v5.7.0/docs/data/material/components/buttons/BasicButtons.tsx',
- dependencies: {
- react: 'latest',
- // #npm-tag-reference
- '@mui/material': 'latest',
- 'react-dom': 'latest',
- '@emotion/react': 'latest',
- '@emotion/styled': 'latest',
- typescript: 'latest',
- },
- devDependencies: {
- 'react-scripts': 'latest',
- '@types/react': 'latest',
- '@types/react-dom': 'latest',
- },
- scripts: {
- build: 'react-scripts build',
- eject: 'react-scripts eject',
- start: 'react-scripts start',
- test: 'react-scripts test',
- },
- },
- },
- 'public/index.html': {
- content: `
-
-
-
- BasicButtons Material Demo
-
-
-
-
-
-
-
-
-
-
- \n
-`,
- },
- 'src/Demo.tsx': {
- content: `import * as React from 'react';
-import Stack from '@mui/material/Stack';
-import Button from '@mui/material/Button';
-
-export default function BasicButtons() {
- return (
-
-
-
-
-
- );
-}
-`,
- },
- 'src/index.tsx': {
- content: `import * as React from 'react';
-import * as ReactDOM from 'react-dom/client';
-import { StyledEngineProvider } from '@mui/material/styles';
-import Demo from './Demo';
-
-ReactDOM.createRoot(document.querySelector("#root")!).render(
-
-
-
-
-
-);`,
- },
- 'tsconfig.json': {
- content: `{
- "compilerOptions": {
- "target": "es5",
- "lib": [
- "dom",
- "dom.iterable",
- "esnext"
- ],
- "allowJs": true,
- "skipLibCheck": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "strict": true,
- "forceConsistentCasingInFileNames": true,
- "module": "esnext",
- "moduleResolution": "node",
- "resolveJsonModule": true,
- "isolatedModules": true,
- "noEmit": true,
- "jsx": "react"
- },
- "include": [
- "src"
- ]
-}
-`,
- },
- });
- expect(result.dependencies).to.deep.equal({
- '@emotion/react': 'latest',
- '@emotion/styled': 'latest',
- // #npm-tag-reference
- '@mui/material': 'latest',
- react: 'latest',
- 'react-dom': 'latest',
- typescript: 'latest',
- });
- expect(result.devDependencies).to.deep.equal({
- 'react-scripts': 'latest',
- '@types/react': 'latest',
- '@types/react-dom': 'latest',
- });
- });
-
- it('should generate the correct stylesheet font link in index.html for Material Two Tones icons', () => {
- const raw = `import * as React from 'react';
- import Icon from '@mui/material/Icon';
-
- export default function TwoToneIcons() {
- return add_circle;
- }
- `;
-
- const result = CodeSandbox.createReactApp({
- raw,
- codeVariant: 'JS',
- });
-
- expect(result.files['public/index.html'].content).to.contain(
- 'https://fonts.googleapis.com/icon?family=Material+Icons+Two+Tone',
- );
- });
-});
diff --git a/docs/src/modules/sandbox/CodeSandbox.ts b/docs/src/modules/sandbox/CodeSandbox.ts
deleted file mode 100644
index 0aa582a07b2a9b..00000000000000
--- a/docs/src/modules/sandbox/CodeSandbox.ts
+++ /dev/null
@@ -1,294 +0,0 @@
-// @ts-ignore
-import LZString from 'lz-string';
-import addHiddenInput from 'docs/src/modules/utils/addHiddenInput';
-import SandboxDependencies from 'docs/src/modules/sandbox/Dependencies';
-import * as CRA from 'docs/src/modules/sandbox/CreateReactApp';
-import getFileExtension from 'docs/src/modules/sandbox/FileExtension';
-import flattenRelativeImports from 'docs/src/modules/sandbox/FlattenRelativeImports';
-import { DemoData, CodeVariant } 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 '-'
- .replace(/\//g, '_') // Convert '/' to '_'
- .replace(/=+$/, ''); // Remove ending '='
-}
-
-function openSandbox({ files, codeVariant, initialFile }: any) {
- const extension = codeVariant === 'TS' ? '.tsx' : '.js';
- const parameters = compress({ files });
-
- // ref: https://codesandbox.io/docs/api/#define-api
- const form = document.createElement('form');
- form.method = 'POST';
- form.target = '_blank';
- form.action = 'https://codesandbox.io/api/v1/sandboxes/define';
- addHiddenInput(form, 'parameters', parameters);
- addHiddenInput(form, 'embed', '1');
- addHiddenInput(
- form,
- 'query',
- `module=${initialFile}${initialFile.match(/(\.tsx|\.ts|\.js)$/) ? '' : extension}&fontsize=12`,
- );
- document.body.appendChild(form);
- form.submit();
- document.body.removeChild(form);
-}
-
-function createReactApp(demoData: DemoData) {
- const ext = getFileExtension(demoData.codeVariant);
- const { title, githubLocation: description } = demoData;
-
- const files: Record = {
- 'public/index.html': {
- content: CRA.getHtml(demoData),
- },
- [`src/index.${ext}`]: {
- content: CRA.getRootIndex(demoData),
- },
- [`src/Demo.${ext}`]: {
- content: flattenRelativeImports(demoData.raw),
- },
- // Spread the relative modules
- ...(demoData.relativeModules &&
- // Transform the relative modules array into an object
- demoData.relativeModules.reduce(
- (acc, curr) => ({
- ...acc,
- // Remove the path and keep the filename
- [`src/${curr.module.replace(/^.*[\\/]/g, '')}`]: {
- content: flattenRelativeImports(curr.raw),
- },
- }),
- {},
- )),
- ...(demoData.codeVariant === 'TS' && {
- 'tsconfig.json': {
- content: CRA.getTsconfig(),
- },
- }),
- };
-
- const { dependencies, devDependencies } = SandboxDependencies(demoData, {
- commitRef: process.env.PULL_REQUEST_ID ? process.env.COMMIT_REF : undefined,
- devDeps: CSB_DEV_DEPENDENCIES,
- });
-
- files['package.json'] = {
- content: {
- private: true,
- description,
- dependencies,
- devDependencies,
- scripts: {
- start: 'react-scripts start',
- build: 'react-scripts build',
- test: 'react-scripts test',
- eject: 'react-scripts eject',
- },
- },
- };
-
- return {
- title,
- description,
- files,
- dependencies,
- devDependencies,
- /**
- * @param {string} initialFile
- * @description should start with `/`, for example `/Demo.tsx`. If the extension is not provided,
- * it will be appended based on the code variant.
- */
- openSandbox: (initialFile: string = `/src/Demo.${ext}`) =>
- openSandbox({ files, codeVariant: demoData.codeVariant, initialFile }),
- };
-}
-
-function createJoyTemplate(templateData: {
- title: string;
- files: Record;
- githubLocation: string;
- codeVariant: CodeVariant;
-}) {
- const ext = getFileExtension(templateData.codeVariant);
- const { title, githubLocation: description } = templateData;
-
- // document.querySelector returns 'Element | null' but createRoot expects 'Element | DocumentFragment'.
- const type = templateData.codeVariant === 'TS' ? '!' : '';
-
- const files: Record = {
- 'public/index.html': {
- content: CRA.getHtml({
- title: templateData.title,
- language: 'en',
- }),
- },
- [`index.${ext}`]: {
- content: `import * as React from 'react';
-import * as ReactDOM from 'react-dom/client';
-import { StyledEngineProvider } from '@mui/joy/styles';
-import App from './App';
-
-ReactDOM.createRoot(document.querySelector("#root")${type}).render(
-
-
-
-
-
-);`,
- },
- ...Object.entries(templateData.files).reduce(
- (prev, curr) => ({
- ...prev,
- [curr[0]]: {
- content: curr[1],
- },
- }),
- {},
- ),
- ...(templateData.codeVariant === 'TS' && {
- 'tsconfig.json': {
- content: CRA.getTsconfig(),
- },
- }),
- };
-
- const { dependencies, devDependencies } = SandboxDependencies(
- {
- codeVariant: templateData.codeVariant,
- raw: Object.entries(templateData.files).reduce((prev, curr) => `${prev}\n${curr}`, ''),
- productId: 'joy-ui',
- },
- {
- commitRef: process.env.PULL_REQUEST_ID ? process.env.COMMIT_REF : undefined,
- devDeps: CSB_DEV_DEPENDENCIES,
- },
- );
-
- files['package.json'] = {
- content: {
- private: true,
- description,
- dependencies,
- devDependencies,
- scripts: {
- start: 'react-scripts start',
- build: 'react-scripts build',
- test: 'react-scripts test',
- eject: 'react-scripts eject',
- },
- },
- };
-
- return {
- title,
- files,
- dependencies,
- devDependencies,
- openSandbox: (initialFile: string = '/App') =>
- openSandbox({ files, codeVariant: templateData.codeVariant, initialFile }),
- };
-}
-
-function createMaterialTemplate(templateData: {
- title: string;
- files: Record;
- githubLocation: string;
- codeVariant: CodeVariant;
-}) {
- const ext = getFileExtension(templateData.codeVariant);
- const { title, githubLocation: description } = templateData;
-
- // document.querySelector returns 'Element | null' but createRoot expects 'Element | DocumentFragment'.
- const type = templateData.codeVariant === 'TS' ? '!' : '';
-
- const files: Record }> = {
- 'public/index.html': {
- content: CRA.getHtml({
- title: templateData.title,
- language: 'en',
- }),
- },
- [`index.${ext}`]: {
- content: `import * as React from 'react';
-import * as ReactDOM from 'react-dom/client';
-import { StyledEngineProvider } from '@mui/material/styles';
-import App from './App';
-
-ReactDOM.createRoot(document.querySelector("#root")${type}).render(
-
-
-
-
-
-);`,
- },
- ...Object.entries(templateData.files).reduce(
- (prev, curr) => ({
- ...prev,
- [curr[0]]: {
- content: curr[1],
- },
- }),
- {},
- ),
- ...(templateData.codeVariant === 'TS' && {
- 'tsconfig.json': {
- content: CRA.getTsconfig(),
- },
- }),
- };
-
- const { dependencies, devDependencies } = SandboxDependencies(
- {
- codeVariant: templateData.codeVariant,
- raw: Object.entries(templateData.files).reduce((prev, curr) => `${prev}\n${curr}`, ''),
- productId: 'material-ui',
- },
- {
- commitRef: process.env.PULL_REQUEST_ID ? process.env.COMMIT_REF : undefined,
- devDeps: CSB_DEV_DEPENDENCIES,
- },
- );
-
- files['package.json'] = {
- content: {
- private: true,
- description,
- dependencies,
- devDependencies,
- scripts: {
- start: 'react-scripts start',
- build: 'react-scripts build',
- test: 'react-scripts test',
- eject: 'react-scripts eject',
- },
- },
- };
-
- return {
- title,
- files,
- dependencies,
- devDependencies,
- replaceContent(updater: (content: string | Record, filePath: string) => string) {
- Object.keys(files).forEach((filePath) => {
- files[filePath].content = updater(files[filePath].content, filePath);
- });
- return this;
- },
- openSandbox: (initialFile: string = '/App') =>
- openSandbox({ files, codeVariant: templateData.codeVariant, initialFile }),
- };
-}
-
-export default {
- createReactApp,
- createJoyTemplate,
- createMaterialTemplate,
-};
diff --git a/docs/src/modules/sandbox/Dependencies.test.js b/docs/src/modules/sandbox/Dependencies.test.js
index 00a4100cdba248..28a56383038767 100644
--- a/docs/src/modules/sandbox/Dependencies.test.js
+++ b/docs/src/modules/sandbox/Dependencies.test.js
@@ -267,8 +267,7 @@ import * as Utils from '@mui/utils';
'https://pkg.pr.new/mui/material-ui/@mui/system@2d0e8b4daf20b7494c818b6f8c4cc8423bc99d6f',
'@mui/utils':
'https://pkg.pr.new/mui/material-ui/@mui/utils@2d0e8b4daf20b7494c818b6f8c4cc8423bc99d6f',
- '@mui/base':
- 'https://pkg.pr.new/mui/material-ui/@mui/base@2d0e8b4daf20b7494c818b6f8c4cc8423bc99d6f',
+ '@mui/base': 'latest',
});
});
diff --git a/docs/src/modules/sandbox/Dependencies.ts b/docs/src/modules/sandbox/Dependencies.ts
index e3b76448c9520a..49860618a596ce 100644
--- a/docs/src/modules/sandbox/Dependencies.ts
+++ b/docs/src/modules/sandbox/Dependencies.ts
@@ -50,13 +50,13 @@ export default function SandboxDependencies(
* @return string - A valid version for a dependency entry in a package.json
*/
function getMuiPackageVersion(packageName: string): string {
+ if (packageName === 'joy' || packageName === 'base') {
+ return 'latest';
+ }
if (
commitRef === undefined ||
process.env.SOURCE_CODE_REPO !== 'https://github.com/mui/material-ui'
) {
- if (['joy', 'base'].includes(packageName)) {
- return 'latest';
- }
// #npm-tag-reference
return 'latest';
}