Skip to content
Open
Show file tree
Hide file tree
Changes from 10 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
20 changes: 8 additions & 12 deletions docs/data/joy/getting-started/templates/TemplateCollection.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ 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 Edit from '@mui/icons-material/Edit';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a different icon would be better suited for this. The pencil makes me think it would start editing inline (like how GitHub works)

What do you think of Terminal, Code, Biotech, PrecisionManufacturing, Construction, DisplaySettings, or OpenInBrowser

Copy link
Member Author

@Janpot Janpot Oct 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think of Terminal, Code, Biotech, PrecisionManufacturing, Construction, DisplaySettings, or OpenInBrowser

Sure, terminal could also make sense. In the templates page Code is already used for linking to the code on github.

Screenshot 2025-10-08 at 17 50 31

The other options

  • Screenshot 2025-10-08 at 17 48 26
  • Screenshot 2025-10-08 at 17 45 18
  • Screenshot 2025-10-08 at 17 47 17
  • Screenshot 2025-10-08 at 17 47 32
  • Screenshot 2025-10-08 at 17 47 45
  • Screenshot 2025-10-08 at 17 48 00
  • Screenshot 2025-10-08 at 17 48 16
  • ViewInAr: Screenshot 2025-10-09 at 11 13 31

Personally I still find the pencil most intuitive, but I don't have a strong opinion on this. Which do you think is best?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like Terminal the most since seeing the logs is the most noticeable difference between inline live-edit and StackBlitz. Another reason I dislike the pencil is that if we add live editing to Base UI, I think it would make sense to need to press the pencil to start live editing within the page. It would be interesting to hear what others think too.

Copy link
Member Author

@Janpot Janpot Oct 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option Launch:

Screenshot 2025-10-09 at 10 56 28

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also prefer Launch

In isolation, I like ViewInAr, but I find it too similar to the focus icon, which is two places to the side.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import SandboxIcon from ...

import stackBlitz from 'docs/src/modules/sandbox/StackBlitz';
import sourceJoyTemplates from 'docs/src/modules/joy/sourceJoyTemplates';

/**
Expand Down Expand Up @@ -269,17 +269,13 @@ export default function TemplateCollection() {
variant="outlined"
color="neutral"
fullWidth
startDecorator={
<SvgIcon viewBox="0 0 1080 1080">
<path d="M755 140.3l0.5-0.3h0.3L512 0 268.3 140h-0.3l0.8 0.4L68.6 256v512L512 1024l443.4-256V256L755 140.3z m-30 506.4v171.2L548 920.1V534.7L883.4 341v215.7l-158.4 90z m-584.4-90.6V340.8L476 534.4v385.7L300 818.5V646.7l-159.4-90.6zM511.7 280l171.1-98.3 166.3 96-336.9 194.5-337-194.6 165.7-95.7L511.7 280z" />
</SvgIcon>
}
aria-label="CodeSandbox playground"
startDecorator={<Edit />}
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`,
Expand All @@ -289,11 +285,11 @@ export default function TemplateCollection() {
item.codeVariant === 'TS' ? 'tsx' : 'js'
}`,
})
.openSandbox()
.openStackBlitz()
}
sx={{ fontFamily: 'IBM Plex Sans' }}
>
CodeSandbox
Open sandbox
</Button>
</Box>
</CardContent>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
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 { gray } from '../../../shared-theme/themePrimitives';

/* eslint-disable import/prefer-default-export */
Expand Down
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The dashboard template is broken because this file was missing

Original file line number Diff line number Diff line change
@@ -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<MuiTheme = unknown> {
MuiDataGrid?: {
defaultProps?: ComponentsProps['MuiDataGrid'];
styleOverrides?: ComponentsOverrides<MuiTheme>['MuiDataGrid'];
};
}

/* eslint-disable import/prefer-default-export */
export const dataGridCustomizations: DataGridComponents<Theme> = {
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 },
},
},
};
54 changes: 17 additions & 37 deletions docs/src/modules/components/DemoToolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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 }) => [
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -492,44 +490,26 @@ export default function DemoToolbar(props) {
{showCodeLabel}
</Button>
{demoOptions.hideEditButton ? null : (
<React.Fragment>
<DemoTooltip title={t('stackblitz')} placement="bottom">
<IconButton
data-ga-event-category="demo"
data-ga-event-label={demo.gaLabel}
data-ga-event-action="stackblitz"
onClick={() => stackBlitz.createReactApp(demoData).openSandbox()}
{...getControlProps(4)}
sx={{ borderRadius: 1 }}
>
<SvgIcon viewBox="0 0 19 28">
<path d="M8.13378 16.1087H0L14.8696 0L10.8662 11.1522L19 11.1522L4.13043 27.2609L8.13378 16.1087Z" />
</SvgIcon>
</IconButton>
</DemoTooltip>
<DemoTooltip title={t('codesandbox')} placement="bottom">
<IconButton
data-ga-event-category="demo"
data-ga-event-label={demo.gaLabel}
data-ga-event-action="codesandbox"
onClick={() => codeSandbox.createReactApp(demoData).openSandbox()}
{...getControlProps(5)}
sx={{ borderRadius: 1 }}
>
<SvgIcon viewBox="0 0 1024 1024">
<path d="M755 140.3l0.5-0.3h0.3L512 0 268.3 140h-0.3l0.8 0.4L68.6 256v512L512 1024l443.4-256V256L755 140.3z m-30 506.4v171.2L548 920.1V534.7L883.4 341v215.7l-158.4 90z m-584.4-90.6V340.8L476 534.4v385.7L300 818.5V646.7l-159.4-90.6zM511.7 280l171.1-98.3 166.3 96-336.9 194.5-337-194.6 165.7-95.7L511.7 280z" />
</SvgIcon>
</IconButton>
</DemoTooltip>
</React.Fragment>
<DemoTooltip title="Open sandbox" placement="bottom">
<IconButton
data-ga-event-category="demo"
data-ga-event-label={demo.gaLabel}
data-ga-event-action="stackblitz"
onClick={() => stackBlitz.createReactApp(demoData).openSandbox()}
{...getControlProps(4)}
sx={{ borderRadius: 1 }}
>
<SandboxIcon />
</IconButton>
</DemoTooltip>
)}
<DemoTooltip title={t('copySource')} placement="bottom">
<IconButton
data-ga-event-category="demo"
data-ga-event-label={demo.gaLabel}
data-ga-event-action="copy"
onClick={copyButtonOnClick}
{...getControlProps(6)}
{...getControlProps(5)}
sx={{ borderRadius: 1 }}
>
{copyIcon}
Expand All @@ -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 }}
>
<ResetFocusIcon />
Expand All @@ -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 }}
>
<RefreshRoundedIcon />
Expand All @@ -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 }}
>
<MoreVertIcon />
Expand Down
22 changes: 12 additions & 10 deletions docs/src/modules/components/JoyThemeBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -1323,15 +1325,15 @@ function TemplatesDialog({
textColor="#fff"
overlay
onClick={() => {
codeSandbox
stackBlitz
.createJoyTemplate({
...item,
files: newFiles,
githubLocation: '',
title: `Joy UI - Custom theme`,
codeVariant: 'TS',
})
.openSandbox();
.openStackBlitz();
}}
endDecorator={<ArrowOutwardIcon sx={{ color: 'inherit', opacity: 0.72 }} />}
sx={{ fontSize: 'xl', fontWeight: 'xl' }}
Expand Down Expand Up @@ -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={<ArrowOutwardIcon />}
sx={{ fontSize: 'lg', fontWeight: 'lg' }}
Expand Down Expand Up @@ -1528,11 +1530,11 @@ export default function JoyThemeBuilder() {
<Code />
</IconButton>
<TemplatesDialog data={data}>
<IconButton variant="solid" color="neutral" size="sm" sx={{ minWidth: '38px' }}>
<SvgIcon viewBox="0 0 1080 1080">
<path d="M755 140.3l0.5-0.3h0.3L512 0 268.3 140h-0.3l0.8 0.4L68.6 256v512L512 1024l443.4-256V256L755 140.3z m-30 506.4v171.2L548 920.1V534.7L883.4 341v215.7l-158.4 90z m-584.4-90.6V340.8L476 534.4v385.7L300 818.5V646.7l-159.4-90.6zM511.7 280l171.1-98.3 166.3 96-336.9 194.5-337-194.6 165.7-95.7L511.7 280z" />
</SvgIcon>
</IconButton>
<Tooltip title="Open sandbox">
<IconButton variant="solid" color="neutral" size="sm" sx={{ minWidth: '38px' }}>
<SandboxIcon />
</IconButton>
</Tooltip>
</TemplatesDialog>
</Box>
)}
Expand Down
Loading
Loading