From b66a7189f660aa82a14852ad718f754d8f4bf9ab Mon Sep 17 00:00:00 2001 From: Rom Grk Date: Tue, 20 Aug 2024 21:55:53 -0400 Subject: [PATCH] [perf] Remove theme/styling allocations (#43372) --- .../mui-material/src/Accordion/Accordion.js | 9 +- .../src/AccordionDetails/AccordionDetails.js | 9 +- .../src/AccordionSummary/AccordionSummary.js | 115 +-- packages/mui-material/src/Alert/Alert.js | 135 ++-- .../mui-material/src/AlertTitle/AlertTitle.js | 15 +- packages/mui-material/src/AppBar/AppBar.js | 219 +++--- .../src/Autocomplete/Autocomplete.js | 175 ++--- packages/mui-material/src/Avatar/Avatar.js | 83 +-- .../src/AvatarGroup/AvatarGroup.js | 25 +- packages/mui-material/src/Badge/Badge.js | 307 ++++---- .../src/BottomNavigation/BottomNavigation.js | 15 +- .../BottomNavigationAction.js | 93 +-- .../src/Breadcrumbs/BreadcrumbCollapsed.js | 41 +- packages/mui-material/src/Button/Button.js | 377 +++++----- .../src/ButtonGroup/ButtonGroup.js | 273 +++---- .../src/CardActionArea/CardActionArea.js | 63 +- .../mui-material/src/Checkbox/Checkbox.js | 87 +-- packages/mui-material/src/Chip/Chip.js | 457 ++++++------ .../src/CircularProgress/CircularProgress.js | 115 +-- .../mui-material/src/Collapse/Collapse.js | 79 +- packages/mui-material/src/Dialog/Dialog.js | 143 ++-- .../src/DialogContent/DialogContent.js | 47 +- packages/mui-material/src/Divider/Divider.js | 277 +++---- packages/mui-material/src/Drawer/Drawer.js | 169 ++--- packages/mui-material/src/Fab/Fab.js | 13 +- .../src/FilledInput/FilledInput.js | 361 +++++----- .../src/FormControlLabel/FormControlLabel.js | 93 +-- .../src/FormHelperText/FormHelperText.js | 63 +- .../mui-material/src/FormLabel/FormLabel.js | 67 +- packages/mui-material/src/Grid/Grid.js | 1 + packages/mui-material/src/Hidden/HiddenCss.js | 1 + packages/mui-material/src/Icon/Icon.js | 141 ++-- .../mui-material/src/IconButton/IconButton.js | 101 ++- .../src/ImageListItemBar/ImageListItemBar.js | 173 ++--- packages/mui-material/src/Input/Input.js | 147 ++-- .../src/InputAdornment/InputAdornment.js | 80 ++- .../mui-material/src/InputBase/InputBase.js | 263 +++---- .../mui-material/src/InputLabel/InputLabel.js | 217 +++--- .../src/LinearProgress/LinearProgress.js | 293 ++++---- packages/mui-material/src/Link/Link.js | 175 ++--- .../mui-material/src/ListItem/ListItem.js | 153 ++-- .../src/ListItemButton/ListItemButton.js | 153 ++-- .../src/ListItemIcon/ListItemIcon.js | 33 +- .../src/ListSubheader/ListSubheader.js | 91 +-- .../mui-material/src/MenuItem/MenuItem.js | 189 ++--- .../src/MobileStepper/MobileStepper.js | 99 +-- packages/mui-material/src/Modal/Modal.js | 33 +- .../src/OutlinedInput/NotchedOutline.js | 5 +- .../src/OutlinedInput/OutlinedInput.js | 233 +++--- .../src/PaginationItem/PaginationItem.js | 387 +++++----- packages/mui-material/src/Paper/Paper.js | 57 +- packages/mui-material/src/Radio/Radio.js | 87 +-- .../mui-material/src/Radio/RadioButtonIcon.js | 43 +- packages/mui-material/src/Rating/Rating.js | 129 ++-- .../ScopedCssBaseline/ScopedCssBaseline.js | 67 +- .../mui-material/src/Skeleton/Skeleton.js | 189 ++--- packages/mui-material/src/Slider/Slider.js | 679 +++++++++--------- .../mui-material/src/Snackbar/Snackbar.js | 89 +-- .../src/SnackbarContent/SnackbarContent.js | 45 +- .../mui-material/src/SpeedDial/SpeedDial.js | 103 +-- .../src/SpeedDialAction/SpeedDialAction.js | 151 ++-- .../src/SpeedDialIcon/SpeedDialIcon.js | 77 +- .../src/StepConnector/StepConnector.js | 49 +- .../src/StepContent/StepContent.js | 37 +- .../mui-material/src/StepIcon/StepIcon.js | 47 +- .../mui-material/src/StepLabel/StepLabel.js | 61 +- packages/mui-material/src/SvgIcon/SvgIcon.js | 111 +-- .../src/SwipeableDrawer/SwipeArea.js | 85 +-- packages/mui-material/src/Switch/Switch.js | 57 +- packages/mui-material/src/Tab/Tab.js | 227 +++--- packages/mui-material/src/Table/Table.js | 43 +- .../mui-material/src/TableCell/TableCell.js | 209 +++--- .../src/TablePagination/TablePagination.js | 69 +- .../mui-material/src/TableRow/TableRow.js | 45 +- .../src/TableSortLabel/TableSortLabel.js | 97 +-- packages/mui-material/src/Tabs/Tabs.js | 107 +-- .../src/ToggleButton/ToggleButton.js | 151 ++-- .../ToggleButtonGroup/ToggleButtonGroup.js | 121 ++-- packages/mui-material/src/Toolbar/Toolbar.js | 59 +- packages/mui-material/src/Tooltip/Tooltip.js | 363 +++++----- .../mui-material/src/Typography/Typography.js | 115 +-- packages/mui-material/src/utils/memoTheme.ts | 31 + 82 files changed, 5527 insertions(+), 5166 deletions(-) create mode 100644 packages/mui-material/src/utils/memoTheme.ts diff --git a/packages/mui-material/src/Accordion/Accordion.js b/packages/mui-material/src/Accordion/Accordion.js index 5f17646ae8c415..79c23f08b744d4 100644 --- a/packages/mui-material/src/Accordion/Accordion.js +++ b/packages/mui-material/src/Accordion/Accordion.js @@ -6,6 +6,7 @@ import clsx from 'clsx'; import chainPropTypes from '@mui/utils/chainPropTypes'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import Collapse from '../Collapse'; import Paper from '../Paper'; @@ -46,7 +47,7 @@ const AccordionRoot = styled(Paper, { ]; }, })( - ({ theme }) => { + memoTheme(({ theme }) => { const transition = { duration: theme.transitions.duration.shortest, }; @@ -91,8 +92,8 @@ const AccordionRoot = styled(Paper, { backgroundColor: (theme.vars || theme).palette.action.disabledBackground, }, }; - }, - ({ theme }) => ({ + }), + memoTheme(({ theme }) => ({ variants: [ { props: (props) => !props.square, @@ -122,7 +123,7 @@ const AccordionRoot = styled(Paper, { }, }, ], - }), + })), ); const AccordionHeading = styled('h3', { diff --git a/packages/mui-material/src/AccordionDetails/AccordionDetails.js b/packages/mui-material/src/AccordionDetails/AccordionDetails.js index bd07c757aad8ea..75b5b3f05aadc2 100644 --- a/packages/mui-material/src/AccordionDetails/AccordionDetails.js +++ b/packages/mui-material/src/AccordionDetails/AccordionDetails.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import { getAccordionDetailsUtilityClass } from './accordionDetailsClasses'; @@ -21,9 +22,11 @@ const AccordionDetailsRoot = styled('div', { name: 'MuiAccordionDetails', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})(({ theme }) => ({ - padding: theme.spacing(1, 2, 2), -})); +})( + memoTheme(({ theme }) => ({ + padding: theme.spacing(1, 2, 2), + })), +); const AccordionDetails = React.forwardRef(function AccordionDetails(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiAccordionDetails' }); diff --git a/packages/mui-material/src/AccordionSummary/AccordionSummary.js b/packages/mui-material/src/AccordionSummary/AccordionSummary.js index 3f23fac82bf689..4ca5ae9dfa0df4 100644 --- a/packages/mui-material/src/AccordionSummary/AccordionSummary.js +++ b/packages/mui-material/src/AccordionSummary/AccordionSummary.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import ButtonBase from '../ButtonBase'; import AccordionContext from '../Accordion/AccordionContext'; @@ -28,76 +29,82 @@ const AccordionSummaryRoot = styled(ButtonBase, { name: 'MuiAccordionSummary', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})(({ theme }) => { - const transition = { - duration: theme.transitions.duration.shortest, - }; +})( + memoTheme(({ theme }) => { + const transition = { + duration: theme.transitions.duration.shortest, + }; + + return { + display: 'flex', + minHeight: 48, + padding: theme.spacing(0, 2), + transition: theme.transitions.create(['min-height', 'background-color'], transition), + [`&.${accordionSummaryClasses.focusVisible}`]: { + backgroundColor: (theme.vars || theme).palette.action.focus, + }, + [`&.${accordionSummaryClasses.disabled}`]: { + opacity: (theme.vars || theme).palette.action.disabledOpacity, + }, + [`&:hover:not(.${accordionSummaryClasses.disabled})`]: { + cursor: 'pointer', + }, + variants: [ + { + props: (props) => !props.disableGutters, + style: { + [`&.${accordionSummaryClasses.expanded}`]: { + minHeight: 64, + }, + }, + }, + ], + }; + }), +); - return { +const AccordionSummaryContent = styled('div', { + name: 'MuiAccordionSummary', + slot: 'Content', + overridesResolver: (props, styles) => styles.content, +})( + memoTheme(({ theme }) => ({ display: 'flex', - minHeight: 48, - padding: theme.spacing(0, 2), - transition: theme.transitions.create(['min-height', 'background-color'], transition), - [`&.${accordionSummaryClasses.focusVisible}`]: { - backgroundColor: (theme.vars || theme).palette.action.focus, - }, - [`&.${accordionSummaryClasses.disabled}`]: { - opacity: (theme.vars || theme).palette.action.disabledOpacity, - }, - [`&:hover:not(.${accordionSummaryClasses.disabled})`]: { - cursor: 'pointer', - }, + flexGrow: 1, + margin: '12px 0', variants: [ { props: (props) => !props.disableGutters, style: { + transition: theme.transitions.create(['margin'], { + duration: theme.transitions.duration.shortest, + }), [`&.${accordionSummaryClasses.expanded}`]: { - minHeight: 64, + margin: '20px 0', }, }, }, ], - }; -}); - -const AccordionSummaryContent = styled('div', { - name: 'MuiAccordionSummary', - slot: 'Content', - overridesResolver: (props, styles) => styles.content, -})(({ theme }) => ({ - display: 'flex', - flexGrow: 1, - margin: '12px 0', - variants: [ - { - props: (props) => !props.disableGutters, - style: { - transition: theme.transitions.create(['margin'], { - duration: theme.transitions.duration.shortest, - }), - [`&.${accordionSummaryClasses.expanded}`]: { - margin: '20px 0', - }, - }, - }, - ], -})); + })), +); const AccordionSummaryExpandIconWrapper = styled('div', { name: 'MuiAccordionSummary', slot: 'ExpandIconWrapper', overridesResolver: (props, styles) => styles.expandIconWrapper, -})(({ theme }) => ({ - display: 'flex', - color: (theme.vars || theme).palette.action.active, - transform: 'rotate(0deg)', - transition: theme.transitions.create('transform', { - duration: theme.transitions.duration.shortest, - }), - [`&.${accordionSummaryClasses.expanded}`]: { - transform: 'rotate(180deg)', - }, -})); +})( + memoTheme(({ theme }) => ({ + display: 'flex', + color: (theme.vars || theme).palette.action.active, + transform: 'rotate(0deg)', + transition: theme.transitions.create('transform', { + duration: theme.transitions.duration.shortest, + }), + [`&.${accordionSummaryClasses.expanded}`]: { + transform: 'rotate(180deg)', + }, + })), +); const AccordionSummary = React.forwardRef(function AccordionSummary(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiAccordionSummary' }); diff --git a/packages/mui-material/src/Alert/Alert.js b/packages/mui-material/src/Alert/Alert.js index b5f3de7861f3ee..5896dac9ee30c3 100644 --- a/packages/mui-material/src/Alert/Alert.js +++ b/packages/mui-material/src/Alert/Alert.js @@ -5,6 +5,7 @@ import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { darken, lighten } from '@mui/system/colorManipulator'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import useSlot from '../utils/useSlot'; import capitalize from '../utils/capitalize'; @@ -47,72 +48,74 @@ const AlertRoot = styled(Paper, { styles[`${ownerState.variant}${capitalize(ownerState.color || ownerState.severity)}`], ]; }, -})(({ theme }) => { - const getColor = theme.palette.mode === 'light' ? darken : lighten; - const getBackgroundColor = theme.palette.mode === 'light' ? lighten : darken; - return { - ...theme.typography.body2, - backgroundColor: 'transparent', - display: 'flex', - padding: '6px 16px', - variants: [ - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main && value.light) - .map(([color]) => ({ - props: { colorSeverity: color, variant: 'standard' }, - style: { - color: theme.vars - ? theme.vars.palette.Alert[`${color}Color`] - : getColor(theme.palette[color].light, 0.6), - backgroundColor: theme.vars - ? theme.vars.palette.Alert[`${color}StandardBg`] - : getBackgroundColor(theme.palette[color].light, 0.9), - [`& .${alertClasses.icon}`]: theme.vars - ? { color: theme.vars.palette.Alert[`${color}IconColor`] } - : { - color: theme.palette[color].main, - }, - }, - })), - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main && value.light) - .map(([color]) => ({ - props: { colorSeverity: color, variant: 'outlined' }, - style: { - color: theme.vars - ? theme.vars.palette.Alert[`${color}Color`] - : getColor(theme.palette[color].light, 0.6), - border: `1px solid ${(theme.vars || theme).palette[color].light}`, - [`& .${alertClasses.icon}`]: theme.vars - ? { color: theme.vars.palette.Alert[`${color}IconColor`] } - : { - color: theme.palette[color].main, - }, - }, - })), - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main && value.dark) - .map(([color]) => ({ - props: { colorSeverity: color, variant: 'filled' }, - style: { - fontWeight: theme.typography.fontWeightMedium, - ...(theme.vars - ? { - color: theme.vars.palette.Alert[`${color}FilledColor`], - backgroundColor: theme.vars.palette.Alert[`${color}FilledBg`], - } - : { - backgroundColor: - theme.palette.mode === 'dark' - ? theme.palette[color].dark - : theme.palette[color].main, - color: theme.palette.getContrastText(theme.palette[color].main), - }), - }, - })), - ], - }; -}); +})( + memoTheme(({ theme }) => { + const getColor = theme.palette.mode === 'light' ? darken : lighten; + const getBackgroundColor = theme.palette.mode === 'light' ? lighten : darken; + return { + ...theme.typography.body2, + backgroundColor: 'transparent', + display: 'flex', + padding: '6px 16px', + variants: [ + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main && value.light) + .map(([color]) => ({ + props: { colorSeverity: color, variant: 'standard' }, + style: { + color: theme.vars + ? theme.vars.palette.Alert[`${color}Color`] + : getColor(theme.palette[color].light, 0.6), + backgroundColor: theme.vars + ? theme.vars.palette.Alert[`${color}StandardBg`] + : getBackgroundColor(theme.palette[color].light, 0.9), + [`& .${alertClasses.icon}`]: theme.vars + ? { color: theme.vars.palette.Alert[`${color}IconColor`] } + : { + color: theme.palette[color].main, + }, + }, + })), + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main && value.light) + .map(([color]) => ({ + props: { colorSeverity: color, variant: 'outlined' }, + style: { + color: theme.vars + ? theme.vars.palette.Alert[`${color}Color`] + : getColor(theme.palette[color].light, 0.6), + border: `1px solid ${(theme.vars || theme).palette[color].light}`, + [`& .${alertClasses.icon}`]: theme.vars + ? { color: theme.vars.palette.Alert[`${color}IconColor`] } + : { + color: theme.palette[color].main, + }, + }, + })), + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main && value.dark) + .map(([color]) => ({ + props: { colorSeverity: color, variant: 'filled' }, + style: { + fontWeight: theme.typography.fontWeightMedium, + ...(theme.vars + ? { + color: theme.vars.palette.Alert[`${color}FilledColor`], + backgroundColor: theme.vars.palette.Alert[`${color}FilledBg`], + } + : { + backgroundColor: + theme.palette.mode === 'dark' + ? theme.palette[color].dark + : theme.palette[color].main, + color: theme.palette.getContrastText(theme.palette[color].main), + }), + }, + })), + ], + }; + }), +); const AlertIcon = styled('div', { name: 'MuiAlert', diff --git a/packages/mui-material/src/AlertTitle/AlertTitle.js b/packages/mui-material/src/AlertTitle/AlertTitle.js index f8e6d0cb3711df..c6ff49c603ce79 100644 --- a/packages/mui-material/src/AlertTitle/AlertTitle.js +++ b/packages/mui-material/src/AlertTitle/AlertTitle.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import Typography from '../Typography'; import { getAlertTitleUtilityClass } from './alertTitleClasses'; @@ -22,12 +23,14 @@ const AlertTitleRoot = styled(Typography, { name: 'MuiAlertTitle', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})(({ theme }) => { - return { - fontWeight: theme.typography.fontWeightMedium, - marginTop: -2, - }; -}); +})( + memoTheme(({ theme }) => { + return { + fontWeight: theme.typography.fontWeightMedium, + marginTop: -2, + }; + }), +); const AlertTitle = React.forwardRef(function AlertTitle(inProps, ref) { const props = useDefaultProps({ diff --git a/packages/mui-material/src/AppBar/AppBar.js b/packages/mui-material/src/AppBar/AppBar.js index 8b6d7b70ad1b82..d46fe696c2c6ce 100644 --- a/packages/mui-material/src/AppBar/AppBar.js +++ b/packages/mui-material/src/AppBar/AppBar.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import capitalize from '../utils/capitalize'; import Paper from '../Paper'; @@ -35,131 +36,133 @@ const AppBarRoot = styled(Paper, { styles[`color${capitalize(ownerState.color)}`], ]; }, -})(({ theme }) => ({ - display: 'flex', - flexDirection: 'column', - width: '100%', - boxSizing: 'border-box', // Prevent padding issue with the Modal and fixed positioned AppBar. - flexShrink: 0, - variants: [ - { - props: { position: 'fixed' }, - style: { - position: 'fixed', - zIndex: (theme.vars || theme).zIndex.appBar, - top: 0, - left: 'auto', - right: 0, - '@media print': { - // Prevent the app bar to be visible on each printed page. - position: 'absolute', +})( + memoTheme(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + width: '100%', + boxSizing: 'border-box', // Prevent padding issue with the Modal and fixed positioned AppBar. + flexShrink: 0, + variants: [ + { + props: { position: 'fixed' }, + style: { + position: 'fixed', + zIndex: (theme.vars || theme).zIndex.appBar, + top: 0, + left: 'auto', + right: 0, + '@media print': { + // Prevent the app bar to be visible on each printed page. + position: 'absolute', + }, }, }, - }, - { - props: { position: 'absolute' }, - style: { - position: 'absolute', - zIndex: (theme.vars || theme).zIndex.appBar, - top: 0, - left: 'auto', - right: 0, + { + props: { position: 'absolute' }, + style: { + position: 'absolute', + zIndex: (theme.vars || theme).zIndex.appBar, + top: 0, + left: 'auto', + right: 0, + }, }, - }, - { - props: { position: 'sticky' }, - style: { - position: 'sticky', - zIndex: (theme.vars || theme).zIndex.appBar, - top: 0, - left: 'auto', - right: 0, + { + props: { position: 'sticky' }, + style: { + position: 'sticky', + zIndex: (theme.vars || theme).zIndex.appBar, + top: 0, + left: 'auto', + right: 0, + }, }, - }, - { - props: { position: 'static' }, - style: { - position: 'static', + { + props: { position: 'static' }, + style: { + position: 'static', + }, }, - }, - { - props: { position: 'relative' }, - style: { - position: 'relative', + { + props: { position: 'relative' }, + style: { + position: 'relative', + }, }, - }, - { - props: { color: 'inherit' }, - style: { - '--AppBar-color': 'inherit', + { + props: { color: 'inherit' }, + style: { + '--AppBar-color': 'inherit', + }, }, - }, - { - props: { color: 'default' }, - style: { - '--AppBar-background': theme.vars - ? theme.vars.palette.AppBar.defaultBg - : theme.palette.grey[100], - '--AppBar-color': theme.vars - ? theme.vars.palette.text.primary - : theme.palette.getContrastText(theme.palette.grey[100]), - ...theme.applyStyles('dark', { + { + props: { color: 'default' }, + style: { '--AppBar-background': theme.vars ? theme.vars.palette.AppBar.defaultBg - : theme.palette.grey[900], + : theme.palette.grey[100], '--AppBar-color': theme.vars ? theme.vars.palette.text.primary - : theme.palette.getContrastText(theme.palette.grey[900]), - }), + : theme.palette.getContrastText(theme.palette.grey[100]), + ...theme.applyStyles('dark', { + '--AppBar-background': theme.vars + ? theme.vars.palette.AppBar.defaultBg + : theme.palette.grey[900], + '--AppBar-color': theme.vars + ? theme.vars.palette.text.primary + : theme.palette.getContrastText(theme.palette.grey[900]), + }), + }, }, - }, - ...Object.entries(theme.palette) - .filter(([, palette]) => palette && palette.main && palette.contrastText) - .map(([color]) => ({ - props: { color }, + ...Object.entries(theme.palette) + .filter(([, palette]) => palette && palette.main && palette.contrastText) + .map(([color]) => ({ + props: { color }, + style: { + '--AppBar-background': (theme.vars ?? theme).palette[color].main, + '--AppBar-color': (theme.vars ?? theme).palette[color].contrastText, + }, + })), + { + props: (props) => + props.enableColorOnDark === true && !['inherit', 'transparent'].includes(props.color), style: { - '--AppBar-background': (theme.vars ?? theme).palette[color].main, - '--AppBar-color': (theme.vars ?? theme).palette[color].contrastText, + backgroundColor: 'var(--AppBar-background)', + color: 'var(--AppBar-color)', }, - })), - { - props: (props) => - props.enableColorOnDark === true && !['inherit', 'transparent'].includes(props.color), - style: { - backgroundColor: 'var(--AppBar-background)', - color: 'var(--AppBar-color)', }, - }, - { - props: (props) => - props.enableColorOnDark === false && !['inherit', 'transparent'].includes(props.color), - style: { - backgroundColor: 'var(--AppBar-background)', - color: 'var(--AppBar-color)', - ...theme.applyStyles('dark', { - backgroundColor: theme.vars - ? joinVars(theme.vars.palette.AppBar.darkBg, 'var(--AppBar-background)') - : null, - color: theme.vars - ? joinVars(theme.vars.palette.AppBar.darkColor, 'var(--AppBar-color)') - : null, - }), + { + props: (props) => + props.enableColorOnDark === false && !['inherit', 'transparent'].includes(props.color), + style: { + backgroundColor: 'var(--AppBar-background)', + color: 'var(--AppBar-color)', + ...theme.applyStyles('dark', { + backgroundColor: theme.vars + ? joinVars(theme.vars.palette.AppBar.darkBg, 'var(--AppBar-background)') + : null, + color: theme.vars + ? joinVars(theme.vars.palette.AppBar.darkColor, 'var(--AppBar-color)') + : null, + }), + }, }, - }, - { - props: { color: 'transparent' }, - style: { - '--AppBar-background': 'transparent', - '--AppBar-color': 'inherit', - backgroundColor: 'var(--AppBar-background)', - color: 'var(--AppBar-color)', - ...theme.applyStyles('dark', { - backgroundImage: 'none', - }), + { + props: { color: 'transparent' }, + style: { + '--AppBar-background': 'transparent', + '--AppBar-color': 'inherit', + backgroundColor: 'var(--AppBar-background)', + color: 'var(--AppBar-color)', + ...theme.applyStyles('dark', { + backgroundImage: 'none', + }), + }, }, - }, - ], -})); + ], + })), +); const AppBar = React.forwardRef(function AppBar(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiAppBar' }); diff --git a/packages/mui-material/src/Autocomplete/Autocomplete.js b/packages/mui-material/src/Autocomplete/Autocomplete.js index 9e47976db676eb..db5d2b1b7cf9b9 100644 --- a/packages/mui-material/src/Autocomplete/Autocomplete.js +++ b/packages/mui-material/src/Autocomplete/Autocomplete.js @@ -19,6 +19,7 @@ import filledInputClasses from '../FilledInput/filledInputClasses'; import ClearIcon from '../internal/svg-icons/Close'; import ArrowDropDownIcon from '../internal/svg-icons/ArrowDropDown'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import autocompleteClasses, { getAutocompleteUtilityClass } from './autocompleteClasses'; import capitalize from '../utils/capitalize'; @@ -278,123 +279,135 @@ const AutocompletePopper = styled(Popper, { ownerState.disablePortal && styles.popperDisablePortal, ]; }, -})(({ theme }) => ({ - zIndex: (theme.vars || theme).zIndex.modal, - variants: [ - { - props: { disablePortal: true }, - style: { - position: 'absolute', +})( + memoTheme(({ theme }) => ({ + zIndex: (theme.vars || theme).zIndex.modal, + variants: [ + { + props: { disablePortal: true }, + style: { + position: 'absolute', + }, }, - }, - ], -})); + ], + })), +); const AutocompletePaper = styled(Paper, { name: 'MuiAutocomplete', slot: 'Paper', overridesResolver: (props, styles) => styles.paper, -})(({ theme }) => ({ - ...theme.typography.body1, - overflow: 'auto', -})); +})( + memoTheme(({ theme }) => ({ + ...theme.typography.body1, + overflow: 'auto', + })), +); const AutocompleteLoading = styled('div', { name: 'MuiAutocomplete', slot: 'Loading', overridesResolver: (props, styles) => styles.loading, -})(({ theme }) => ({ - color: (theme.vars || theme).palette.text.secondary, - padding: '14px 16px', -})); +})( + memoTheme(({ theme }) => ({ + color: (theme.vars || theme).palette.text.secondary, + padding: '14px 16px', + })), +); const AutocompleteNoOptions = styled('div', { name: 'MuiAutocomplete', slot: 'NoOptions', overridesResolver: (props, styles) => styles.noOptions, -})(({ theme }) => ({ - color: (theme.vars || theme).palette.text.secondary, - padding: '14px 16px', -})); +})( + memoTheme(({ theme }) => ({ + color: (theme.vars || theme).palette.text.secondary, + padding: '14px 16px', + })), +); const AutocompleteListbox = styled('div', { name: 'MuiAutocomplete', slot: 'Listbox', overridesResolver: (props, styles) => styles.listbox, -})(({ theme }) => ({ - listStyle: 'none', - margin: 0, - padding: '8px 0', - maxHeight: '40vh', - overflow: 'auto', - position: 'relative', - [`& .${autocompleteClasses.option}`]: { - minHeight: 48, - display: 'flex', - overflow: 'hidden', - justifyContent: 'flex-start', - alignItems: 'center', - cursor: 'pointer', - paddingTop: 6, - boxSizing: 'border-box', - outline: '0', - WebkitTapHighlightColor: 'transparent', - paddingBottom: 6, - paddingLeft: 16, - paddingRight: 16, - [theme.breakpoints.up('sm')]: { - minHeight: 'auto', - }, - [`&.${autocompleteClasses.focused}`]: { - backgroundColor: (theme.vars || theme).palette.action.hover, - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: 'transparent', +})( + memoTheme(({ theme }) => ({ + listStyle: 'none', + margin: 0, + padding: '8px 0', + maxHeight: '40vh', + overflow: 'auto', + position: 'relative', + [`& .${autocompleteClasses.option}`]: { + minHeight: 48, + display: 'flex', + overflow: 'hidden', + justifyContent: 'flex-start', + alignItems: 'center', + cursor: 'pointer', + paddingTop: 6, + boxSizing: 'border-box', + outline: '0', + WebkitTapHighlightColor: 'transparent', + paddingBottom: 6, + paddingLeft: 16, + paddingRight: 16, + [theme.breakpoints.up('sm')]: { + minHeight: 'auto', }, - }, - '&[aria-disabled="true"]': { - opacity: (theme.vars || theme).palette.action.disabledOpacity, - pointerEvents: 'none', - }, - [`&.${autocompleteClasses.focusVisible}`]: { - backgroundColor: (theme.vars || theme).palette.action.focus, - }, - '&[aria-selected="true"]': { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` - : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), [`&.${autocompleteClasses.focused}`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` - : alpha( - theme.palette.primary.main, - theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, - ), + backgroundColor: (theme.vars || theme).palette.action.hover, // Reset on touch devices, it doesn't add specificity '@media (hover: none)': { - backgroundColor: (theme.vars || theme).palette.action.selected, + backgroundColor: 'transparent', }, }, + '&[aria-disabled="true"]': { + opacity: (theme.vars || theme).palette.action.disabledOpacity, + pointerEvents: 'none', + }, [`&.${autocompleteClasses.focusVisible}`]: { + backgroundColor: (theme.vars || theme).palette.action.focus, + }, + '&[aria-selected="true"]': { backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))` - : alpha( - theme.palette.primary.main, - theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity, - ), + ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` + : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), + [`&.${autocompleteClasses.focused}`]: { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` + : alpha( + theme.palette.primary.main, + theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, + ), + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: (theme.vars || theme).palette.action.selected, + }, + }, + [`&.${autocompleteClasses.focusVisible}`]: { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))` + : alpha( + theme.palette.primary.main, + theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity, + ), + }, }, }, - }, -})); + })), +); const AutocompleteGroupLabel = styled(ListSubheader, { name: 'MuiAutocomplete', slot: 'GroupLabel', overridesResolver: (props, styles) => styles.groupLabel, -})(({ theme }) => ({ - backgroundColor: (theme.vars || theme).palette.background.paper, - top: -8, -})); +})( + memoTheme(({ theme }) => ({ + backgroundColor: (theme.vars || theme).palette.background.paper, + top: -8, + })), +); const AutocompleteGroupUl = styled('ul', { name: 'MuiAutocomplete', diff --git a/packages/mui-material/src/Avatar/Avatar.js b/packages/mui-material/src/Avatar/Avatar.js index 9f1c21adacf21c..0ba9e1cf8ee8e2 100644 --- a/packages/mui-material/src/Avatar/Avatar.js +++ b/packages/mui-material/src/Avatar/Avatar.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import Person from '../internal/svg-icons/Person'; import { getAvatarUtilityClass } from './avatarClasses'; @@ -33,49 +34,51 @@ const AvatarRoot = styled('div', { ownerState.colorDefault && styles.colorDefault, ]; }, -})(({ theme }) => ({ - position: 'relative', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - flexShrink: 0, - width: 40, - height: 40, - fontFamily: theme.typography.fontFamily, - fontSize: theme.typography.pxToRem(20), - lineHeight: 1, - borderRadius: '50%', - overflow: 'hidden', - userSelect: 'none', - variants: [ - { - props: { variant: 'rounded' }, - style: { - borderRadius: (theme.vars || theme).shape.borderRadius, +})( + memoTheme(({ theme }) => ({ + position: 'relative', + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + flexShrink: 0, + width: 40, + height: 40, + fontFamily: theme.typography.fontFamily, + fontSize: theme.typography.pxToRem(20), + lineHeight: 1, + borderRadius: '50%', + overflow: 'hidden', + userSelect: 'none', + variants: [ + { + props: { variant: 'rounded' }, + style: { + borderRadius: (theme.vars || theme).shape.borderRadius, + }, }, - }, - { - props: { variant: 'square' }, - style: { - borderRadius: 0, + { + props: { variant: 'square' }, + style: { + borderRadius: 0, + }, }, - }, - { - props: { colorDefault: true }, - style: { - color: (theme.vars || theme).palette.background.default, - ...(theme.vars - ? { - backgroundColor: theme.vars.palette.Avatar.defaultBg, - } - : { - backgroundColor: theme.palette.grey[400], - ...theme.applyStyles('dark', { backgroundColor: theme.palette.grey[600] }), - }), + { + props: { colorDefault: true }, + style: { + color: (theme.vars || theme).palette.background.default, + ...(theme.vars + ? { + backgroundColor: theme.vars.palette.Avatar.defaultBg, + } + : { + backgroundColor: theme.palette.grey[400], + ...theme.applyStyles('dark', { backgroundColor: theme.palette.grey[600] }), + }), + }, }, - }, - ], -})); + ], + })), +); const AvatarImg = styled('img', { name: 'MuiAvatar', diff --git a/packages/mui-material/src/AvatarGroup/AvatarGroup.js b/packages/mui-material/src/AvatarGroup/AvatarGroup.js index 507109723fb912..48bded04532dde 100644 --- a/packages/mui-material/src/AvatarGroup/AvatarGroup.js +++ b/packages/mui-material/src/AvatarGroup/AvatarGroup.js @@ -6,6 +6,7 @@ import clsx from 'clsx'; import chainPropTypes from '@mui/utils/chainPropTypes'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import Avatar, { avatarClasses } from '../Avatar'; import avatarGroupClasses, { getAvatarGroupUtilityClass } from './avatarGroupClasses'; @@ -34,18 +35,20 @@ const AvatarGroupRoot = styled('div', { [`& .${avatarGroupClasses.avatar}`]: styles.avatar, ...styles.root, }), -})(({ theme }) => ({ - display: 'flex', - flexDirection: 'row-reverse', - [`& .${avatarClasses.root}`]: { - border: `2px solid ${(theme.vars || theme).palette.background.default}`, - boxSizing: 'content-box', - marginLeft: 'var(--AvatarGroup-spacing, -8px)', - '&:last-child': { - marginLeft: 0, +})( + memoTheme(({ theme }) => ({ + display: 'flex', + flexDirection: 'row-reverse', + [`& .${avatarClasses.root}`]: { + border: `2px solid ${(theme.vars || theme).palette.background.default}`, + boxSizing: 'content-box', + marginLeft: 'var(--AvatarGroup-spacing, -8px)', + '&:last-child': { + marginLeft: 0, + }, }, - }, -})); + })), +); const AvatarGroup = React.forwardRef(function AvatarGroup(inProps, ref) { const props = useDefaultProps({ diff --git a/packages/mui-material/src/Badge/Badge.js b/packages/mui-material/src/Badge/Badge.js index dfbcf3bb652643..c0916458f64175 100644 --- a/packages/mui-material/src/Badge/Badge.js +++ b/packages/mui-material/src/Badge/Badge.js @@ -7,6 +7,7 @@ import composeClasses from '@mui/utils/composeClasses'; import useSlotProps from '@mui/utils/useSlotProps'; import useBadge from './useBadge'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import capitalize from '../utils/capitalize'; import badgeClasses, { getBadgeUtilityClass } from './badgeClasses'; @@ -65,178 +66,180 @@ const BadgeBadge = styled('span', { ownerState.invisible && styles.invisible, ]; }, -})(({ theme }) => ({ - display: 'flex', - flexDirection: 'row', - flexWrap: 'wrap', - justifyContent: 'center', - alignContent: 'center', - alignItems: 'center', - position: 'absolute', - boxSizing: 'border-box', - fontFamily: theme.typography.fontFamily, - fontWeight: theme.typography.fontWeightMedium, - fontSize: theme.typography.pxToRem(12), - minWidth: RADIUS_STANDARD * 2, - lineHeight: 1, - padding: '0 6px', - height: RADIUS_STANDARD * 2, - borderRadius: RADIUS_STANDARD, - zIndex: 1, // Render the badge on top of potential ripples. - transition: theme.transitions.create('transform', { - easing: theme.transitions.easing.easeInOut, - duration: theme.transitions.duration.enteringScreen, - }), - variants: [ - ...Object.entries(theme.palette) - .filter(([, palette]) => palette && palette.main && palette.contrastText) - .map(([color]) => ({ - props: { color }, +})( + memoTheme(({ theme }) => ({ + display: 'flex', + flexDirection: 'row', + flexWrap: 'wrap', + justifyContent: 'center', + alignContent: 'center', + alignItems: 'center', + position: 'absolute', + boxSizing: 'border-box', + fontFamily: theme.typography.fontFamily, + fontWeight: theme.typography.fontWeightMedium, + fontSize: theme.typography.pxToRem(12), + minWidth: RADIUS_STANDARD * 2, + lineHeight: 1, + padding: '0 6px', + height: RADIUS_STANDARD * 2, + borderRadius: RADIUS_STANDARD, + zIndex: 1, // Render the badge on top of potential ripples. + transition: theme.transitions.create('transform', { + easing: theme.transitions.easing.easeInOut, + duration: theme.transitions.duration.enteringScreen, + }), + variants: [ + ...Object.entries(theme.palette) + .filter(([, palette]) => palette && palette.main && palette.contrastText) + .map(([color]) => ({ + props: { color }, + style: { + backgroundColor: (theme.vars || theme).palette[color].main, + color: (theme.vars || theme).palette[color].contrastText, + }, + })), + { + props: { variant: 'dot' }, style: { - backgroundColor: (theme.vars || theme).palette[color].main, - color: (theme.vars || theme).palette[color].contrastText, + borderRadius: RADIUS_DOT, + height: RADIUS_DOT * 2, + minWidth: RADIUS_DOT * 2, + padding: 0, }, - })), - { - props: { variant: 'dot' }, - style: { - borderRadius: RADIUS_DOT, - height: RADIUS_DOT * 2, - minWidth: RADIUS_DOT * 2, - padding: 0, }, - }, - { - props: ({ ownerState }) => - ownerState.anchorOrigin.vertical === 'top' && - ownerState.anchorOrigin.horizontal === 'right' && - ownerState.overlap === 'rectangular', - style: { - top: 0, - right: 0, - transform: 'scale(1) translate(50%, -50%)', - transformOrigin: '100% 0%', - [`&.${badgeClasses.invisible}`]: { - transform: 'scale(0) translate(50%, -50%)', + { + props: ({ ownerState }) => + ownerState.anchorOrigin.vertical === 'top' && + ownerState.anchorOrigin.horizontal === 'right' && + ownerState.overlap === 'rectangular', + style: { + top: 0, + right: 0, + transform: 'scale(1) translate(50%, -50%)', + transformOrigin: '100% 0%', + [`&.${badgeClasses.invisible}`]: { + transform: 'scale(0) translate(50%, -50%)', + }, }, }, - }, - { - props: ({ ownerState }) => - ownerState.anchorOrigin.vertical === 'bottom' && - ownerState.anchorOrigin.horizontal === 'right' && - ownerState.overlap === 'rectangular', - style: { - bottom: 0, - right: 0, - transform: 'scale(1) translate(50%, 50%)', - transformOrigin: '100% 100%', - [`&.${badgeClasses.invisible}`]: { - transform: 'scale(0) translate(50%, 50%)', + { + props: ({ ownerState }) => + ownerState.anchorOrigin.vertical === 'bottom' && + ownerState.anchorOrigin.horizontal === 'right' && + ownerState.overlap === 'rectangular', + style: { + bottom: 0, + right: 0, + transform: 'scale(1) translate(50%, 50%)', + transformOrigin: '100% 100%', + [`&.${badgeClasses.invisible}`]: { + transform: 'scale(0) translate(50%, 50%)', + }, }, }, - }, - { - props: ({ ownerState }) => - ownerState.anchorOrigin.vertical === 'top' && - ownerState.anchorOrigin.horizontal === 'left' && - ownerState.overlap === 'rectangular', - style: { - top: 0, - left: 0, - transform: 'scale(1) translate(-50%, -50%)', - transformOrigin: '0% 0%', - [`&.${badgeClasses.invisible}`]: { - transform: 'scale(0) translate(-50%, -50%)', + { + props: ({ ownerState }) => + ownerState.anchorOrigin.vertical === 'top' && + ownerState.anchorOrigin.horizontal === 'left' && + ownerState.overlap === 'rectangular', + style: { + top: 0, + left: 0, + transform: 'scale(1) translate(-50%, -50%)', + transformOrigin: '0% 0%', + [`&.${badgeClasses.invisible}`]: { + transform: 'scale(0) translate(-50%, -50%)', + }, }, }, - }, - { - props: ({ ownerState }) => - ownerState.anchorOrigin.vertical === 'bottom' && - ownerState.anchorOrigin.horizontal === 'left' && - ownerState.overlap === 'rectangular', - style: { - bottom: 0, - left: 0, - transform: 'scale(1) translate(-50%, 50%)', - transformOrigin: '0% 100%', - [`&.${badgeClasses.invisible}`]: { - transform: 'scale(0) translate(-50%, 50%)', + { + props: ({ ownerState }) => + ownerState.anchorOrigin.vertical === 'bottom' && + ownerState.anchorOrigin.horizontal === 'left' && + ownerState.overlap === 'rectangular', + style: { + bottom: 0, + left: 0, + transform: 'scale(1) translate(-50%, 50%)', + transformOrigin: '0% 100%', + [`&.${badgeClasses.invisible}`]: { + transform: 'scale(0) translate(-50%, 50%)', + }, }, }, - }, - { - props: ({ ownerState }) => - ownerState.anchorOrigin.vertical === 'top' && - ownerState.anchorOrigin.horizontal === 'right' && - ownerState.overlap === 'circular', - style: { - top: '14%', - right: '14%', - transform: 'scale(1) translate(50%, -50%)', - transformOrigin: '100% 0%', - [`&.${badgeClasses.invisible}`]: { - transform: 'scale(0) translate(50%, -50%)', + { + props: ({ ownerState }) => + ownerState.anchorOrigin.vertical === 'top' && + ownerState.anchorOrigin.horizontal === 'right' && + ownerState.overlap === 'circular', + style: { + top: '14%', + right: '14%', + transform: 'scale(1) translate(50%, -50%)', + transformOrigin: '100% 0%', + [`&.${badgeClasses.invisible}`]: { + transform: 'scale(0) translate(50%, -50%)', + }, }, }, - }, - { - props: ({ ownerState }) => - ownerState.anchorOrigin.vertical === 'bottom' && - ownerState.anchorOrigin.horizontal === 'right' && - ownerState.overlap === 'circular', - style: { - bottom: '14%', - right: '14%', - transform: 'scale(1) translate(50%, 50%)', - transformOrigin: '100% 100%', - [`&.${badgeClasses.invisible}`]: { - transform: 'scale(0) translate(50%, 50%)', + { + props: ({ ownerState }) => + ownerState.anchorOrigin.vertical === 'bottom' && + ownerState.anchorOrigin.horizontal === 'right' && + ownerState.overlap === 'circular', + style: { + bottom: '14%', + right: '14%', + transform: 'scale(1) translate(50%, 50%)', + transformOrigin: '100% 100%', + [`&.${badgeClasses.invisible}`]: { + transform: 'scale(0) translate(50%, 50%)', + }, }, }, - }, - { - props: ({ ownerState }) => - ownerState.anchorOrigin.vertical === 'top' && - ownerState.anchorOrigin.horizontal === 'left' && - ownerState.overlap === 'circular', - style: { - top: '14%', - left: '14%', - transform: 'scale(1) translate(-50%, -50%)', - transformOrigin: '0% 0%', - [`&.${badgeClasses.invisible}`]: { - transform: 'scale(0) translate(-50%, -50%)', + { + props: ({ ownerState }) => + ownerState.anchorOrigin.vertical === 'top' && + ownerState.anchorOrigin.horizontal === 'left' && + ownerState.overlap === 'circular', + style: { + top: '14%', + left: '14%', + transform: 'scale(1) translate(-50%, -50%)', + transformOrigin: '0% 0%', + [`&.${badgeClasses.invisible}`]: { + transform: 'scale(0) translate(-50%, -50%)', + }, }, }, - }, - { - props: ({ ownerState }) => - ownerState.anchorOrigin.vertical === 'bottom' && - ownerState.anchorOrigin.horizontal === 'left' && - ownerState.overlap === 'circular', - style: { - bottom: '14%', - left: '14%', - transform: 'scale(1) translate(-50%, 50%)', - transformOrigin: '0% 100%', - [`&.${badgeClasses.invisible}`]: { - transform: 'scale(0) translate(-50%, 50%)', + { + props: ({ ownerState }) => + ownerState.anchorOrigin.vertical === 'bottom' && + ownerState.anchorOrigin.horizontal === 'left' && + ownerState.overlap === 'circular', + style: { + bottom: '14%', + left: '14%', + transform: 'scale(1) translate(-50%, 50%)', + transformOrigin: '0% 100%', + [`&.${badgeClasses.invisible}`]: { + transform: 'scale(0) translate(-50%, 50%)', + }, }, }, - }, - { - props: { invisible: true }, - style: { - transition: theme.transitions.create('transform', { - easing: theme.transitions.easing.easeInOut, - duration: theme.transitions.duration.leavingScreen, - }), + { + props: { invisible: true }, + style: { + transition: theme.transitions.create('transform', { + easing: theme.transitions.easing.easeInOut, + duration: theme.transitions.duration.leavingScreen, + }), + }, }, - }, - ], -})); + ], + })), +); const Badge = React.forwardRef(function Badge(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiBadge' }); diff --git a/packages/mui-material/src/BottomNavigation/BottomNavigation.js b/packages/mui-material/src/BottomNavigation/BottomNavigation.js index 976f43c61bd4ac..1ecedd850c051d 100755 --- a/packages/mui-material/src/BottomNavigation/BottomNavigation.js +++ b/packages/mui-material/src/BottomNavigation/BottomNavigation.js @@ -5,6 +5,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import { getBottomNavigationUtilityClass } from './bottomNavigationClasses'; @@ -22,12 +23,14 @@ const BottomNavigationRoot = styled('div', { name: 'MuiBottomNavigation', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})(({ theme }) => ({ - display: 'flex', - justifyContent: 'center', - height: 56, - backgroundColor: (theme.vars || theme).palette.background.paper, -})); +})( + memoTheme(({ theme }) => ({ + display: 'flex', + justifyContent: 'center', + height: 56, + backgroundColor: (theme.vars || theme).palette.background.paper, + })), +); const BottomNavigation = React.forwardRef(function BottomNavigation(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiBottomNavigation' }); diff --git a/packages/mui-material/src/BottomNavigationAction/BottomNavigationAction.js b/packages/mui-material/src/BottomNavigationAction/BottomNavigationAction.js index e47b9c83e1890c..63421f84698921 100644 --- a/packages/mui-material/src/BottomNavigationAction/BottomNavigationAction.js +++ b/packages/mui-material/src/BottomNavigationAction/BottomNavigationAction.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import ButtonBase from '../ButtonBase'; import unsupportedProp from '../utils/unsupportedProp'; @@ -30,58 +31,62 @@ const BottomNavigationActionRoot = styled(ButtonBase, { return [styles.root, !ownerState.showLabel && !ownerState.selected && styles.iconOnly]; }, -})(({ theme }) => ({ - transition: theme.transitions.create(['color', 'padding-top'], { - duration: theme.transitions.duration.short, - }), - padding: '0px 12px', - minWidth: 80, - maxWidth: 168, - color: (theme.vars || theme).palette.text.secondary, - flexDirection: 'column', - flex: '1', - [`&.${bottomNavigationActionClasses.selected}`]: { - color: (theme.vars || theme).palette.primary.main, - }, - variants: [ - { - props: ({ showLabel, selected }) => !showLabel && !selected, - style: { - paddingTop: 14, - }, +})( + memoTheme(({ theme }) => ({ + transition: theme.transitions.create(['color', 'padding-top'], { + duration: theme.transitions.duration.short, + }), + padding: '0px 12px', + minWidth: 80, + maxWidth: 168, + color: (theme.vars || theme).palette.text.secondary, + flexDirection: 'column', + flex: '1', + [`&.${bottomNavigationActionClasses.selected}`]: { + color: (theme.vars || theme).palette.primary.main, }, - { - props: ({ showLabel, selected, label }) => !showLabel && !selected && !label, - style: { - paddingTop: 0, + variants: [ + { + props: ({ showLabel, selected }) => !showLabel && !selected, + style: { + paddingTop: 14, + }, }, - }, - ], -})); + { + props: ({ showLabel, selected, label }) => !showLabel && !selected && !label, + style: { + paddingTop: 0, + }, + }, + ], + })), +); const BottomNavigationActionLabel = styled('span', { name: 'MuiBottomNavigationAction', slot: 'Label', overridesResolver: (props, styles) => styles.label, -})(({ theme }) => ({ - fontFamily: theme.typography.fontFamily, - fontSize: theme.typography.pxToRem(12), - opacity: 1, - transition: 'font-size 0.2s, opacity 0.2s', - transitionDelay: '0.1s', - [`&.${bottomNavigationActionClasses.selected}`]: { - fontSize: theme.typography.pxToRem(14), - }, - variants: [ - { - props: ({ showLabel, selected }) => !showLabel && !selected, - style: { - opacity: 0, - transitionDelay: '0s', - }, +})( + memoTheme(({ theme }) => ({ + fontFamily: theme.typography.fontFamily, + fontSize: theme.typography.pxToRem(12), + opacity: 1, + transition: 'font-size 0.2s, opacity 0.2s', + transitionDelay: '0.1s', + [`&.${bottomNavigationActionClasses.selected}`]: { + fontSize: theme.typography.pxToRem(14), }, - ], -})); + variants: [ + { + props: ({ showLabel, selected }) => !showLabel && !selected, + style: { + opacity: 0, + transitionDelay: '0s', + }, + }, + ], + })), +); const BottomNavigationAction = React.forwardRef(function BottomNavigationAction(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiBottomNavigationAction' }); diff --git a/packages/mui-material/src/Breadcrumbs/BreadcrumbCollapsed.js b/packages/mui-material/src/Breadcrumbs/BreadcrumbCollapsed.js index 7a5dc972423cba..5b4f936916a317 100644 --- a/packages/mui-material/src/Breadcrumbs/BreadcrumbCollapsed.js +++ b/packages/mui-material/src/Breadcrumbs/BreadcrumbCollapsed.js @@ -3,29 +3,32 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import { emphasize } from '@mui/system/colorManipulator'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import MoreHorizIcon from '../internal/svg-icons/MoreHoriz'; import ButtonBase from '../ButtonBase'; -const BreadcrumbCollapsedButton = styled(ButtonBase)(({ theme }) => ({ - display: 'flex', - marginLeft: `calc(${theme.spacing(1)} * 0.5)`, - marginRight: `calc(${theme.spacing(1)} * 0.5)`, - ...(theme.palette.mode === 'light' - ? { backgroundColor: theme.palette.grey[100], color: theme.palette.grey[700] } - : { backgroundColor: theme.palette.grey[700], color: theme.palette.grey[100] }), - borderRadius: 2, - '&:hover, &:focus': { +const BreadcrumbCollapsedButton = styled(ButtonBase)( + memoTheme(({ theme }) => ({ + display: 'flex', + marginLeft: `calc(${theme.spacing(1)} * 0.5)`, + marginRight: `calc(${theme.spacing(1)} * 0.5)`, ...(theme.palette.mode === 'light' - ? { backgroundColor: theme.palette.grey[200] } - : { backgroundColor: theme.palette.grey[600] }), - }, - '&:active': { - boxShadow: theme.shadows[0], - ...(theme.palette.mode === 'light' - ? { backgroundColor: emphasize(theme.palette.grey[200], 0.12) } - : { backgroundColor: emphasize(theme.palette.grey[600], 0.12) }), - }, -})); + ? { backgroundColor: theme.palette.grey[100], color: theme.palette.grey[700] } + : { backgroundColor: theme.palette.grey[700], color: theme.palette.grey[100] }), + borderRadius: 2, + '&:hover, &:focus': { + ...(theme.palette.mode === 'light' + ? { backgroundColor: theme.palette.grey[200] } + : { backgroundColor: theme.palette.grey[600] }), + }, + '&:active': { + boxShadow: theme.shadows[0], + ...(theme.palette.mode === 'light' + ? { backgroundColor: emphasize(theme.palette.grey[200], 0.12) } + : { backgroundColor: emphasize(theme.palette.grey[600], 0.12) }), + }, + })), +); const BreadcrumbCollapsedIcon = styled(MoreHorizIcon)({ width: 24, diff --git a/packages/mui-material/src/Button/Button.js b/packages/mui-material/src/Button/Button.js index a61970c0e6ec66..5829312c6e194f 100644 --- a/packages/mui-material/src/Button/Button.js +++ b/packages/mui-material/src/Button/Button.js @@ -7,6 +7,7 @@ import composeClasses from '@mui/utils/composeClasses'; import { alpha } from '@mui/system/colorManipulator'; import rootShouldForwardProp from '../styles/rootShouldForwardProp'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import ButtonBase from '../ButtonBase'; import capitalize from '../utils/capitalize'; @@ -86,218 +87,220 @@ const ButtonRoot = styled(ButtonBase, { ownerState.fullWidth && styles.fullWidth, ]; }, -})(({ theme }) => { - const inheritContainedBackgroundColor = - theme.palette.mode === 'light' ? theme.palette.grey[300] : theme.palette.grey[800]; +})( + memoTheme(({ theme }) => { + const inheritContainedBackgroundColor = + theme.palette.mode === 'light' ? theme.palette.grey[300] : theme.palette.grey[800]; - const inheritContainedHoverBackgroundColor = - theme.palette.mode === 'light' ? theme.palette.grey.A100 : theme.palette.grey[700]; - return { - ...theme.typography.button, - minWidth: 64, - padding: '6px 16px', - border: 0, - borderRadius: (theme.vars || theme).shape.borderRadius, - transition: theme.transitions.create( - ['background-color', 'box-shadow', 'border-color', 'color'], - { - duration: theme.transitions.duration.short, + const inheritContainedHoverBackgroundColor = + theme.palette.mode === 'light' ? theme.palette.grey.A100 : theme.palette.grey[700]; + return { + ...theme.typography.button, + minWidth: 64, + padding: '6px 16px', + border: 0, + borderRadius: (theme.vars || theme).shape.borderRadius, + transition: theme.transitions.create( + ['background-color', 'box-shadow', 'border-color', 'color'], + { + duration: theme.transitions.duration.short, + }, + ), + '&:hover': { + textDecoration: 'none', }, - ), - '&:hover': { - textDecoration: 'none', - }, - [`&.${buttonClasses.disabled}`]: { - color: (theme.vars || theme).palette.action.disabled, - }, - variants: [ - { - props: { variant: 'contained' }, - style: { - color: `var(--variant-containedColor)`, - backgroundColor: `var(--variant-containedBg)`, - boxShadow: (theme.vars || theme).shadows[2], - '&:hover': { - boxShadow: (theme.vars || theme).shadows[4], - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - boxShadow: (theme.vars || theme).shadows[2], + [`&.${buttonClasses.disabled}`]: { + color: (theme.vars || theme).palette.action.disabled, + }, + variants: [ + { + props: { variant: 'contained' }, + style: { + color: `var(--variant-containedColor)`, + backgroundColor: `var(--variant-containedBg)`, + boxShadow: (theme.vars || theme).shadows[2], + '&:hover': { + boxShadow: (theme.vars || theme).shadows[4], + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + boxShadow: (theme.vars || theme).shadows[2], + }, + }, + '&:active': { + boxShadow: (theme.vars || theme).shadows[8], + }, + [`&.${buttonClasses.focusVisible}`]: { + boxShadow: (theme.vars || theme).shadows[6], + }, + [`&.${buttonClasses.disabled}`]: { + color: (theme.vars || theme).palette.action.disabled, + boxShadow: (theme.vars || theme).shadows[0], + backgroundColor: (theme.vars || theme).palette.action.disabledBackground, }, - }, - '&:active': { - boxShadow: (theme.vars || theme).shadows[8], - }, - [`&.${buttonClasses.focusVisible}`]: { - boxShadow: (theme.vars || theme).shadows[6], - }, - [`&.${buttonClasses.disabled}`]: { - color: (theme.vars || theme).palette.action.disabled, - boxShadow: (theme.vars || theme).shadows[0], - backgroundColor: (theme.vars || theme).palette.action.disabledBackground, }, }, - }, - { - props: { variant: 'outlined' }, - style: { - padding: '5px 15px', - border: '1px solid currentColor', - borderColor: `var(--variant-outlinedBorder, currentColor)`, - backgroundColor: `var(--variant-outlinedBg)`, - color: `var(--variant-outlinedColor)`, - [`&.${buttonClasses.disabled}`]: { - border: `1px solid ${(theme.vars || theme).palette.action.disabledBackground}`, + { + props: { variant: 'outlined' }, + style: { + padding: '5px 15px', + border: '1px solid currentColor', + borderColor: `var(--variant-outlinedBorder, currentColor)`, + backgroundColor: `var(--variant-outlinedBg)`, + color: `var(--variant-outlinedColor)`, + [`&.${buttonClasses.disabled}`]: { + border: `1px solid ${(theme.vars || theme).palette.action.disabledBackground}`, + }, }, }, - }, - { - props: { variant: 'text' }, - style: { - padding: '6px 8px', - color: `var(--variant-textColor)`, - backgroundColor: `var(--variant-textBg)`, + { + props: { variant: 'text' }, + style: { + padding: '6px 8px', + color: `var(--variant-textColor)`, + backgroundColor: `var(--variant-textBg)`, + }, }, - }, - ...Object.entries(theme.palette) - .filter(([, palette]) => palette && palette.main && palette.dark && palette.contrastText) - .map(([color]) => ({ - props: { color }, + ...Object.entries(theme.palette) + .filter(([, palette]) => palette && palette.main && palette.dark && palette.contrastText) + .map(([color]) => ({ + props: { color }, + style: { + '--variant-textColor': (theme.vars || theme).palette[color].main, + '--variant-outlinedColor': (theme.vars || theme).palette[color].main, + '--variant-outlinedBorder': theme.vars + ? `rgba(${theme.vars.palette[color].mainChannel} / 0.5)` + : alpha(theme.palette[color].main, 0.5), + '--variant-containedColor': (theme.vars || theme).palette[color].contrastText, + '--variant-containedBg': (theme.vars || theme).palette[color].main, + '@media (hover: hover)': { + '&:hover': { + '--variant-containedBg': (theme.vars || theme).palette[color].dark, + '--variant-textBg': theme.vars + ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.hoverOpacity})` + : alpha(theme.palette[color].main, theme.palette.action.hoverOpacity), + '--variant-outlinedBorder': (theme.vars || theme).palette[color].main, + '--variant-outlinedBg': theme.vars + ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.hoverOpacity})` + : alpha(theme.palette[color].main, theme.palette.action.hoverOpacity), + }, + }, + }, + })), + { + props: { + color: 'inherit', + }, style: { - '--variant-textColor': (theme.vars || theme).palette[color].main, - '--variant-outlinedColor': (theme.vars || theme).palette[color].main, - '--variant-outlinedBorder': theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / 0.5)` - : alpha(theme.palette[color].main, 0.5), - '--variant-containedColor': (theme.vars || theme).palette[color].contrastText, - '--variant-containedBg': (theme.vars || theme).palette[color].main, + '--variant-containedColor': theme.vars + ? // this is safe because grey does not change between default light/dark mode + theme.vars.palette.text.primary + : theme.palette.getContrastText?.(inheritContainedBackgroundColor), + '--variant-containedBg': theme.vars + ? theme.vars.palette.Button.inheritContainedBg + : inheritContainedBackgroundColor, '@media (hover: hover)': { '&:hover': { - '--variant-containedBg': (theme.vars || theme).palette[color].dark, + '--variant-containedBg': theme.vars + ? theme.vars.palette.Button.inheritContainedHoverBg + : inheritContainedHoverBackgroundColor, '--variant-textBg': theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.hoverOpacity})` - : alpha(theme.palette[color].main, theme.palette.action.hoverOpacity), - '--variant-outlinedBorder': (theme.vars || theme).palette[color].main, + ? `rgba(${theme.vars.palette.text.primaryChannel} / ${theme.vars.palette.action.hoverOpacity})` + : alpha(theme.palette.text.primary, theme.palette.action.hoverOpacity), '--variant-outlinedBg': theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.hoverOpacity})` - : alpha(theme.palette[color].main, theme.palette.action.hoverOpacity), + ? `rgba(${theme.vars.palette.text.primaryChannel} / ${theme.vars.palette.action.hoverOpacity})` + : alpha(theme.palette.text.primary, theme.palette.action.hoverOpacity), }, }, }, - })), - { - props: { - color: 'inherit', }, - style: { - '--variant-containedColor': theme.vars - ? // this is safe because grey does not change between default light/dark mode - theme.vars.palette.text.primary - : theme.palette.getContrastText?.(inheritContainedBackgroundColor), - '--variant-containedBg': theme.vars - ? theme.vars.palette.Button.inheritContainedBg - : inheritContainedBackgroundColor, - '@media (hover: hover)': { - '&:hover': { - '--variant-containedBg': theme.vars - ? theme.vars.palette.Button.inheritContainedHoverBg - : inheritContainedHoverBackgroundColor, - '--variant-textBg': theme.vars - ? `rgba(${theme.vars.palette.text.primaryChannel} / ${theme.vars.palette.action.hoverOpacity})` - : alpha(theme.palette.text.primary, theme.palette.action.hoverOpacity), - '--variant-outlinedBg': theme.vars - ? `rgba(${theme.vars.palette.text.primaryChannel} / ${theme.vars.palette.action.hoverOpacity})` - : alpha(theme.palette.text.primary, theme.palette.action.hoverOpacity), - }, + { + props: { + size: 'small', + variant: 'text', + }, + style: { + padding: '4px 5px', + fontSize: theme.typography.pxToRem(13), }, }, - }, - { - props: { - size: 'small', - variant: 'text', - }, - style: { - padding: '4px 5px', - fontSize: theme.typography.pxToRem(13), - }, - }, - { - props: { - size: 'large', - variant: 'text', - }, - style: { - padding: '8px 11px', - fontSize: theme.typography.pxToRem(15), - }, - }, - { - props: { - size: 'small', - variant: 'outlined', - }, - style: { - padding: '3px 9px', - fontSize: theme.typography.pxToRem(13), - }, - }, - { - props: { - size: 'large', - variant: 'outlined', - }, - style: { - padding: '7px 21px', - fontSize: theme.typography.pxToRem(15), - }, - }, - { - props: { - size: 'small', - variant: 'contained', - }, - style: { - padding: '4px 10px', - fontSize: theme.typography.pxToRem(13), + { + props: { + size: 'large', + variant: 'text', + }, + style: { + padding: '8px 11px', + fontSize: theme.typography.pxToRem(15), + }, }, - }, - { - props: { - size: 'large', - variant: 'contained', + { + props: { + size: 'small', + variant: 'outlined', + }, + style: { + padding: '3px 9px', + fontSize: theme.typography.pxToRem(13), + }, }, - style: { - padding: '8px 22px', - fontSize: theme.typography.pxToRem(15), + { + props: { + size: 'large', + variant: 'outlined', + }, + style: { + padding: '7px 21px', + fontSize: theme.typography.pxToRem(15), + }, }, - }, - { - props: { - disableElevation: true, + { + props: { + size: 'small', + variant: 'contained', + }, + style: { + padding: '4px 10px', + fontSize: theme.typography.pxToRem(13), + }, }, - style: { - boxShadow: 'none', - '&:hover': { - boxShadow: 'none', + { + props: { + size: 'large', + variant: 'contained', }, - [`&.${buttonClasses.focusVisible}`]: { - boxShadow: 'none', + style: { + padding: '8px 22px', + fontSize: theme.typography.pxToRem(15), }, - '&:active': { - boxShadow: 'none', + }, + { + props: { + disableElevation: true, }, - [`&.${buttonClasses.disabled}`]: { + style: { boxShadow: 'none', + '&:hover': { + boxShadow: 'none', + }, + [`&.${buttonClasses.focusVisible}`]: { + boxShadow: 'none', + }, + '&:active': { + boxShadow: 'none', + }, + [`&.${buttonClasses.disabled}`]: { + boxShadow: 'none', + }, }, }, - }, - { - props: { fullWidth: true }, - style: { width: '100%' }, - }, - ], - }; -}); + { + props: { fullWidth: true }, + style: { width: '100%' }, + }, + ], + }; + }), +); const ButtonStartIcon = styled('span', { name: 'MuiButton', @@ -307,7 +310,7 @@ const ButtonStartIcon = styled('span', { return [styles.startIcon, styles[`iconSize${capitalize(ownerState.size)}`]]; }, -})(() => ({ +})({ display: 'inherit', marginRight: 8, marginLeft: -4, @@ -320,7 +323,7 @@ const ButtonStartIcon = styled('span', { }, ...commonIconStyles, ], -})); +}); const ButtonEndIcon = styled('span', { name: 'MuiButton', @@ -330,7 +333,7 @@ const ButtonEndIcon = styled('span', { return [styles.endIcon, styles[`iconSize${capitalize(ownerState.size)}`]]; }, -})(() => ({ +})({ display: 'inherit', marginRight: -4, marginLeft: 8, @@ -343,7 +346,7 @@ const ButtonEndIcon = styled('span', { }, ...commonIconStyles, ], -})); +}); const Button = React.forwardRef(function Button(inProps, ref) { // props priority: `inProps` > `contextProps` > `themeDefaultProps` diff --git a/packages/mui-material/src/ButtonGroup/ButtonGroup.js b/packages/mui-material/src/ButtonGroup/ButtonGroup.js index 0486a079366ffe..981f8a2b7609b8 100644 --- a/packages/mui-material/src/ButtonGroup/ButtonGroup.js +++ b/packages/mui-material/src/ButtonGroup/ButtonGroup.js @@ -7,6 +7,7 @@ import { alpha } from '@mui/system/colorManipulator'; import getValidReactChildren from '@mui/utils/getValidReactChildren'; import capitalize from '../utils/capitalize'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import buttonGroupClasses, { getButtonGroupUtilityClass } from './buttonGroupClasses'; import ButtonGroupContext from './ButtonGroupContext'; @@ -79,171 +80,177 @@ const ButtonGroupRoot = styled('div', { name: 'MuiButtonGroup', slot: 'Root', overridesResolver, -})(({ theme }) => ({ - display: 'inline-flex', - borderRadius: (theme.vars || theme).shape.borderRadius, - variants: [ - { - props: { variant: 'contained' }, - style: { - boxShadow: (theme.vars || theme).shadows[2], - }, - }, - { - props: { disableElevation: true }, - style: { - boxShadow: 'none', - }, - }, - { - props: { fullWidth: true }, - style: { - width: '100%', - }, - }, - { - props: { orientation: 'vertical' }, - style: { - flexDirection: 'column', - [`& .${buttonGroupClasses.lastButton},& .${buttonGroupClasses.middleButton}`]: { - borderTopRightRadius: 0, - borderTopLeftRadius: 0, - }, - [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { - borderBottomRightRadius: 0, - borderBottomLeftRadius: 0, +})( + memoTheme(({ theme }) => ({ + display: 'inline-flex', + borderRadius: (theme.vars || theme).shape.borderRadius, + variants: [ + { + props: { variant: 'contained' }, + style: { + boxShadow: (theme.vars || theme).shadows[2], }, }, - }, - { - props: { orientation: 'horizontal' }, - style: { - [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { - borderTopRightRadius: 0, - borderBottomRightRadius: 0, + { + props: { disableElevation: true }, + style: { + boxShadow: 'none', }, - [`& .${buttonGroupClasses.lastButton},& .${buttonGroupClasses.middleButton}`]: { - borderTopLeftRadius: 0, - borderBottomLeftRadius: 0, + }, + { + props: { fullWidth: true }, + style: { + width: '100%', }, }, - }, - { - props: { variant: 'text', orientation: 'horizontal' }, - style: { - [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { - borderRight: theme.vars - ? `1px solid rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.23)` - : `1px solid ${ - theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)' - }`, - [`&.${buttonGroupClasses.disabled}`]: { - borderRight: `1px solid ${(theme.vars || theme).palette.action.disabled}`, + { + props: { orientation: 'vertical' }, + style: { + flexDirection: 'column', + [`& .${buttonGroupClasses.lastButton},& .${buttonGroupClasses.middleButton}`]: { + borderTopRightRadius: 0, + borderTopLeftRadius: 0, + }, + [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { + borderBottomRightRadius: 0, + borderBottomLeftRadius: 0, }, }, }, - }, - { - props: { variant: 'text', orientation: 'vertical' }, - style: { - [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { - borderBottom: theme.vars - ? `1px solid rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.23)` - : `1px solid ${ - theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)' - }`, - [`&.${buttonGroupClasses.disabled}`]: { - borderBottom: `1px solid ${(theme.vars || theme).palette.action.disabled}`, + { + props: { orientation: 'horizontal' }, + style: { + [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { + borderTopRightRadius: 0, + borderBottomRightRadius: 0, + }, + [`& .${buttonGroupClasses.lastButton},& .${buttonGroupClasses.middleButton}`]: { + borderTopLeftRadius: 0, + borderBottomLeftRadius: 0, }, }, }, - }, - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main) - .flatMap(([color]) => [ - { - props: { variant: 'text', color }, - style: { - [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { - borderColor: theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / 0.5)` - : alpha(theme.palette[color].main, 0.5), + { + props: { variant: 'text', orientation: 'horizontal' }, + style: { + [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { + borderRight: theme.vars + ? `1px solid rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.23)` + : `1px solid ${ + theme.palette.mode === 'light' + ? 'rgba(0, 0, 0, 0.23)' + : 'rgba(255, 255, 255, 0.23)' + }`, + [`&.${buttonGroupClasses.disabled}`]: { + borderRight: `1px solid ${(theme.vars || theme).palette.action.disabled}`, }, }, }, - ]), - { - props: { variant: 'outlined', orientation: 'horizontal' }, - style: { - [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { - borderRightColor: 'transparent', - '&:hover': { - borderRightColor: 'currentColor', + }, + { + props: { variant: 'text', orientation: 'vertical' }, + style: { + [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { + borderBottom: theme.vars + ? `1px solid rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.23)` + : `1px solid ${ + theme.palette.mode === 'light' + ? 'rgba(0, 0, 0, 0.23)' + : 'rgba(255, 255, 255, 0.23)' + }`, + [`&.${buttonGroupClasses.disabled}`]: { + borderBottom: `1px solid ${(theme.vars || theme).palette.action.disabled}`, + }, }, }, - [`& .${buttonGroupClasses.lastButton},& .${buttonGroupClasses.middleButton}`]: { - marginLeft: -1, - }, }, - }, - { - props: { variant: 'outlined', orientation: 'vertical' }, - style: { - [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { - borderBottomColor: 'transparent', - '&:hover': { - borderBottomColor: 'currentColor', + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main) + .flatMap(([color]) => [ + { + props: { variant: 'text', color }, + style: { + [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { + borderColor: theme.vars + ? `rgba(${theme.vars.palette[color].mainChannel} / 0.5)` + : alpha(theme.palette[color].main, 0.5), + }, + }, + }, + ]), + { + props: { variant: 'outlined', orientation: 'horizontal' }, + style: { + [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { + borderRightColor: 'transparent', + '&:hover': { + borderRightColor: 'currentColor', + }, + }, + [`& .${buttonGroupClasses.lastButton},& .${buttonGroupClasses.middleButton}`]: { + marginLeft: -1, }, - }, - [`& .${buttonGroupClasses.lastButton},& .${buttonGroupClasses.middleButton}`]: { - marginTop: -1, }, }, - }, - { - props: { variant: 'contained', orientation: 'horizontal' }, - style: { - [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { - borderRight: `1px solid ${(theme.vars || theme).palette.grey[400]}`, - [`&.${buttonGroupClasses.disabled}`]: { - borderRight: `1px solid ${(theme.vars || theme).palette.action.disabled}`, + { + props: { variant: 'outlined', orientation: 'vertical' }, + style: { + [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { + borderBottomColor: 'transparent', + '&:hover': { + borderBottomColor: 'currentColor', + }, + }, + [`& .${buttonGroupClasses.lastButton},& .${buttonGroupClasses.middleButton}`]: { + marginTop: -1, }, }, }, - }, - { - props: { variant: 'contained', orientation: 'vertical' }, - style: { - [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { - borderBottom: `1px solid ${(theme.vars || theme).palette.grey[400]}`, - [`&.${buttonGroupClasses.disabled}`]: { - borderBottom: `1px solid ${(theme.vars || theme).palette.action.disabled}`, + { + props: { variant: 'contained', orientation: 'horizontal' }, + style: { + [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { + borderRight: `1px solid ${(theme.vars || theme).palette.grey[400]}`, + [`&.${buttonGroupClasses.disabled}`]: { + borderRight: `1px solid ${(theme.vars || theme).palette.action.disabled}`, + }, }, }, }, - }, - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.dark) - .map(([color]) => ({ - props: { variant: 'contained', color }, + { + props: { variant: 'contained', orientation: 'vertical' }, style: { [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { - borderColor: (theme.vars || theme).palette[color].dark, + borderBottom: `1px solid ${(theme.vars || theme).palette.grey[400]}`, + [`&.${buttonGroupClasses.disabled}`]: { + borderBottom: `1px solid ${(theme.vars || theme).palette.action.disabled}`, + }, + }, + }, + }, + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.dark) + .map(([color]) => ({ + props: { variant: 'contained', color }, + style: { + [`& .${buttonGroupClasses.firstButton},& .${buttonGroupClasses.middleButton}`]: { + borderColor: (theme.vars || theme).palette[color].dark, + }, }, + })), + ], + [`& .${buttonGroupClasses.grouped}`]: { + minWidth: 40, + boxShadow: 'none', + props: { variant: 'contained' }, + style: { + '&:hover': { + boxShadow: 'none', }, - })), - ], - [`& .${buttonGroupClasses.grouped}`]: { - minWidth: 40, - boxShadow: 'none', - props: { variant: 'contained' }, - style: { - '&:hover': { - boxShadow: 'none', }, }, - }, -})); + })), +); const ButtonGroup = React.forwardRef(function ButtonGroup(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiButtonGroup' }); diff --git a/packages/mui-material/src/CardActionArea/CardActionArea.js b/packages/mui-material/src/CardActionArea/CardActionArea.js index f6b5168e3ccc4b..c7674b63f86aca 100644 --- a/packages/mui-material/src/CardActionArea/CardActionArea.js +++ b/packages/mui-material/src/CardActionArea/CardActionArea.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import cardActionAreaClasses, { getCardActionAreaUtilityClass } from './cardActionAreaClasses'; import ButtonBase from '../ButtonBase'; @@ -23,41 +24,45 @@ const CardActionAreaRoot = styled(ButtonBase, { name: 'MuiCardActionArea', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})(({ theme }) => ({ - display: 'block', - textAlign: 'inherit', - borderRadius: 'inherit', // for Safari to work https://github.com/mui/material-ui/issues/36285. - width: '100%', - [`&:hover .${cardActionAreaClasses.focusHighlight}`]: { - opacity: (theme.vars || theme).palette.action.hoverOpacity, - '@media (hover: none)': { - opacity: 0, +})( + memoTheme(({ theme }) => ({ + display: 'block', + textAlign: 'inherit', + borderRadius: 'inherit', // for Safari to work https://github.com/mui/material-ui/issues/36285. + width: '100%', + [`&:hover .${cardActionAreaClasses.focusHighlight}`]: { + opacity: (theme.vars || theme).palette.action.hoverOpacity, + '@media (hover: none)': { + opacity: 0, + }, }, - }, - [`&.${cardActionAreaClasses.focusVisible} .${cardActionAreaClasses.focusHighlight}`]: { - opacity: (theme.vars || theme).palette.action.focusOpacity, - }, -})); + [`&.${cardActionAreaClasses.focusVisible} .${cardActionAreaClasses.focusHighlight}`]: { + opacity: (theme.vars || theme).palette.action.focusOpacity, + }, + })), +); const CardActionAreaFocusHighlight = styled('span', { name: 'MuiCardActionArea', slot: 'FocusHighlight', overridesResolver: (props, styles) => styles.focusHighlight, -})(({ theme }) => ({ - overflow: 'hidden', - pointerEvents: 'none', - position: 'absolute', - top: 0, - right: 0, - bottom: 0, - left: 0, - borderRadius: 'inherit', - opacity: 0, - backgroundColor: 'currentcolor', - transition: theme.transitions.create('opacity', { - duration: theme.transitions.duration.short, - }), -})); +})( + memoTheme(({ theme }) => ({ + overflow: 'hidden', + pointerEvents: 'none', + position: 'absolute', + top: 0, + right: 0, + bottom: 0, + left: 0, + borderRadius: 'inherit', + opacity: 0, + backgroundColor: 'currentcolor', + transition: theme.transitions.create('opacity', { + duration: theme.transitions.duration.short, + }), + })), +); const CardActionArea = React.forwardRef(function CardActionArea(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiCardActionArea' }); diff --git a/packages/mui-material/src/Checkbox/Checkbox.js b/packages/mui-material/src/Checkbox/Checkbox.js index 9f76fc068f4d78..741d83b483339e 100644 --- a/packages/mui-material/src/Checkbox/Checkbox.js +++ b/packages/mui-material/src/Checkbox/Checkbox.js @@ -13,6 +13,7 @@ import capitalize from '../utils/capitalize'; import rootShouldForwardProp from '../styles/rootShouldForwardProp'; import checkboxClasses, { getCheckboxUtilityClass } from './checkboxClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; @@ -50,58 +51,60 @@ const CheckboxRoot = styled(SwitchBase, { ownerState.color !== 'default' && styles[`color${capitalize(ownerState.color)}`], ]; }, -})(({ theme }) => ({ - color: (theme.vars || theme).palette.text.secondary, - variants: [ - { - props: { color: 'default', disableRipple: false }, - style: { - '&:hover': { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.action.activeChannel} / ${theme.vars.palette.action.hoverOpacity})` - : alpha(theme.palette.action.active, theme.palette.action.hoverOpacity), - }, - }, - }, - ...Object.entries(theme.palette) - .filter(([, palette]) => palette && palette.main) - .map(([color]) => ({ - props: { color, disableRipple: false }, +})( + memoTheme(({ theme }) => ({ + color: (theme.vars || theme).palette.text.secondary, + variants: [ + { + props: { color: 'default', disableRipple: false }, style: { '&:hover': { backgroundColor: theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.hoverOpacity})` - : alpha(theme.palette[color].main, theme.palette.action.hoverOpacity), + ? `rgba(${theme.vars.palette.action.activeChannel} / ${theme.vars.palette.action.hoverOpacity})` + : alpha(theme.palette.action.active, theme.palette.action.hoverOpacity), }, }, - })), - ...Object.entries(theme.palette) - .filter(([, palette]) => palette && palette.main) - .map(([color]) => ({ - props: { color }, - style: { - [`&.${checkboxClasses.checked}, &.${checkboxClasses.indeterminate}`]: { - color: (theme.vars || theme).palette[color].main, + }, + ...Object.entries(theme.palette) + .filter(([, palette]) => palette && palette.main) + .map(([color]) => ({ + props: { color, disableRipple: false }, + style: { + '&:hover': { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.hoverOpacity})` + : alpha(theme.palette[color].main, theme.palette.action.hoverOpacity), + }, }, - [`&.${checkboxClasses.disabled}`]: { - color: (theme.vars || theme).palette.action.disabled, + })), + ...Object.entries(theme.palette) + .filter(([, palette]) => palette && palette.main) + .map(([color]) => ({ + props: { color }, + style: { + [`&.${checkboxClasses.checked}, &.${checkboxClasses.indeterminate}`]: { + color: (theme.vars || theme).palette[color].main, + }, + [`&.${checkboxClasses.disabled}`]: { + color: (theme.vars || theme).palette.action.disabled, + }, }, - }, - })), - { - // Should be last to override other colors - props: { disableRipple: false }, - style: { - // Reset on touch devices, it doesn't add specificity - '&:hover': { - '@media (hover: none)': { - backgroundColor: 'transparent', + })), + { + // Should be last to override other colors + props: { disableRipple: false }, + style: { + // Reset on touch devices, it doesn't add specificity + '&:hover': { + '@media (hover: none)': { + backgroundColor: 'transparent', + }, }, }, }, - }, - ], -})); + ], + })), +); const defaultCheckedIcon = ; const defaultIcon = ; diff --git a/packages/mui-material/src/Chip/Chip.js b/packages/mui-material/src/Chip/Chip.js index 9b42fef06e4edb..bea43f06e19903 100644 --- a/packages/mui-material/src/Chip/Chip.js +++ b/packages/mui-material/src/Chip/Chip.js @@ -10,6 +10,7 @@ import unsupportedProp from '../utils/unsupportedProp'; import capitalize from '../utils/capitalize'; import ButtonBase from '../ButtonBase'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import chipClasses, { getChipUtilityClass } from './chipClasses'; @@ -75,259 +76,261 @@ const ChipRoot = styled('div', { styles[`${variant}${capitalize(color)}`], ]; }, -})(({ theme }) => { - const textColor = - theme.palette.mode === 'light' ? theme.palette.grey[700] : theme.palette.grey[300]; - return { - maxWidth: '100%', - fontFamily: theme.typography.fontFamily, - fontSize: theme.typography.pxToRem(13), - display: 'inline-flex', - alignItems: 'center', - justifyContent: 'center', - height: 32, - color: (theme.vars || theme).palette.text.primary, - backgroundColor: (theme.vars || theme).palette.action.selected, - borderRadius: 32 / 2, - whiteSpace: 'nowrap', - transition: theme.transitions.create(['background-color', 'box-shadow']), - // reset cursor explicitly in case ButtonBase is used - cursor: 'unset', - // We disable the focus ring for mouse, touch and keyboard users. - outline: 0, - textDecoration: 'none', - border: 0, // Remove `button` border - padding: 0, // Remove `button` padding - verticalAlign: 'middle', - boxSizing: 'border-box', - [`&.${chipClasses.disabled}`]: { - opacity: (theme.vars || theme).palette.action.disabledOpacity, - pointerEvents: 'none', - }, - [`& .${chipClasses.avatar}`]: { - marginLeft: 5, - marginRight: -6, - width: 24, - height: 24, - color: theme.vars ? theme.vars.palette.Chip.defaultAvatarColor : textColor, - fontSize: theme.typography.pxToRem(12), - }, - [`& .${chipClasses.avatarColorPrimary}`]: { - color: (theme.vars || theme).palette.primary.contrastText, - backgroundColor: (theme.vars || theme).palette.primary.dark, - }, - [`& .${chipClasses.avatarColorSecondary}`]: { - color: (theme.vars || theme).palette.secondary.contrastText, - backgroundColor: (theme.vars || theme).palette.secondary.dark, - }, - [`& .${chipClasses.avatarSmall}`]: { - marginLeft: 4, - marginRight: -4, - width: 18, - height: 18, - fontSize: theme.typography.pxToRem(10), - }, - [`& .${chipClasses.icon}`]: { - marginLeft: 5, - marginRight: -6, - }, - [`& .${chipClasses.deleteIcon}`]: { - WebkitTapHighlightColor: 'transparent', - color: theme.vars - ? `rgba(${theme.vars.palette.text.primaryChannel} / 0.26)` - : alpha(theme.palette.text.primary, 0.26), - fontSize: 22, - cursor: 'pointer', - margin: '0 5px 0 -6px', - '&:hover': { +})( + memoTheme(({ theme }) => { + const textColor = + theme.palette.mode === 'light' ? theme.palette.grey[700] : theme.palette.grey[300]; + return { + maxWidth: '100%', + fontFamily: theme.typography.fontFamily, + fontSize: theme.typography.pxToRem(13), + display: 'inline-flex', + alignItems: 'center', + justifyContent: 'center', + height: 32, + color: (theme.vars || theme).palette.text.primary, + backgroundColor: (theme.vars || theme).palette.action.selected, + borderRadius: 32 / 2, + whiteSpace: 'nowrap', + transition: theme.transitions.create(['background-color', 'box-shadow']), + // reset cursor explicitly in case ButtonBase is used + cursor: 'unset', + // We disable the focus ring for mouse, touch and keyboard users. + outline: 0, + textDecoration: 'none', + border: 0, // Remove `button` border + padding: 0, // Remove `button` padding + verticalAlign: 'middle', + boxSizing: 'border-box', + [`&.${chipClasses.disabled}`]: { + opacity: (theme.vars || theme).palette.action.disabledOpacity, + pointerEvents: 'none', + }, + [`& .${chipClasses.avatar}`]: { + marginLeft: 5, + marginRight: -6, + width: 24, + height: 24, + color: theme.vars ? theme.vars.palette.Chip.defaultAvatarColor : textColor, + fontSize: theme.typography.pxToRem(12), + }, + [`& .${chipClasses.avatarColorPrimary}`]: { + color: (theme.vars || theme).palette.primary.contrastText, + backgroundColor: (theme.vars || theme).palette.primary.dark, + }, + [`& .${chipClasses.avatarColorSecondary}`]: { + color: (theme.vars || theme).palette.secondary.contrastText, + backgroundColor: (theme.vars || theme).palette.secondary.dark, + }, + [`& .${chipClasses.avatarSmall}`]: { + marginLeft: 4, + marginRight: -4, + width: 18, + height: 18, + fontSize: theme.typography.pxToRem(10), + }, + [`& .${chipClasses.icon}`]: { + marginLeft: 5, + marginRight: -6, + }, + [`& .${chipClasses.deleteIcon}`]: { + WebkitTapHighlightColor: 'transparent', color: theme.vars - ? `rgba(${theme.vars.palette.text.primaryChannel} / 0.4)` - : alpha(theme.palette.text.primary, 0.4), + ? `rgba(${theme.vars.palette.text.primaryChannel} / 0.26)` + : alpha(theme.palette.text.primary, 0.26), + fontSize: 22, + cursor: 'pointer', + margin: '0 5px 0 -6px', + '&:hover': { + color: theme.vars + ? `rgba(${theme.vars.palette.text.primaryChannel} / 0.4)` + : alpha(theme.palette.text.primary, 0.4), + }, }, - }, - variants: [ - { - props: { size: 'small' }, - style: { - height: 24, - [`& .${chipClasses.icon}`]: { - fontSize: 18, - marginLeft: 4, - marginRight: -4, - }, - [`& .${chipClasses.deleteIcon}`]: { - fontSize: 16, - marginRight: 4, - marginLeft: -4, + variants: [ + { + props: { size: 'small' }, + style: { + height: 24, + [`& .${chipClasses.icon}`]: { + fontSize: 18, + marginLeft: 4, + marginRight: -4, + }, + [`& .${chipClasses.deleteIcon}`]: { + fontSize: 16, + marginRight: 4, + marginLeft: -4, + }, }, }, - }, - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main && value.contrastText) - .map(([color]) => { - return { - props: { color }, - style: { - backgroundColor: (theme.vars || theme).palette[color].main, - color: (theme.vars || theme).palette[color].contrastText, - [`& .${chipClasses.deleteIcon}`]: { - color: theme.vars - ? `rgba(${theme.vars.palette[color].contrastTextChannel} / 0.7)` - : alpha(theme.palette[color].contrastText, 0.7), - '&:hover, &:active': { - color: (theme.vars || theme).palette[color].contrastText, + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main && value.contrastText) + .map(([color]) => { + return { + props: { color }, + style: { + backgroundColor: (theme.vars || theme).palette[color].main, + color: (theme.vars || theme).palette[color].contrastText, + [`& .${chipClasses.deleteIcon}`]: { + color: theme.vars + ? `rgba(${theme.vars.palette[color].contrastTextChannel} / 0.7)` + : alpha(theme.palette[color].contrastText, 0.7), + '&:hover, &:active': { + color: (theme.vars || theme).palette[color].contrastText, + }, }, }, + }; + }), + { + props: (props) => props.iconColor === props.color, + style: { + [`& .${chipClasses.icon}`]: { + color: theme.vars ? theme.vars.palette.Chip.defaultIconColor : textColor, }, - }; - }), - { - props: (props) => props.iconColor === props.color, - style: { - [`& .${chipClasses.icon}`]: { - color: theme.vars ? theme.vars.palette.Chip.defaultIconColor : textColor, }, }, - }, - { - props: (props) => props.iconColor === props.color && props.color !== 'default', - style: { - [`& .${chipClasses.icon}`]: { - color: 'inherit', - }, - }, - }, - { - props: { onDelete: true }, - style: { - [`&.${chipClasses.focusVisible}`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.action.selectedChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))` - : alpha( - theme.palette.action.selected, - theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity, - ), + { + props: (props) => props.iconColor === props.color && props.color !== 'default', + style: { + [`& .${chipClasses.icon}`]: { + color: 'inherit', + }, }, }, - }, - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.dark) - .map(([color]) => { - return { - props: { color, onDelete: true }, - style: { - [`&.${chipClasses.focusVisible}`]: { - background: (theme.vars || theme).palette[color].dark, - }, + { + props: { onDelete: true }, + style: { + [`&.${chipClasses.focusVisible}`]: { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.action.selectedChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))` + : alpha( + theme.palette.action.selected, + theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity, + ), }, - }; - }), - { - props: { clickable: true }, - style: { - userSelect: 'none', - WebkitTapHighlightColor: 'transparent', - cursor: 'pointer', - '&:hover': { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.action.selectedChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` - : alpha( - theme.palette.action.selected, - theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, - ), - }, - [`&.${chipClasses.focusVisible}`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.action.selectedChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))` - : alpha( - theme.palette.action.selected, - theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity, - ), - }, - '&:active': { - boxShadow: (theme.vars || theme).shadows[1], }, }, - }, - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.dark) - .map(([color]) => ({ - props: { color, clickable: true }, + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.dark) + .map(([color]) => { + return { + props: { color, onDelete: true }, + style: { + [`&.${chipClasses.focusVisible}`]: { + background: (theme.vars || theme).palette[color].dark, + }, + }, + }; + }), + { + props: { clickable: true }, style: { - [`&:hover, &.${chipClasses.focusVisible}`]: { - backgroundColor: (theme.vars || theme).palette[color].dark, + userSelect: 'none', + WebkitTapHighlightColor: 'transparent', + cursor: 'pointer', + '&:hover': { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.action.selectedChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` + : alpha( + theme.palette.action.selected, + theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, + ), + }, + [`&.${chipClasses.focusVisible}`]: { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.action.selectedChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))` + : alpha( + theme.palette.action.selected, + theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity, + ), + }, + '&:active': { + boxShadow: (theme.vars || theme).shadows[1], }, - }, - })), - { - props: { variant: 'outlined' }, - style: { - backgroundColor: 'transparent', - border: theme.vars - ? `1px solid ${theme.vars.palette.Chip.defaultBorder}` - : `1px solid ${ - theme.palette.mode === 'light' ? theme.palette.grey[400] : theme.palette.grey[700] - }`, - [`&.${chipClasses.clickable}:hover`]: { - backgroundColor: (theme.vars || theme).palette.action.hover, - }, - [`&.${chipClasses.focusVisible}`]: { - backgroundColor: (theme.vars || theme).palette.action.focus, - }, - [`& .${chipClasses.avatar}`]: { - marginLeft: 4, - }, - [`& .${chipClasses.avatarSmall}`]: { - marginLeft: 2, - }, - [`& .${chipClasses.icon}`]: { - marginLeft: 4, - }, - [`& .${chipClasses.iconSmall}`]: { - marginLeft: 2, - }, - [`& .${chipClasses.deleteIcon}`]: { - marginRight: 5, - }, - [`& .${chipClasses.deleteIconSmall}`]: { - marginRight: 3, }, }, - }, - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main) // no need to check for mainChannel as it's calculated from main - .map(([color]) => ({ - props: { variant: 'outlined', color }, + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.dark) + .map(([color]) => ({ + props: { color, clickable: true }, + style: { + [`&:hover, &.${chipClasses.focusVisible}`]: { + backgroundColor: (theme.vars || theme).palette[color].dark, + }, + }, + })), + { + props: { variant: 'outlined' }, style: { - color: (theme.vars || theme).palette[color].main, - border: `1px solid ${ - theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / 0.7)` - : alpha(theme.palette[color].main, 0.7) - }`, + backgroundColor: 'transparent', + border: theme.vars + ? `1px solid ${theme.vars.palette.Chip.defaultBorder}` + : `1px solid ${ + theme.palette.mode === 'light' ? theme.palette.grey[400] : theme.palette.grey[700] + }`, [`&.${chipClasses.clickable}:hover`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.hoverOpacity})` - : alpha(theme.palette[color].main, theme.palette.action.hoverOpacity), + backgroundColor: (theme.vars || theme).palette.action.hover, }, [`&.${chipClasses.focusVisible}`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.focusOpacity})` - : alpha(theme.palette[color].main, theme.palette.action.focusOpacity), + backgroundColor: (theme.vars || theme).palette.action.focus, + }, + [`& .${chipClasses.avatar}`]: { + marginLeft: 4, + }, + [`& .${chipClasses.avatarSmall}`]: { + marginLeft: 2, + }, + [`& .${chipClasses.icon}`]: { + marginLeft: 4, + }, + [`& .${chipClasses.iconSmall}`]: { + marginLeft: 2, }, [`& .${chipClasses.deleteIcon}`]: { - color: theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / 0.7)` - : alpha(theme.palette[color].main, 0.7), - '&:hover, &:active': { - color: (theme.vars || theme).palette[color].main, - }, + marginRight: 5, + }, + [`& .${chipClasses.deleteIconSmall}`]: { + marginRight: 3, }, }, - })), - ], - }; -}); + }, + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main) // no need to check for mainChannel as it's calculated from main + .map(([color]) => ({ + props: { variant: 'outlined', color }, + style: { + color: (theme.vars || theme).palette[color].main, + border: `1px solid ${ + theme.vars + ? `rgba(${theme.vars.palette[color].mainChannel} / 0.7)` + : alpha(theme.palette[color].main, 0.7) + }`, + [`&.${chipClasses.clickable}:hover`]: { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.hoverOpacity})` + : alpha(theme.palette[color].main, theme.palette.action.hoverOpacity), + }, + [`&.${chipClasses.focusVisible}`]: { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.focusOpacity})` + : alpha(theme.palette[color].main, theme.palette.action.focusOpacity), + }, + [`& .${chipClasses.deleteIcon}`]: { + color: theme.vars + ? `rgba(${theme.vars.palette[color].mainChannel} / 0.7)` + : alpha(theme.palette[color].main, 0.7), + '&:hover, &:active': { + color: (theme.vars || theme).palette[color].main, + }, + }, + }, + })), + ], + }; + }), +); const ChipLabel = styled('span', { name: 'MuiChip', diff --git a/packages/mui-material/src/CircularProgress/CircularProgress.js b/packages/mui-material/src/CircularProgress/CircularProgress.js index 68fa5a0e4143eb..88746f36205e9e 100644 --- a/packages/mui-material/src/CircularProgress/CircularProgress.js +++ b/packages/mui-material/src/CircularProgress/CircularProgress.js @@ -5,6 +5,7 @@ import clsx from 'clsx'; import chainPropTypes from '@mui/utils/chainPropTypes'; import composeClasses from '@mui/utils/composeClasses'; import { keyframes, css, styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import capitalize from '../utils/capitalize'; import { getCircularProgressUtilityClass } from './circularProgressClasses'; @@ -79,35 +80,37 @@ const CircularProgressRoot = styled('span', { styles[`color${capitalize(ownerState.color)}`], ]; }, -})(({ theme }) => ({ - display: 'inline-block', - variants: [ - { - props: { - variant: 'determinate', - }, - style: { - transition: theme.transitions.create('transform'), - }, - }, - { - props: { - variant: 'indeterminate', - }, - style: rotateAnimation || { - animation: `${circularRotateKeyframe} 1.4s linear infinite`, - }, - }, - ...Object.entries(theme.palette) - .filter(([, palette]) => palette && palette.main) - .map(([color]) => ({ - props: { color }, +})( + memoTheme(({ theme }) => ({ + display: 'inline-block', + variants: [ + { + props: { + variant: 'determinate', + }, style: { - color: (theme.vars || theme).palette[color].main, + transition: theme.transitions.create('transform'), }, - })), - ], -})); + }, + { + props: { + variant: 'indeterminate', + }, + style: rotateAnimation || { + animation: `${circularRotateKeyframe} 1.4s linear infinite`, + }, + }, + ...Object.entries(theme.palette) + .filter(([, palette]) => palette && palette.main) + .map(([color]) => ({ + props: { color }, + style: { + color: (theme.vars || theme).palette[color].main, + }, + })), + ], + })), +); const CircularProgressSVG = styled('svg', { name: 'MuiCircularProgress', @@ -129,37 +132,39 @@ const CircularProgressCircle = styled('circle', { ownerState.disableShrink && styles.circleDisableShrink, ]; }, -})(({ theme }) => ({ - stroke: 'currentColor', - variants: [ - { - props: { - variant: 'determinate', - }, - style: { - transition: theme.transitions.create('stroke-dashoffset'), - }, - }, - { - props: { - variant: 'indeterminate', +})( + memoTheme(({ theme }) => ({ + stroke: 'currentColor', + variants: [ + { + props: { + variant: 'determinate', + }, + style: { + transition: theme.transitions.create('stroke-dashoffset'), + }, }, - style: { - // Some default value that looks fine waiting for the animation to kicks in. - strokeDasharray: '80px, 200px', - strokeDashoffset: 0, // Add the unit to fix a Edge 16 and below bug. + { + props: { + variant: 'indeterminate', + }, + style: { + // Some default value that looks fine waiting for the animation to kicks in. + strokeDasharray: '80px, 200px', + strokeDashoffset: 0, // Add the unit to fix a Edge 16 and below bug. + }, }, - }, - { - props: ({ ownerState }) => - ownerState.variant === 'indeterminate' && !ownerState.disableShrink, - style: dashAnimation || { - // At runtime for Pigment CSS, `bufferAnimation` will be null and the generated keyframe will be used. - animation: `${circularDashKeyframe} 1.4s ease-in-out infinite`, + { + props: ({ ownerState }) => + ownerState.variant === 'indeterminate' && !ownerState.disableShrink, + style: dashAnimation || { + // At runtime for Pigment CSS, `bufferAnimation` will be null and the generated keyframe will be used. + animation: `${circularDashKeyframe} 1.4s ease-in-out infinite`, + }, }, - }, - ], -})); + ], + })), +); /** * ## ARIA diff --git a/packages/mui-material/src/Collapse/Collapse.js b/packages/mui-material/src/Collapse/Collapse.js index dcb6dd2ec21da0..276056ecd58d1e 100644 --- a/packages/mui-material/src/Collapse/Collapse.js +++ b/packages/mui-material/src/Collapse/Collapse.js @@ -7,6 +7,7 @@ import useTimeout from '@mui/utils/useTimeout'; import elementTypeAcceptingRef from '@mui/utils/elementTypeAcceptingRef'; import composeClasses from '@mui/utils/composeClasses'; import { styled, useTheme } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import { duration } from '../styles/createTransitions'; import { getTransitionProps } from '../transitions/utils'; @@ -43,48 +44,50 @@ const CollapseRoot = styled('div', { styles.hidden, ]; }, -})(({ theme }) => ({ - height: 0, - overflow: 'hidden', - transition: theme.transitions.create('height'), - variants: [ - { - props: { - orientation: 'horizontal', - }, - style: { - height: 'auto', - width: 0, - transition: theme.transitions.create('width'), - }, - }, - { - props: { - state: 'entered', - }, - style: { - height: 'auto', - overflow: 'visible', +})( + memoTheme(({ theme }) => ({ + height: 0, + overflow: 'hidden', + transition: theme.transitions.create('height'), + variants: [ + { + props: { + orientation: 'horizontal', + }, + style: { + height: 'auto', + width: 0, + transition: theme.transitions.create('width'), + }, }, - }, - { - props: { - state: 'entered', - orientation: 'horizontal', + { + props: { + state: 'entered', + }, + style: { + height: 'auto', + overflow: 'visible', + }, }, - style: { - width: 'auto', + { + props: { + state: 'entered', + orientation: 'horizontal', + }, + style: { + width: 'auto', + }, }, - }, - { - props: ({ ownerState }) => - ownerState.state === 'exited' && !ownerState.in && ownerState.collapsedSize === '0px', - style: { - visibility: 'hidden', + { + props: ({ ownerState }) => + ownerState.state === 'exited' && !ownerState.in && ownerState.collapsedSize === '0px', + style: { + visibility: 'hidden', + }, }, - }, - ], -})); + ], + })), +); const CollapseWrapper = styled('div', { name: 'MuiCollapse', diff --git a/packages/mui-material/src/Dialog/Dialog.js b/packages/mui-material/src/Dialog/Dialog.js index 443347ed1b5388..49b220ae076e35 100644 --- a/packages/mui-material/src/Dialog/Dialog.js +++ b/packages/mui-material/src/Dialog/Dialog.js @@ -12,6 +12,7 @@ import dialogClasses, { getDialogUtilityClass } from './dialogClasses'; import DialogContext from './DialogContext'; import Backdrop from '../Backdrop'; import { styled, useTheme } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; @@ -113,92 +114,94 @@ const DialogPaper = styled(Paper, { ownerState.fullScreen && styles.paperFullScreen, ]; }, -})(({ theme }) => ({ - margin: 32, - position: 'relative', - '@media print': { - overflowY: 'visible', - boxShadow: 'none', - }, - variants: [ - { - props: { - scroll: 'paper', - }, - style: { - display: 'flex', - flexDirection: 'column', - maxHeight: 'calc(100% - 64px)', - }, - }, - { - props: { - scroll: 'body', - }, - style: { - display: 'inline-block', - verticalAlign: 'middle', - textAlign: 'initial', - }, +})( + memoTheme(({ theme }) => ({ + margin: 32, + position: 'relative', + '@media print': { + overflowY: 'visible', + boxShadow: 'none', }, - { - props: ({ ownerState }) => !ownerState.maxWidth, - style: { - maxWidth: 'calc(100% - 64px)', + variants: [ + { + props: { + scroll: 'paper', + }, + style: { + display: 'flex', + flexDirection: 'column', + maxHeight: 'calc(100% - 64px)', + }, }, - }, - { - props: { - maxWidth: 'xs', + { + props: { + scroll: 'body', + }, + style: { + display: 'inline-block', + verticalAlign: 'middle', + textAlign: 'initial', + }, }, - style: { - maxWidth: - theme.breakpoints.unit === 'px' - ? Math.max(theme.breakpoints.values.xs, 444) - : `max(${theme.breakpoints.values.xs}${theme.breakpoints.unit}, 444px)`, - [`&.${dialogClasses.paperScrollBody}`]: { - [theme.breakpoints.down(Math.max(theme.breakpoints.values.xs, 444) + 32 * 2)]: { - maxWidth: 'calc(100% - 64px)', - }, + { + props: ({ ownerState }) => !ownerState.maxWidth, + style: { + maxWidth: 'calc(100% - 64px)', }, }, - }, - ...Object.keys(theme.breakpoints.values) - .filter((maxWidth) => maxWidth !== 'xs') - .map((maxWidth) => ({ - props: { maxWidth }, + { + props: { + maxWidth: 'xs', + }, style: { - maxWidth: `${theme.breakpoints.values[maxWidth]}${theme.breakpoints.unit}`, + maxWidth: + theme.breakpoints.unit === 'px' + ? Math.max(theme.breakpoints.values.xs, 444) + : `max(${theme.breakpoints.values.xs}${theme.breakpoints.unit}, 444px)`, [`&.${dialogClasses.paperScrollBody}`]: { - [theme.breakpoints.down(theme.breakpoints.values[maxWidth] + 32 * 2)]: { + [theme.breakpoints.down(Math.max(theme.breakpoints.values.xs, 444) + 32 * 2)]: { maxWidth: 'calc(100% - 64px)', }, }, }, - })), - { - props: ({ ownerState }) => ownerState.fullWidth, - style: { - width: 'calc(100% - 64px)', }, - }, - { - props: ({ ownerState }) => ownerState.fullScreen, - style: { - margin: 0, - width: '100%', - maxWidth: '100%', - height: '100%', - maxHeight: 'none', - borderRadius: 0, - [`&.${dialogClasses.paperScrollBody}`]: { + ...Object.keys(theme.breakpoints.values) + .filter((maxWidth) => maxWidth !== 'xs') + .map((maxWidth) => ({ + props: { maxWidth }, + style: { + maxWidth: `${theme.breakpoints.values[maxWidth]}${theme.breakpoints.unit}`, + [`&.${dialogClasses.paperScrollBody}`]: { + [theme.breakpoints.down(theme.breakpoints.values[maxWidth] + 32 * 2)]: { + maxWidth: 'calc(100% - 64px)', + }, + }, + }, + })), + { + props: ({ ownerState }) => ownerState.fullWidth, + style: { + width: 'calc(100% - 64px)', + }, + }, + { + props: ({ ownerState }) => ownerState.fullScreen, + style: { margin: 0, + width: '100%', maxWidth: '100%', + height: '100%', + maxHeight: 'none', + borderRadius: 0, + [`&.${dialogClasses.paperScrollBody}`]: { + margin: 0, + maxWidth: '100%', + }, }, }, - }, - ], -})); + ], + })), +); /** * Dialogs are overlaid modal paper based components with a backdrop. diff --git a/packages/mui-material/src/DialogContent/DialogContent.js b/packages/mui-material/src/DialogContent/DialogContent.js index 93c017300eb144..c5acfb7c3ef304 100644 --- a/packages/mui-material/src/DialogContent/DialogContent.js +++ b/packages/mui-material/src/DialogContent/DialogContent.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import { getDialogContentUtilityClass } from './dialogContentClasses'; import dialogTitleClasses from '../DialogTitle/dialogTitleClasses'; @@ -26,31 +27,33 @@ const DialogContentRoot = styled('div', { return [styles.root, ownerState.dividers && styles.dividers]; }, -})(({ theme }) => ({ - flex: '1 1 auto', - // Add iOS momentum scrolling for iOS < 13.0 - WebkitOverflowScrolling: 'touch', - overflowY: 'auto', - padding: '20px 24px', - variants: [ - { - props: ({ ownerState }) => ownerState.dividers, - style: { - padding: '16px 24px', - borderTop: `1px solid ${(theme.vars || theme).palette.divider}`, - borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`, +})( + memoTheme(({ theme }) => ({ + flex: '1 1 auto', + // Add iOS momentum scrolling for iOS < 13.0 + WebkitOverflowScrolling: 'touch', + overflowY: 'auto', + padding: '20px 24px', + variants: [ + { + props: ({ ownerState }) => ownerState.dividers, + style: { + padding: '16px 24px', + borderTop: `1px solid ${(theme.vars || theme).palette.divider}`, + borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`, + }, }, - }, - { - props: ({ ownerState }) => !ownerState.dividers, - style: { - [`.${dialogTitleClasses.root} + &`]: { - paddingTop: 0, + { + props: ({ ownerState }) => !ownerState.dividers, + style: { + [`.${dialogTitleClasses.root} + &`]: { + paddingTop: 0, + }, }, }, - }, - ], -})); + ], + })), +); const DialogContent = React.forwardRef(function DialogContent(inProps, ref) { const props = useDefaultProps({ diff --git a/packages/mui-material/src/Divider/Divider.js b/packages/mui-material/src/Divider/Divider.js index 2f7db911fb313c..1e28de482e2d05 100644 --- a/packages/mui-material/src/Divider/Divider.js +++ b/packages/mui-material/src/Divider/Divider.js @@ -5,6 +5,7 @@ import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { alpha } from '@mui/system/colorManipulator'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import { getDividerUtilityClass } from './dividerClasses'; @@ -54,144 +55,146 @@ const DividerRoot = styled('div', { styles.textAlignLeft, ]; }, -})(({ theme }) => ({ - margin: 0, // Reset browser default style. - flexShrink: 0, - borderWidth: 0, - borderStyle: 'solid', - borderColor: (theme.vars || theme).palette.divider, - borderBottomWidth: 'thin', - variants: [ - { - props: { - absolute: true, - }, - style: { - position: 'absolute', - bottom: 0, - left: 0, - width: '100%', - }, - }, - { - props: { - light: true, - }, - style: { - borderColor: theme.vars - ? `rgba(${theme.vars.palette.dividerChannel} / 0.08)` - : alpha(theme.palette.divider, 0.08), - }, - }, - { - props: { - variant: 'inset', - }, - style: { - marginLeft: 72, - }, - }, - { - props: { - variant: 'middle', - orientation: 'horizontal', - }, - style: { - marginLeft: theme.spacing(2), - marginRight: theme.spacing(2), - }, - }, - { - props: { - variant: 'middle', - orientation: 'vertical', - }, - style: { - marginTop: theme.spacing(1), - marginBottom: theme.spacing(1), +})( + memoTheme(({ theme }) => ({ + margin: 0, // Reset browser default style. + flexShrink: 0, + borderWidth: 0, + borderStyle: 'solid', + borderColor: (theme.vars || theme).palette.divider, + borderBottomWidth: 'thin', + variants: [ + { + props: { + absolute: true, + }, + style: { + position: 'absolute', + bottom: 0, + left: 0, + width: '100%', + }, }, - }, - { - props: { - orientation: 'vertical', + { + props: { + light: true, + }, + style: { + borderColor: theme.vars + ? `rgba(${theme.vars.palette.dividerChannel} / 0.08)` + : alpha(theme.palette.divider, 0.08), + }, }, - style: { - height: '100%', - borderBottomWidth: 0, - borderRightWidth: 'thin', + { + props: { + variant: 'inset', + }, + style: { + marginLeft: 72, + }, }, - }, - { - props: { - flexItem: true, + { + props: { + variant: 'middle', + orientation: 'horizontal', + }, + style: { + marginLeft: theme.spacing(2), + marginRight: theme.spacing(2), + }, }, - style: { - alignSelf: 'stretch', - height: 'auto', + { + props: { + variant: 'middle', + orientation: 'vertical', + }, + style: { + marginTop: theme.spacing(1), + marginBottom: theme.spacing(1), + }, }, - }, - { - props: ({ ownerState }) => !!ownerState.children, - style: { - display: 'flex', - whiteSpace: 'nowrap', - textAlign: 'center', - border: 0, - borderTopStyle: 'solid', - borderLeftStyle: 'solid', - '&::before, &::after': { - content: '""', - alignSelf: 'center', + { + props: { + orientation: 'vertical', + }, + style: { + height: '100%', + borderBottomWidth: 0, + borderRightWidth: 'thin', }, }, - }, - { - props: ({ ownerState }) => ownerState.children && ownerState.orientation !== 'vertical', - style: { - '&::before, &::after': { - width: '100%', - borderTop: `thin solid ${(theme.vars || theme).palette.divider}`, - borderTopStyle: 'inherit', + { + props: { + flexItem: true, + }, + style: { + alignSelf: 'stretch', + height: 'auto', }, }, - }, - { - props: ({ ownerState }) => ownerState.orientation === 'vertical' && ownerState.children, - style: { - flexDirection: 'column', - '&::before, &::after': { - height: '100%', - borderLeft: `thin solid ${(theme.vars || theme).palette.divider}`, - borderLeftStyle: 'inherit', + { + props: ({ ownerState }) => !!ownerState.children, + style: { + display: 'flex', + whiteSpace: 'nowrap', + textAlign: 'center', + border: 0, + borderTopStyle: 'solid', + borderLeftStyle: 'solid', + '&::before, &::after': { + content: '""', + alignSelf: 'center', + }, }, }, - }, - { - props: ({ ownerState }) => - ownerState.textAlign === 'right' && ownerState.orientation !== 'vertical', - style: { - '&::before': { - width: '90%', + { + props: ({ ownerState }) => ownerState.children && ownerState.orientation !== 'vertical', + style: { + '&::before, &::after': { + width: '100%', + borderTop: `thin solid ${(theme.vars || theme).palette.divider}`, + borderTopStyle: 'inherit', + }, }, - '&::after': { - width: '10%', + }, + { + props: ({ ownerState }) => ownerState.orientation === 'vertical' && ownerState.children, + style: { + flexDirection: 'column', + '&::before, &::after': { + height: '100%', + borderLeft: `thin solid ${(theme.vars || theme).palette.divider}`, + borderLeftStyle: 'inherit', + }, }, }, - }, - { - props: ({ ownerState }) => - ownerState.textAlign === 'left' && ownerState.orientation !== 'vertical', - style: { - '&::before': { - width: '10%', + { + props: ({ ownerState }) => + ownerState.textAlign === 'right' && ownerState.orientation !== 'vertical', + style: { + '&::before': { + width: '90%', + }, + '&::after': { + width: '10%', + }, }, - '&::after': { - width: '90%', + }, + { + props: ({ ownerState }) => + ownerState.textAlign === 'left' && ownerState.orientation !== 'vertical', + style: { + '&::before': { + width: '10%', + }, + '&::after': { + width: '90%', + }, }, }, - }, - ], -})); + ], + })), +); const DividerWrapper = styled('span', { name: 'MuiDivider', @@ -201,22 +204,24 @@ const DividerWrapper = styled('span', { return [styles.wrapper, ownerState.orientation === 'vertical' && styles.wrapperVertical]; }, -})(({ theme }) => ({ - display: 'inline-block', - paddingLeft: `calc(${theme.spacing(1)} * 1.2)`, - paddingRight: `calc(${theme.spacing(1)} * 1.2)`, - variants: [ - { - props: { - orientation: 'vertical', - }, - style: { - paddingTop: `calc(${theme.spacing(1)} * 1.2)`, - paddingBottom: `calc(${theme.spacing(1)} * 1.2)`, +})( + memoTheme(({ theme }) => ({ + display: 'inline-block', + paddingLeft: `calc(${theme.spacing(1)} * 1.2)`, + paddingRight: `calc(${theme.spacing(1)} * 1.2)`, + variants: [ + { + props: { + orientation: 'vertical', + }, + style: { + paddingTop: `calc(${theme.spacing(1)} * 1.2)`, + paddingBottom: `calc(${theme.spacing(1)} * 1.2)`, + }, }, - }, - ], -})); + ], + })), +); const Divider = React.forwardRef(function Divider(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiDivider' }); diff --git a/packages/mui-material/src/Drawer/Drawer.js b/packages/mui-material/src/Drawer/Drawer.js index bca98f317cd493..b1f262166cf3ea 100644 --- a/packages/mui-material/src/Drawer/Drawer.js +++ b/packages/mui-material/src/Drawer/Drawer.js @@ -11,6 +11,7 @@ import Paper from '../Paper'; import capitalize from '../utils/capitalize'; import rootShouldForwardProp from '../styles/rootShouldForwardProp'; import { styled, useTheme } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import { getDrawerUtilityClass } from './drawerClasses'; @@ -45,9 +46,11 @@ const DrawerRoot = styled(Modal, { name: 'MuiDrawer', slot: 'Root', overridesResolver, -})(({ theme }) => ({ - zIndex: (theme.vars || theme).zIndex.drawer, -})); +})( + memoTheme(({ theme }) => ({ + zIndex: (theme.vars || theme).zIndex.drawer, + })), +); const DrawerDockedRoot = styled('div', { shouldForwardProp: rootShouldForwardProp, @@ -72,92 +75,96 @@ const DrawerPaper = styled(Paper, { styles[`paperAnchorDocked${capitalize(ownerState.anchor)}`], ]; }, -})(({ theme }) => ({ - overflowY: 'auto', - display: 'flex', - flexDirection: 'column', - height: '100%', - flex: '1 0 auto', - zIndex: (theme.vars || theme).zIndex.drawer, - // Add iOS momentum scrolling for iOS < 13.0 - WebkitOverflowScrolling: 'touch', - // temporary style - position: 'fixed', - top: 0, - // We disable the focus ring for mouse, touch and keyboard users. - // At some point, it would be better to keep it for keyboard users. - // :focus-ring CSS pseudo-class will help. - outline: 0, - variants: [ - { - props: { - anchor: 'left', +})( + memoTheme(({ theme }) => ({ + overflowY: 'auto', + display: 'flex', + flexDirection: 'column', + height: '100%', + flex: '1 0 auto', + zIndex: (theme.vars || theme).zIndex.drawer, + // Add iOS momentum scrolling for iOS < 13.0 + WebkitOverflowScrolling: 'touch', + // temporary style + position: 'fixed', + top: 0, + // We disable the focus ring for mouse, touch and keyboard users. + // At some point, it would be better to keep it for keyboard users. + // :focus-ring CSS pseudo-class will help. + outline: 0, + variants: [ + { + props: { + anchor: 'left', + }, + style: { + left: 0, + }, }, - style: { - left: 0, + { + props: { + anchor: 'top', + }, + style: { + top: 0, + left: 0, + right: 0, + height: 'auto', + maxHeight: '100%', + }, }, - }, - { - props: { - anchor: 'top', + { + props: { + anchor: 'right', + }, + style: { + right: 0, + }, }, - style: { - top: 0, - left: 0, - right: 0, - height: 'auto', - maxHeight: '100%', + { + props: { + anchor: 'bottom', + }, + style: { + top: 'auto', + left: 0, + bottom: 0, + right: 0, + height: 'auto', + maxHeight: '100%', + }, }, - }, - { - props: { - anchor: 'right', + { + props: ({ ownerState }) => + ownerState.anchor === 'left' && ownerState.variant !== 'temporary', + style: { + borderRight: `1px solid ${(theme.vars || theme).palette.divider}`, + }, }, - style: { - right: 0, + { + props: ({ ownerState }) => + ownerState.anchor === 'top' && ownerState.variant !== 'temporary', + style: { + borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`, + }, }, - }, - { - props: { - anchor: 'bottom', + { + props: ({ ownerState }) => + ownerState.anchor === 'right' && ownerState.variant !== 'temporary', + style: { + borderLeft: `1px solid ${(theme.vars || theme).palette.divider}`, + }, }, - style: { - top: 'auto', - left: 0, - bottom: 0, - right: 0, - height: 'auto', - maxHeight: '100%', + { + props: ({ ownerState }) => + ownerState.anchor === 'bottom' && ownerState.variant !== 'temporary', + style: { + borderTop: `1px solid ${(theme.vars || theme).palette.divider}`, + }, }, - }, - { - props: ({ ownerState }) => ownerState.anchor === 'left' && ownerState.variant !== 'temporary', - style: { - borderRight: `1px solid ${(theme.vars || theme).palette.divider}`, - }, - }, - { - props: ({ ownerState }) => ownerState.anchor === 'top' && ownerState.variant !== 'temporary', - style: { - borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`, - }, - }, - { - props: ({ ownerState }) => - ownerState.anchor === 'right' && ownerState.variant !== 'temporary', - style: { - borderLeft: `1px solid ${(theme.vars || theme).palette.divider}`, - }, - }, - { - props: ({ ownerState }) => - ownerState.anchor === 'bottom' && ownerState.variant !== 'temporary', - style: { - borderTop: `1px solid ${(theme.vars || theme).palette.divider}`, - }, - }, - ], -})); + ], + })), +); const oppositeDirection = { left: 'right', diff --git a/packages/mui-material/src/Fab/Fab.js b/packages/mui-material/src/Fab/Fab.js index 71da7157e83527..2a7db6fcf197e5 100644 --- a/packages/mui-material/src/Fab/Fab.js +++ b/packages/mui-material/src/Fab/Fab.js @@ -8,6 +8,7 @@ import capitalize from '../utils/capitalize'; import fabClasses, { getFabUtilityClass } from './fabClasses'; import rootShouldForwardProp from '../styles/rootShouldForwardProp'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; @@ -48,7 +49,7 @@ const FabRoot = styled(ButtonBase, { ]; }, })( - ({ theme }) => ({ + memoTheme(({ theme }) => ({ ...theme.typography.button, minHeight: 36, transition: theme.transitions.create(['background-color', 'box-shadow', 'border-color'], { @@ -132,8 +133,8 @@ const FabRoot = styled(ButtonBase, { }, }, ], - }), - ({ theme }) => ({ + })), + memoTheme(({ theme }) => ({ variants: [ ...Object.entries(theme.palette) .filter(([, value]) => value && value.main && value.dark && value.contrastText) // check all the used fields in the style below @@ -152,14 +153,14 @@ const FabRoot = styled(ButtonBase, { }, })), ], - }), - ({ theme }) => ({ + })), + memoTheme(({ theme }) => ({ [`&.${fabClasses.disabled}`]: { color: (theme.vars || theme).palette.action.disabled, boxShadow: (theme.vars || theme).shadows[0], backgroundColor: (theme.vars || theme).palette.action.disabledBackground, }, - }), + })), ); const Fab = React.forwardRef(function Fab(inProps, ref) { diff --git a/packages/mui-material/src/FilledInput/FilledInput.js b/packages/mui-material/src/FilledInput/FilledInput.js index b8622869a6b813..94a3f1bf4a4ca1 100644 --- a/packages/mui-material/src/FilledInput/FilledInput.js +++ b/packages/mui-material/src/FilledInput/FilledInput.js @@ -7,6 +7,7 @@ import composeClasses from '@mui/utils/composeClasses'; import InputBase from '../InputBase'; import rootShouldForwardProp from '../styles/rootShouldForwardProp'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import filledInputClasses, { getFilledInputUtilityClass } from './filledInputClasses'; import { @@ -53,220 +54,226 @@ const FilledInputRoot = styled(InputBaseRoot, { !ownerState.disableUnderline && styles.underline, ]; }, -})(({ theme }) => { - const light = theme.palette.mode === 'light'; - const bottomLineColor = light ? 'rgba(0, 0, 0, 0.42)' : 'rgba(255, 255, 255, 0.7)'; - const backgroundColor = light ? 'rgba(0, 0, 0, 0.06)' : 'rgba(255, 255, 255, 0.09)'; - const hoverBackground = light ? 'rgba(0, 0, 0, 0.09)' : 'rgba(255, 255, 255, 0.13)'; - const disabledBackground = light ? 'rgba(0, 0, 0, 0.12)' : 'rgba(255, 255, 255, 0.12)'; - return { - position: 'relative', - backgroundColor: theme.vars ? theme.vars.palette.FilledInput.bg : backgroundColor, - borderTopLeftRadius: (theme.vars || theme).shape.borderRadius, - borderTopRightRadius: (theme.vars || theme).shape.borderRadius, - transition: theme.transitions.create('background-color', { - duration: theme.transitions.duration.shorter, - easing: theme.transitions.easing.easeOut, - }), - '&:hover': { - backgroundColor: theme.vars ? theme.vars.palette.FilledInput.hoverBg : hoverBackground, - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { +})( + memoTheme(({ theme }) => { + const light = theme.palette.mode === 'light'; + const bottomLineColor = light ? 'rgba(0, 0, 0, 0.42)' : 'rgba(255, 255, 255, 0.7)'; + const backgroundColor = light ? 'rgba(0, 0, 0, 0.06)' : 'rgba(255, 255, 255, 0.09)'; + const hoverBackground = light ? 'rgba(0, 0, 0, 0.09)' : 'rgba(255, 255, 255, 0.13)'; + const disabledBackground = light ? 'rgba(0, 0, 0, 0.12)' : 'rgba(255, 255, 255, 0.12)'; + return { + position: 'relative', + backgroundColor: theme.vars ? theme.vars.palette.FilledInput.bg : backgroundColor, + borderTopLeftRadius: (theme.vars || theme).shape.borderRadius, + borderTopRightRadius: (theme.vars || theme).shape.borderRadius, + transition: theme.transitions.create('background-color', { + duration: theme.transitions.duration.shorter, + easing: theme.transitions.easing.easeOut, + }), + '&:hover': { + backgroundColor: theme.vars ? theme.vars.palette.FilledInput.hoverBg : hoverBackground, + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: theme.vars ? theme.vars.palette.FilledInput.bg : backgroundColor, + }, + }, + [`&.${filledInputClasses.focused}`]: { backgroundColor: theme.vars ? theme.vars.palette.FilledInput.bg : backgroundColor, }, - }, - [`&.${filledInputClasses.focused}`]: { - backgroundColor: theme.vars ? theme.vars.palette.FilledInput.bg : backgroundColor, - }, - [`&.${filledInputClasses.disabled}`]: { - backgroundColor: theme.vars ? theme.vars.palette.FilledInput.disabledBg : disabledBackground, - }, - variants: [ - { - props: ({ ownerState }) => !ownerState.disableUnderline, - style: { - '&::after': { - left: 0, - bottom: 0, - content: '""', - position: 'absolute', - right: 0, - transform: 'scaleX(0)', - transition: theme.transitions.create('transform', { - duration: theme.transitions.duration.shorter, - easing: theme.transitions.easing.easeOut, - }), - pointerEvents: 'none', // Transparent to the hover style. - }, - [`&.${filledInputClasses.focused}:after`]: { - // translateX(0) is a workaround for Safari transform scale bug - // See https://github.com/mui/material-ui/issues/31766 - transform: 'scaleX(1) translateX(0)', + [`&.${filledInputClasses.disabled}`]: { + backgroundColor: theme.vars + ? theme.vars.palette.FilledInput.disabledBg + : disabledBackground, + }, + variants: [ + { + props: ({ ownerState }) => !ownerState.disableUnderline, + style: { + '&::after': { + left: 0, + bottom: 0, + content: '""', + position: 'absolute', + right: 0, + transform: 'scaleX(0)', + transition: theme.transitions.create('transform', { + duration: theme.transitions.duration.shorter, + easing: theme.transitions.easing.easeOut, + }), + pointerEvents: 'none', // Transparent to the hover style. + }, + [`&.${filledInputClasses.focused}:after`]: { + // translateX(0) is a workaround for Safari transform scale bug + // See https://github.com/mui/material-ui/issues/31766 + transform: 'scaleX(1) translateX(0)', + }, + [`&.${filledInputClasses.error}`]: { + '&::before, &::after': { + borderBottomColor: (theme.vars || theme).palette.error.main, + }, + }, + '&::before': { + borderBottom: `1px solid ${ + theme.vars + ? `rgba(${theme.vars.palette.common.onBackgroundChannel} / ${theme.vars.opacity.inputUnderline})` + : bottomLineColor + }`, + left: 0, + bottom: 0, + content: '"\\00a0"', + position: 'absolute', + right: 0, + transition: theme.transitions.create('border-bottom-color', { + duration: theme.transitions.duration.shorter, + }), + pointerEvents: 'none', // Transparent to the hover style. + }, + [`&:hover:not(.${filledInputClasses.disabled}, .${filledInputClasses.error}):before`]: { + borderBottom: `1px solid ${(theme.vars || theme).palette.text.primary}`, + }, + [`&.${filledInputClasses.disabled}:before`]: { + borderBottomStyle: 'dotted', + }, }, - [`&.${filledInputClasses.error}`]: { - '&::before, &::after': { - borderBottomColor: (theme.vars || theme).palette.error.main, + }, + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main) // check all the used fields in the style below + .map(([color]) => ({ + props: { + disableUnderline: false, + color, }, + style: { + '&::after': { + borderBottom: `2px solid ${(theme.vars || theme).palette[color]?.main}`, + }, + }, + })), + { + props: ({ ownerState }) => ownerState.startAdornment, + style: { + paddingLeft: 12, }, - '&::before': { - borderBottom: `1px solid ${ - theme.vars - ? `rgba(${theme.vars.palette.common.onBackgroundChannel} / ${theme.vars.opacity.inputUnderline})` - : bottomLineColor - }`, - left: 0, - bottom: 0, - content: '"\\00a0"', - position: 'absolute', - right: 0, - transition: theme.transitions.create('border-bottom-color', { - duration: theme.transitions.duration.shorter, - }), - pointerEvents: 'none', // Transparent to the hover style. + }, + { + props: ({ ownerState }) => ownerState.endAdornment, + style: { + paddingRight: 12, }, - [`&:hover:not(.${filledInputClasses.disabled}, .${filledInputClasses.error}):before`]: { - borderBottom: `1px solid ${(theme.vars || theme).palette.text.primary}`, + }, + { + props: ({ ownerState }) => ownerState.multiline, + style: { + padding: '25px 12px 8px', }, - [`&.${filledInputClasses.disabled}:before`]: { - borderBottomStyle: 'dotted', + }, + { + props: ({ ownerState, size }) => ownerState.multiline && size === 'small', + style: { + paddingTop: 21, + paddingBottom: 4, }, }, - }, - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main) // check all the used fields in the style below - .map(([color]) => ({ - props: { - disableUnderline: false, - color, + { + props: ({ ownerState }) => ownerState.multiline && ownerState.hiddenLabel, + style: { + paddingTop: 16, + paddingBottom: 17, }, + }, + { + props: ({ ownerState }) => + ownerState.multiline && ownerState.hiddenLabel && ownerState.size === 'small', style: { - '&::after': { - borderBottom: `2px solid ${(theme.vars || theme).palette[color]?.main}`, - }, + paddingTop: 8, + paddingBottom: 9, }, - })), - { - props: ({ ownerState }) => ownerState.startAdornment, - style: { - paddingLeft: 12, + }, + ], + }; + }), +); + +const FilledInputInput = styled(InputBaseInput, { + name: 'MuiFilledInput', + slot: 'Input', + overridesResolver: inputBaseInputOverridesResolver, +})( + memoTheme(({ theme }) => ({ + paddingTop: 25, + paddingRight: 12, + paddingBottom: 8, + paddingLeft: 12, + ...(!theme.vars && { + '&:-webkit-autofill': { + WebkitBoxShadow: theme.palette.mode === 'light' ? null : '0 0 0 100px #266798 inset', + WebkitTextFillColor: theme.palette.mode === 'light' ? null : '#fff', + caretColor: theme.palette.mode === 'light' ? null : '#fff', + borderTopLeftRadius: 'inherit', + borderTopRightRadius: 'inherit', + }, + }), + ...(theme.vars && { + '&:-webkit-autofill': { + borderTopLeftRadius: 'inherit', + borderTopRightRadius: 'inherit', + }, + [theme.getColorSchemeSelector('dark')]: { + '&:-webkit-autofill': { + WebkitBoxShadow: '0 0 0 100px #266798 inset', + WebkitTextFillColor: '#fff', + caretColor: '#fff', }, }, + }), + variants: [ { - props: ({ ownerState }) => ownerState.endAdornment, + props: { + size: 'small', + }, style: { - paddingRight: 12, + paddingTop: 21, + paddingBottom: 4, }, }, { - props: ({ ownerState }) => ownerState.multiline, + props: ({ ownerState }) => ownerState.hiddenLabel, style: { - padding: '25px 12px 8px', + paddingTop: 16, + paddingBottom: 17, }, }, { - props: ({ ownerState, size }) => ownerState.multiline && size === 'small', + props: ({ ownerState }) => ownerState.startAdornment, style: { - paddingTop: 21, - paddingBottom: 4, + paddingLeft: 0, }, }, { - props: ({ ownerState }) => ownerState.multiline && ownerState.hiddenLabel, + props: ({ ownerState }) => ownerState.endAdornment, style: { - paddingTop: 16, - paddingBottom: 17, + paddingRight: 0, }, }, { - props: ({ ownerState }) => - ownerState.multiline && ownerState.hiddenLabel && ownerState.size === 'small', + props: ({ ownerState }) => ownerState.hiddenLabel && ownerState.size === 'small', style: { paddingTop: 8, paddingBottom: 9, }, }, - ], - }; -}); - -const FilledInputInput = styled(InputBaseInput, { - name: 'MuiFilledInput', - slot: 'Input', - overridesResolver: inputBaseInputOverridesResolver, -})(({ theme }) => ({ - paddingTop: 25, - paddingRight: 12, - paddingBottom: 8, - paddingLeft: 12, - ...(!theme.vars && { - '&:-webkit-autofill': { - WebkitBoxShadow: theme.palette.mode === 'light' ? null : '0 0 0 100px #266798 inset', - WebkitTextFillColor: theme.palette.mode === 'light' ? null : '#fff', - caretColor: theme.palette.mode === 'light' ? null : '#fff', - borderTopLeftRadius: 'inherit', - borderTopRightRadius: 'inherit', - }, - }), - ...(theme.vars && { - '&:-webkit-autofill': { - borderTopLeftRadius: 'inherit', - borderTopRightRadius: 'inherit', - }, - [theme.getColorSchemeSelector('dark')]: { - '&:-webkit-autofill': { - WebkitBoxShadow: '0 0 0 100px #266798 inset', - WebkitTextFillColor: '#fff', - caretColor: '#fff', - }, - }, - }), - variants: [ - { - props: { - size: 'small', - }, - style: { - paddingTop: 21, - paddingBottom: 4, - }, - }, - { - props: ({ ownerState }) => ownerState.hiddenLabel, - style: { - paddingTop: 16, - paddingBottom: 17, - }, - }, - { - props: ({ ownerState }) => ownerState.startAdornment, - style: { - paddingLeft: 0, - }, - }, - { - props: ({ ownerState }) => ownerState.endAdornment, - style: { - paddingRight: 0, - }, - }, - { - props: ({ ownerState }) => ownerState.hiddenLabel && ownerState.size === 'small', - style: { - paddingTop: 8, - paddingBottom: 9, - }, - }, - { - props: ({ ownerState }) => ownerState.multiline, - style: { - paddingTop: 0, - paddingBottom: 0, - paddingLeft: 0, - paddingRight: 0, + { + props: ({ ownerState }) => ownerState.multiline, + style: { + paddingTop: 0, + paddingBottom: 0, + paddingLeft: 0, + paddingRight: 0, + }, }, - }, - ], -})); + ], + })), +); const FilledInput = React.forwardRef(function FilledInput(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiFilledInput' }); diff --git a/packages/mui-material/src/FormControlLabel/FormControlLabel.js b/packages/mui-material/src/FormControlLabel/FormControlLabel.js index 9801c7aef896fb..bb453ae5a567b2 100644 --- a/packages/mui-material/src/FormControlLabel/FormControlLabel.js +++ b/packages/mui-material/src/FormControlLabel/FormControlLabel.js @@ -6,6 +6,7 @@ import refType from '@mui/utils/refType'; import composeClasses from '@mui/utils/composeClasses'; import { useFormControl } from '../FormControl'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import Typography from '../Typography'; import capitalize from '../utils/capitalize'; @@ -44,62 +45,66 @@ export const FormControlLabelRoot = styled('label', { styles[`labelPlacement${capitalize(ownerState.labelPlacement)}`], ]; }, -})(({ theme }) => ({ - display: 'inline-flex', - alignItems: 'center', - cursor: 'pointer', - // For correct alignment with the text. - verticalAlign: 'middle', - WebkitTapHighlightColor: 'transparent', - marginLeft: -11, - marginRight: 16, // used for row presentation of radio/checkbox - [`&.${formControlLabelClasses.disabled}`]: { - cursor: 'default', - }, - [`& .${formControlLabelClasses.label}`]: { +})( + memoTheme(({ theme }) => ({ + display: 'inline-flex', + alignItems: 'center', + cursor: 'pointer', + // For correct alignment with the text. + verticalAlign: 'middle', + WebkitTapHighlightColor: 'transparent', + marginLeft: -11, + marginRight: 16, // used for row presentation of radio/checkbox [`&.${formControlLabelClasses.disabled}`]: { - color: (theme.vars || theme).palette.text.disabled, + cursor: 'default', }, - }, - variants: [ - { - props: { labelPlacement: 'start' }, - style: { - flexDirection: 'row-reverse', - marginRight: -11, + [`& .${formControlLabelClasses.label}`]: { + [`&.${formControlLabelClasses.disabled}`]: { + color: (theme.vars || theme).palette.text.disabled, }, }, - { - props: { labelPlacement: 'top' }, - style: { - flexDirection: 'column-reverse', + variants: [ + { + props: { labelPlacement: 'start' }, + style: { + flexDirection: 'row-reverse', + marginRight: -11, + }, }, - }, - { - props: { labelPlacement: 'bottom' }, - style: { - flexDirection: 'column', + { + props: { labelPlacement: 'top' }, + style: { + flexDirection: 'column-reverse', + }, }, - }, - { - props: ({ labelPlacement }) => - labelPlacement === 'start' || labelPlacement === 'top' || labelPlacement === 'bottom', - style: { - marginLeft: 16, // used for row presentation of radio/checkbox + { + props: { labelPlacement: 'bottom' }, + style: { + flexDirection: 'column', + }, }, - }, - ], -})); + { + props: ({ labelPlacement }) => + labelPlacement === 'start' || labelPlacement === 'top' || labelPlacement === 'bottom', + style: { + marginLeft: 16, // used for row presentation of radio/checkbox + }, + }, + ], + })), +); const AsteriskComponent = styled('span', { name: 'MuiFormControlLabel', slot: 'Asterisk', overridesResolver: (props, styles) => styles.asterisk, -})(({ theme }) => ({ - [`&.${formControlLabelClasses.error}`]: { - color: (theme.vars || theme).palette.error.main, - }, -})); +})( + memoTheme(({ theme }) => ({ + [`&.${formControlLabelClasses.error}`]: { + color: (theme.vars || theme).palette.error.main, + }, + })), +); /** * Drop-in replacement of the `Radio`, `Switch` and `Checkbox` component. diff --git a/packages/mui-material/src/FormHelperText/FormHelperText.js b/packages/mui-material/src/FormHelperText/FormHelperText.js index 44a2ae9215e9fa..14cad8a81fff28 100644 --- a/packages/mui-material/src/FormHelperText/FormHelperText.js +++ b/packages/mui-material/src/FormHelperText/FormHelperText.js @@ -6,6 +6,7 @@ import composeClasses from '@mui/utils/composeClasses'; import formControlState from '../FormControl/formControlState'; import useFormControl from '../FormControl/useFormControl'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import capitalize from '../utils/capitalize'; import formHelperTextClasses, { getFormHelperTextUtilityClasses } from './formHelperTextClasses'; @@ -41,38 +42,40 @@ const FormHelperTextRoot = styled('p', { ownerState.filled && styles.filled, ]; }, -})(({ theme }) => ({ - color: (theme.vars || theme).palette.text.secondary, - ...theme.typography.caption, - textAlign: 'left', - marginTop: 3, - marginRight: 0, - marginBottom: 0, - marginLeft: 0, - [`&.${formHelperTextClasses.disabled}`]: { - color: (theme.vars || theme).palette.text.disabled, - }, - [`&.${formHelperTextClasses.error}`]: { - color: (theme.vars || theme).palette.error.main, - }, - variants: [ - { - props: { - size: 'small', - }, - style: { - marginTop: 4, - }, +})( + memoTheme(({ theme }) => ({ + color: (theme.vars || theme).palette.text.secondary, + ...theme.typography.caption, + textAlign: 'left', + marginTop: 3, + marginRight: 0, + marginBottom: 0, + marginLeft: 0, + [`&.${formHelperTextClasses.disabled}`]: { + color: (theme.vars || theme).palette.text.disabled, }, - { - props: ({ ownerState }) => ownerState.contained, - style: { - marginLeft: 14, - marginRight: 14, - }, + [`&.${formHelperTextClasses.error}`]: { + color: (theme.vars || theme).palette.error.main, }, - ], -})); + variants: [ + { + props: { + size: 'small', + }, + style: { + marginTop: 4, + }, + }, + { + props: ({ ownerState }) => ownerState.contained, + style: { + marginLeft: 14, + marginRight: 14, + }, + }, + ], + })), +); const FormHelperText = React.forwardRef(function FormHelperText(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiFormHelperText' }); diff --git a/packages/mui-material/src/FormLabel/FormLabel.js b/packages/mui-material/src/FormLabel/FormLabel.js index b412549321dd2b..446f6494b4b1b5 100644 --- a/packages/mui-material/src/FormLabel/FormLabel.js +++ b/packages/mui-material/src/FormLabel/FormLabel.js @@ -7,6 +7,7 @@ import formControlState from '../FormControl/formControlState'; import useFormControl from '../FormControl/useFormControl'; import capitalize from '../utils/capitalize'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import formLabelClasses, { getFormLabelUtilityClasses } from './formLabelClasses'; @@ -38,46 +39,50 @@ export const FormLabelRoot = styled('label', { ...(ownerState.filled && styles.filled), }; }, -})(({ theme }) => ({ - color: (theme.vars || theme).palette.text.secondary, - ...theme.typography.body1, - lineHeight: '1.4375em', - padding: 0, - position: 'relative', - variants: [ - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main) - .map(([color]) => ({ - props: { color }, +})( + memoTheme(({ theme }) => ({ + color: (theme.vars || theme).palette.text.secondary, + ...theme.typography.body1, + lineHeight: '1.4375em', + padding: 0, + position: 'relative', + variants: [ + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main) + .map(([color]) => ({ + props: { color }, + style: { + [`&.${formLabelClasses.focused}`]: { + color: (theme.vars || theme).palette[color].main, + }, + }, + })), + { + props: {}, style: { - [`&.${formLabelClasses.focused}`]: { - color: (theme.vars || theme).palette[color].main, + [`&.${formLabelClasses.disabled}`]: { + color: (theme.vars || theme).palette.text.disabled, + }, + [`&.${formLabelClasses.error}`]: { + color: (theme.vars || theme).palette.error.main, }, - }, - })), - { - props: {}, - style: { - [`&.${formLabelClasses.disabled}`]: { - color: (theme.vars || theme).palette.text.disabled, - }, - [`&.${formLabelClasses.error}`]: { - color: (theme.vars || theme).palette.error.main, }, }, - }, - ], -})); + ], + })), +); const AsteriskComponent = styled('span', { name: 'MuiFormLabel', slot: 'Asterisk', overridesResolver: (props, styles) => styles.asterisk, -})(({ theme }) => ({ - [`&.${formLabelClasses.error}`]: { - color: (theme.vars || theme).palette.error.main, - }, -})); +})( + memoTheme(({ theme }) => ({ + [`&.${formLabelClasses.error}`]: { + color: (theme.vars || theme).palette.error.main, + }, + })), +); const FormLabel = React.forwardRef(function FormLabel(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiFormLabel' }); diff --git a/packages/mui-material/src/Grid/Grid.js b/packages/mui-material/src/Grid/Grid.js index c232d9be41936a..ec8f82bda71359 100644 --- a/packages/mui-material/src/Grid/Grid.js +++ b/packages/mui-material/src/Grid/Grid.js @@ -309,6 +309,7 @@ const GridRoot = styled('div', { ]; }, })( + // FIXME(romgrk): Can't use memoTheme here ({ ownerState }) => ({ boxSizing: 'border-box', ...(ownerState.container && { diff --git a/packages/mui-material/src/Hidden/HiddenCss.js b/packages/mui-material/src/Hidden/HiddenCss.js index c88531677ce928..fc1c469b304605 100644 --- a/packages/mui-material/src/Hidden/HiddenCss.js +++ b/packages/mui-material/src/Hidden/HiddenCss.js @@ -25,6 +25,7 @@ const useUtilityClasses = (ownerState) => { return composeClasses(slots, getHiddenCssUtilityClass, classes); }; +// FIXME(romgrk): Can't use memoTheme here, should we memo also on ownerState? const HiddenCssRoot = styled('div', { name: 'PrivateHiddenCss', slot: 'Root', diff --git a/packages/mui-material/src/Icon/Icon.js b/packages/mui-material/src/Icon/Icon.js index 8368b113b52972..1908f8b4f7decd 100644 --- a/packages/mui-material/src/Icon/Icon.js +++ b/packages/mui-material/src/Icon/Icon.js @@ -5,6 +5,7 @@ import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import capitalize from '../utils/capitalize'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import { getIconUtilityClass } from './iconClasses'; @@ -34,83 +35,85 @@ const IconRoot = styled('span', { styles[`fontSize${capitalize(ownerState.fontSize)}`], ]; }, -})(({ theme }) => ({ - userSelect: 'none', - width: '1em', - height: '1em', - // Chrome fix for https://bugs.chromium.org/p/chromium/issues/detail?id=820541 - // To remove at some point. - overflow: 'hidden', - display: 'inline-block', // allow overflow hidden to take action - textAlign: 'center', // support non-square icon - flexShrink: 0, - variants: [ - { - props: { - fontSize: 'inherit', - }, - style: { - fontSize: 'inherit', - }, - }, - { - props: { - fontSize: 'small', - }, - style: { - fontSize: theme.typography.pxToRem(20), - }, - }, - { - props: { - fontSize: 'medium', - }, - style: { - fontSize: theme.typography.pxToRem(24), - }, - }, - { - props: { - fontSize: 'large', - }, - style: { - fontSize: theme.typography.pxToRem(36), - }, - }, - { - props: { - color: 'action', +})( + memoTheme(({ theme }) => ({ + userSelect: 'none', + width: '1em', + height: '1em', + // Chrome fix for https://bugs.chromium.org/p/chromium/issues/detail?id=820541 + // To remove at some point. + overflow: 'hidden', + display: 'inline-block', // allow overflow hidden to take action + textAlign: 'center', // support non-square icon + flexShrink: 0, + variants: [ + { + props: { + fontSize: 'inherit', + }, + style: { + fontSize: 'inherit', + }, }, - style: { - color: (theme.vars || theme).palette.action.active, + { + props: { + fontSize: 'small', + }, + style: { + fontSize: theme.typography.pxToRem(20), + }, }, - }, - { - props: { - color: 'disabled', + { + props: { + fontSize: 'medium', + }, + style: { + fontSize: theme.typography.pxToRem(24), + }, }, - style: { - color: (theme.vars || theme).palette.action.disabled, + { + props: { + fontSize: 'large', + }, + style: { + fontSize: theme.typography.pxToRem(36), + }, }, - }, - { - props: { - color: 'inherit', + { + props: { + color: 'action', + }, + style: { + color: (theme.vars || theme).palette.action.active, + }, }, - style: { - color: undefined, + { + props: { + color: 'disabled', + }, + style: { + color: (theme.vars || theme).palette.action.disabled, + }, }, - }, - ...Object.entries(theme.palette) - .filter(([, palette]) => palette && palette.main) - .map(([color]) => ({ - props: { color }, + { + props: { + color: 'inherit', + }, style: { - color: (theme.vars || theme).palette[color].main, + color: undefined, }, - })), - ], -})); + }, + ...Object.entries(theme.palette) + .filter(([, palette]) => palette && palette.main) + .map(([color]) => ({ + props: { color }, + style: { + color: (theme.vars || theme).palette[color].main, + }, + })), + ], + })), +); const Icon = React.forwardRef(function Icon(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiIcon' }); diff --git a/packages/mui-material/src/IconButton/IconButton.js b/packages/mui-material/src/IconButton/IconButton.js index 316781b6cd5341..af22d5c655a9ff 100644 --- a/packages/mui-material/src/IconButton/IconButton.js +++ b/packages/mui-material/src/IconButton/IconButton.js @@ -6,6 +6,7 @@ import chainPropTypes from '@mui/utils/chainPropTypes'; import composeClasses from '@mui/utils/composeClasses'; import { alpha } from '@mui/system/colorManipulator'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import ButtonBase from '../ButtonBase'; import capitalize from '../utils/capitalize'; @@ -41,7 +42,7 @@ const IconButtonRoot = styled(ButtonBase, { ]; }, })( - ({ theme }) => ({ + memoTheme(({ theme }) => ({ textAlign: 'center', flex: '0 0 auto', fontSize: theme.typography.pxToRem(24), @@ -91,64 +92,62 @@ const IconButtonRoot = styled(ButtonBase, { }, }, ], - }), - ({ theme }) => { - return { - variants: [ - { - props: { color: 'inherit' }, + })), + memoTheme(({ theme }) => ({ + variants: [ + { + props: { color: 'inherit' }, + style: { + color: 'inherit', + }, + }, + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main) // check all the used fields in the style below + .map(([color]) => ({ + props: { color }, style: { - color: 'inherit', + color: (theme.vars || theme).palette[color].main, }, - }, - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main) // check all the used fields in the style below - .map(([color]) => ({ - props: { color }, - style: { - color: (theme.vars || theme).palette[color].main, - }, - })), - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main) // check all the used fields in the style below - .map(([color]) => ({ - props: { color, disableRipple: false }, - style: { - '&:hover': { - backgroundColor: theme.vars - ? `rgba(${(theme.vars || theme).palette[color].mainChannel} / ${theme.vars.palette.action.hoverOpacity})` - : alpha( - (theme.vars || theme).palette[color].main, - theme.palette.action.hoverOpacity, - ), - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: 'transparent', - }, + })), + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main) // check all the used fields in the style below + .map(([color]) => ({ + props: { color, disableRipple: false }, + style: { + '&:hover': { + backgroundColor: theme.vars + ? `rgba(${(theme.vars || theme).palette[color].mainChannel} / ${theme.vars.palette.action.hoverOpacity})` + : alpha( + (theme.vars || theme).palette[color].main, + theme.palette.action.hoverOpacity, + ), + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: 'transparent', }, }, - })), - { - props: { size: 'small' }, - style: { - padding: 5, - fontSize: theme.typography.pxToRem(18), }, + })), + { + props: { size: 'small' }, + style: { + padding: 5, + fontSize: theme.typography.pxToRem(18), }, - { - props: { size: 'large' }, - style: { - padding: 12, - fontSize: theme.typography.pxToRem(28), - }, + }, + { + props: { size: 'large' }, + style: { + padding: 12, + fontSize: theme.typography.pxToRem(28), }, - ], - [`&.${iconButtonClasses.disabled}`]: { - backgroundColor: 'transparent', - color: (theme.vars || theme).palette.action.disabled, }, - }; - }, + ], + [`&.${iconButtonClasses.disabled}`]: { + backgroundColor: 'transparent', + color: (theme.vars || theme).palette.action.disabled, + }, + })), ); /** diff --git a/packages/mui-material/src/ImageListItemBar/ImageListItemBar.js b/packages/mui-material/src/ImageListItemBar/ImageListItemBar.js index da46c6ddd9cb86..206cd1e801779b 100644 --- a/packages/mui-material/src/ImageListItemBar/ImageListItemBar.js +++ b/packages/mui-material/src/ImageListItemBar/ImageListItemBar.js @@ -4,6 +4,7 @@ import clsx from 'clsx'; import PropTypes from 'prop-types'; import * as React from 'react'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import capitalize from '../utils/capitalize'; import { getImageListItemBarUtilityClass } from './imageListItemBarClasses'; @@ -38,45 +39,47 @@ const ImageListItemBarRoot = styled('div', { return [styles.root, styles[`position${capitalize(ownerState.position)}`]]; }, -})(({ theme }) => { - return { - position: 'absolute', - left: 0, - right: 0, - background: 'rgba(0, 0, 0, 0.5)', - display: 'flex', - alignItems: 'center', - fontFamily: theme.typography.fontFamily, - variants: [ - { - props: { - position: 'bottom', +})( + memoTheme(({ theme }) => { + return { + position: 'absolute', + left: 0, + right: 0, + background: 'rgba(0, 0, 0, 0.5)', + display: 'flex', + alignItems: 'center', + fontFamily: theme.typography.fontFamily, + variants: [ + { + props: { + position: 'bottom', + }, + style: { + bottom: 0, + }, }, - style: { - bottom: 0, + { + props: { + position: 'top', + }, + style: { + top: 0, + }, }, - }, - { - props: { - position: 'top', - }, - style: { - top: 0, - }, - }, - { - props: { - position: 'below', - }, - style: { - position: 'relative', - background: 'transparent', - alignItems: 'normal', + { + props: { + position: 'below', + }, + style: { + position: 'relative', + background: 'transparent', + alignItems: 'normal', + }, }, - }, - ], - }; -}); + ], + }; + }), +); const ImageListItemBarTitleWrap = styled('div', { name: 'MuiImageListItemBar', @@ -90,65 +93,71 @@ const ImageListItemBarTitleWrap = styled('div', { ownerState.actionIcon && styles[`titleWrapActionPos${capitalize(ownerState.actionPosition)}`], ]; }, -})(({ theme }) => { - return { - flexGrow: 1, - padding: '12px 16px', - color: (theme.vars || theme).palette.common.white, - overflow: 'hidden', - variants: [ - { - props: { - position: 'below', - }, - style: { - padding: '6px 0 12px', - color: 'inherit', +})( + memoTheme(({ theme }) => { + return { + flexGrow: 1, + padding: '12px 16px', + color: (theme.vars || theme).palette.common.white, + overflow: 'hidden', + variants: [ + { + props: { + position: 'below', + }, + style: { + padding: '6px 0 12px', + color: 'inherit', + }, }, - }, - { - props: ({ ownerState }) => ownerState.actionIcon && ownerState.actionPosition === 'left', - style: { - paddingLeft: 0, + { + props: ({ ownerState }) => ownerState.actionIcon && ownerState.actionPosition === 'left', + style: { + paddingLeft: 0, + }, }, - }, - { - props: ({ ownerState }) => ownerState.actionIcon && ownerState.actionPosition === 'right', - style: { - paddingRight: 0, + { + props: ({ ownerState }) => ownerState.actionIcon && ownerState.actionPosition === 'right', + style: { + paddingRight: 0, + }, }, - }, - ], - }; -}); + ], + }; + }), +); const ImageListItemBarTitle = styled('div', { name: 'MuiImageListItemBar', slot: 'Title', overridesResolver: (props, styles) => styles.title, -})(({ theme }) => { - return { - fontSize: theme.typography.pxToRem(16), - lineHeight: '24px', - textOverflow: 'ellipsis', - overflow: 'hidden', - whiteSpace: 'nowrap', - }; -}); +})( + memoTheme(({ theme }) => { + return { + fontSize: theme.typography.pxToRem(16), + lineHeight: '24px', + textOverflow: 'ellipsis', + overflow: 'hidden', + whiteSpace: 'nowrap', + }; + }), +); const ImageListItemBarSubtitle = styled('div', { name: 'MuiImageListItemBar', slot: 'Subtitle', overridesResolver: (props, styles) => styles.subtitle, -})(({ theme }) => { - return { - fontSize: theme.typography.pxToRem(12), - lineHeight: 1, - textOverflow: 'ellipsis', - overflow: 'hidden', - whiteSpace: 'nowrap', - }; -}); +})( + memoTheme(({ theme }) => { + return { + fontSize: theme.typography.pxToRem(12), + lineHeight: 1, + textOverflow: 'ellipsis', + overflow: 'hidden', + whiteSpace: 'nowrap', + }; + }), +); const ImageListItemBarActionIcon = styled('div', { name: 'MuiImageListItemBar', diff --git a/packages/mui-material/src/Input/Input.js b/packages/mui-material/src/Input/Input.js index 4e7fd4525a36f8..aabc346951caae 100644 --- a/packages/mui-material/src/Input/Input.js +++ b/packages/mui-material/src/Input/Input.js @@ -7,6 +7,7 @@ import refType from '@mui/utils/refType'; import InputBase from '../InputBase'; import rootShouldForwardProp from '../styles/rootShouldForwardProp'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import inputClasses, { getInputUtilityClass } from './inputClasses'; import { @@ -44,86 +45,88 @@ const InputRoot = styled(InputBaseRoot, { !ownerState.disableUnderline && styles.underline, ]; }, -})(({ theme }) => { - const light = theme.palette.mode === 'light'; - let bottomLineColor = light ? 'rgba(0, 0, 0, 0.42)' : 'rgba(255, 255, 255, 0.7)'; - if (theme.vars) { - bottomLineColor = `rgba(${theme.vars.palette.common.onBackgroundChannel} / ${theme.vars.opacity.inputUnderline})`; - } - return { - position: 'relative', - variants: [ - { - props: ({ ownerState }) => ownerState.formControl, - style: { - 'label + &': { - marginTop: 16, +})( + memoTheme(({ theme }) => { + const light = theme.palette.mode === 'light'; + let bottomLineColor = light ? 'rgba(0, 0, 0, 0.42)' : 'rgba(255, 255, 255, 0.7)'; + if (theme.vars) { + bottomLineColor = `rgba(${theme.vars.palette.common.onBackgroundChannel} / ${theme.vars.opacity.inputUnderline})`; + } + return { + position: 'relative', + variants: [ + { + props: ({ ownerState }) => ownerState.formControl, + style: { + 'label + &': { + marginTop: 16, + }, }, }, - }, - { - props: ({ ownerState }) => !ownerState.disableUnderline, - style: { - '&::after': { - left: 0, - bottom: 0, - content: '""', - position: 'absolute', - right: 0, - transform: 'scaleX(0)', - transition: theme.transitions.create('transform', { - duration: theme.transitions.duration.shorter, - easing: theme.transitions.easing.easeOut, - }), - pointerEvents: 'none', // Transparent to the hover style. - }, - [`&.${inputClasses.focused}:after`]: { - // translateX(0) is a workaround for Safari transform scale bug - // See https://github.com/mui/material-ui/issues/31766 - transform: 'scaleX(1) translateX(0)', - }, - [`&.${inputClasses.error}`]: { - '&::before, &::after': { - borderBottomColor: (theme.vars || theme).palette.error.main, + { + props: ({ ownerState }) => !ownerState.disableUnderline, + style: { + '&::after': { + left: 0, + bottom: 0, + content: '""', + position: 'absolute', + right: 0, + transform: 'scaleX(0)', + transition: theme.transitions.create('transform', { + duration: theme.transitions.duration.shorter, + easing: theme.transitions.easing.easeOut, + }), + pointerEvents: 'none', // Transparent to the hover style. }, - }, - '&::before': { - borderBottom: `1px solid ${bottomLineColor}`, - left: 0, - bottom: 0, - content: '"\\00a0"', - position: 'absolute', - right: 0, - transition: theme.transitions.create('border-bottom-color', { - duration: theme.transitions.duration.shorter, - }), - pointerEvents: 'none', // Transparent to the hover style. - }, - [`&:hover:not(.${inputClasses.disabled}, .${inputClasses.error}):before`]: { - borderBottom: `2px solid ${(theme.vars || theme).palette.text.primary}`, - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { + [`&.${inputClasses.focused}:after`]: { + // translateX(0) is a workaround for Safari transform scale bug + // See https://github.com/mui/material-ui/issues/31766 + transform: 'scaleX(1) translateX(0)', + }, + [`&.${inputClasses.error}`]: { + '&::before, &::after': { + borderBottomColor: (theme.vars || theme).palette.error.main, + }, + }, + '&::before': { borderBottom: `1px solid ${bottomLineColor}`, + left: 0, + bottom: 0, + content: '"\\00a0"', + position: 'absolute', + right: 0, + transition: theme.transitions.create('border-bottom-color', { + duration: theme.transitions.duration.shorter, + }), + pointerEvents: 'none', // Transparent to the hover style. + }, + [`&:hover:not(.${inputClasses.disabled}, .${inputClasses.error}):before`]: { + borderBottom: `2px solid ${(theme.vars || theme).palette.text.primary}`, + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + borderBottom: `1px solid ${bottomLineColor}`, + }, + }, + [`&.${inputClasses.disabled}:before`]: { + borderBottomStyle: 'dotted', }, - }, - [`&.${inputClasses.disabled}:before`]: { - borderBottomStyle: 'dotted', }, }, - }, - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main) - .map(([color]) => ({ - props: { color, disableUnderline: false }, - style: { - '&::after': { - borderBottom: `2px solid ${(theme.vars || theme).palette[color].main}`, + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main) + .map(([color]) => ({ + props: { color, disableUnderline: false }, + style: { + '&::after': { + borderBottom: `2px solid ${(theme.vars || theme).palette[color].main}`, + }, }, - }, - })), - ], - }; -}); + })), + ], + }; + }), +); const InputInput = styled(InputBaseInput, { name: 'MuiInput', diff --git a/packages/mui-material/src/InputAdornment/InputAdornment.js b/packages/mui-material/src/InputAdornment/InputAdornment.js index dcb85e41a1b8bc..4d0b4df0e73b1d 100644 --- a/packages/mui-material/src/InputAdornment/InputAdornment.js +++ b/packages/mui-material/src/InputAdornment/InputAdornment.js @@ -8,6 +8,7 @@ import Typography from '../Typography'; import FormControlContext from '../FormControl/FormControlContext'; import useFormControl from '../FormControl/useFormControl'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import inputAdornmentClasses, { getInputAdornmentUtilityClass } from './inputAdornmentClasses'; @@ -42,49 +43,52 @@ const InputAdornmentRoot = styled('div', { name: 'MuiInputAdornment', slot: 'Root', overridesResolver, -})(({ theme }) => ({ - display: 'flex', - maxHeight: '2em', - alignItems: 'center', - whiteSpace: 'nowrap', - color: (theme.vars || theme).palette.action.active, - variants: [ - { - props: { - variant: 'filled', - }, - style: { - [`&.${inputAdornmentClasses.positionStart}&:not(.${inputAdornmentClasses.hiddenLabel})`]: { - marginTop: 16, +})( + memoTheme(({ theme }) => ({ + display: 'flex', + maxHeight: '2em', + alignItems: 'center', + whiteSpace: 'nowrap', + color: (theme.vars || theme).palette.action.active, + variants: [ + { + props: { + variant: 'filled', + }, + style: { + [`&.${inputAdornmentClasses.positionStart}&:not(.${inputAdornmentClasses.hiddenLabel})`]: + { + marginTop: 16, + }, }, }, - }, - { - props: { - position: 'start', - }, - style: { - marginRight: 8, - }, - }, - { - props: { - position: 'end', - }, - style: { - marginLeft: 8, + { + props: { + position: 'start', + }, + style: { + marginRight: 8, + }, }, - }, - { - props: { - disablePointerEvents: true, + { + props: { + position: 'end', + }, + style: { + marginLeft: 8, + }, }, - style: { - pointerEvents: 'none', + { + props: { + disablePointerEvents: true, + }, + style: { + pointerEvents: 'none', + }, }, - }, - ], -})); + ], + })), +); const InputAdornment = React.forwardRef(function InputAdornment(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiInputAdornment' }); diff --git a/packages/mui-material/src/InputBase/InputBase.js b/packages/mui-material/src/InputBase/InputBase.js index 9dd59f8509ea30..5f9c6cd0ba8816 100644 --- a/packages/mui-material/src/InputBase/InputBase.js +++ b/packages/mui-material/src/InputBase/InputBase.js @@ -12,6 +12,7 @@ import formControlState from '../FormControl/formControlState'; import FormControlContext from '../FormControl/FormControlContext'; import useFormControl from '../FormControl/useFormControl'; import { styled, globalCss } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import capitalize from '../utils/capitalize'; import useForkRef from '../utils/useForkRef'; @@ -103,153 +104,157 @@ export const InputBaseRoot = styled('div', { name: 'MuiInputBase', slot: 'Root', overridesResolver: rootOverridesResolver, -})(({ theme }) => ({ - ...theme.typography.body1, - color: (theme.vars || theme).palette.text.primary, - lineHeight: '1.4375em', // 23px - boxSizing: 'border-box', // Prevent padding issue with fullWidth. - position: 'relative', - cursor: 'text', - display: 'inline-flex', - alignItems: 'center', - [`&.${inputBaseClasses.disabled}`]: { - color: (theme.vars || theme).palette.text.disabled, - cursor: 'default', - }, - variants: [ - { - props: ({ ownerState }) => ownerState.multiline, - style: { - padding: '4px 0 5px', - }, - }, - { - props: ({ ownerState, size }) => ownerState.multiline && size === 'small', - style: { - paddingTop: 1, - }, - }, - { - props: ({ ownerState }) => ownerState.fullWidth, - style: { - width: '100%', - }, - }, - ], -})); - -export const InputBaseInput = styled('input', { - name: 'MuiInputBase', - slot: 'Input', - overridesResolver: inputOverridesResolver, -})(({ theme }) => { - const light = theme.palette.mode === 'light'; - const placeholder = { - color: 'currentColor', - ...(theme.vars - ? { - opacity: theme.vars.opacity.inputPlaceholder, - } - : { - opacity: light ? 0.42 : 0.5, - }), - transition: theme.transitions.create('opacity', { - duration: theme.transitions.duration.shorter, - }), - }; - const placeholderHidden = { - opacity: '0 !important', - }; - const placeholderVisible = theme.vars - ? { - opacity: theme.vars.opacity.inputPlaceholder, - } - : { - opacity: light ? 0.42 : 0.5, - }; - - return { - font: 'inherit', - letterSpacing: 'inherit', - color: 'currentColor', - padding: '4px 0 5px', - border: 0, - boxSizing: 'content-box', - background: 'none', - height: '1.4375em', // Reset 23pxthe native input line-height - margin: 0, // Reset for Safari - WebkitTapHighlightColor: 'transparent', - display: 'block', - // Make the flex item shrink with Firefox - minWidth: 0, - width: '100%', - '&::-webkit-input-placeholder': placeholder, - '&::-moz-placeholder': placeholder, // Firefox 19+ - '&::-ms-input-placeholder': placeholder, // Edge - '&:focus': { - outline: 0, - }, - // Reset Firefox invalid required input style - '&:invalid': { - boxShadow: 'none', - }, - '&::-webkit-search-decoration': { - // Remove the padding when type=search. - WebkitAppearance: 'none', - }, - // Show and hide the placeholder logic - [`label[data-shrink=false] + .${inputBaseClasses.formControl} &`]: { - '&::-webkit-input-placeholder': placeholderHidden, - '&::-moz-placeholder': placeholderHidden, // Firefox 19+ - '&::-ms-input-placeholder': placeholderHidden, // Edge - '&:focus::-webkit-input-placeholder': placeholderVisible, - '&:focus::-moz-placeholder': placeholderVisible, // Firefox 19+ - '&:focus::-ms-input-placeholder': placeholderVisible, // Edge - }, +})( + memoTheme(({ theme }) => ({ + ...theme.typography.body1, + color: (theme.vars || theme).palette.text.primary, + lineHeight: '1.4375em', // 23px + boxSizing: 'border-box', // Prevent padding issue with fullWidth. + position: 'relative', + cursor: 'text', + display: 'inline-flex', + alignItems: 'center', [`&.${inputBaseClasses.disabled}`]: { - opacity: 1, // Reset iOS opacity - WebkitTextFillColor: (theme.vars || theme).palette.text.disabled, // Fix opacity Safari bug + color: (theme.vars || theme).palette.text.disabled, + cursor: 'default', }, variants: [ { - props: ({ ownerState }) => !ownerState.disableInjectingGlobalStyles, + props: ({ ownerState }) => ownerState.multiline, style: { - animationName: 'mui-auto-fill-cancel', - animationDuration: '10ms', - '&:-webkit-autofill': { - animationDuration: '5000s', - animationName: 'mui-auto-fill', - }, + padding: '4px 0 5px', }, }, { - props: { - size: 'small', - }, + props: ({ ownerState, size }) => ownerState.multiline && size === 'small', style: { paddingTop: 1, }, }, { - props: ({ ownerState }) => ownerState.multiline, + props: ({ ownerState }) => ownerState.fullWidth, style: { - height: 'auto', - resize: 'none', - padding: 0, - paddingTop: 0, + width: '100%', }, }, - { - props: { - type: 'search', + ], + })), +); + +export const InputBaseInput = styled('input', { + name: 'MuiInputBase', + slot: 'Input', + overridesResolver: inputOverridesResolver, +})( + memoTheme(({ theme }) => { + const light = theme.palette.mode === 'light'; + const placeholder = { + color: 'currentColor', + ...(theme.vars + ? { + opacity: theme.vars.opacity.inputPlaceholder, + } + : { + opacity: light ? 0.42 : 0.5, + }), + transition: theme.transitions.create('opacity', { + duration: theme.transitions.duration.shorter, + }), + }; + const placeholderHidden = { + opacity: '0 !important', + }; + const placeholderVisible = theme.vars + ? { + opacity: theme.vars.opacity.inputPlaceholder, + } + : { + opacity: light ? 0.42 : 0.5, + }; + + return { + font: 'inherit', + letterSpacing: 'inherit', + color: 'currentColor', + padding: '4px 0 5px', + border: 0, + boxSizing: 'content-box', + background: 'none', + height: '1.4375em', // Reset 23pxthe native input line-height + margin: 0, // Reset for Safari + WebkitTapHighlightColor: 'transparent', + display: 'block', + // Make the flex item shrink with Firefox + minWidth: 0, + width: '100%', + '&::-webkit-input-placeholder': placeholder, + '&::-moz-placeholder': placeholder, // Firefox 19+ + '&::-ms-input-placeholder': placeholder, // Edge + '&:focus': { + outline: 0, + }, + // Reset Firefox invalid required input style + '&:invalid': { + boxShadow: 'none', + }, + '&::-webkit-search-decoration': { + // Remove the padding when type=search. + WebkitAppearance: 'none', + }, + // Show and hide the placeholder logic + [`label[data-shrink=false] + .${inputBaseClasses.formControl} &`]: { + '&::-webkit-input-placeholder': placeholderHidden, + '&::-moz-placeholder': placeholderHidden, // Firefox 19+ + '&::-ms-input-placeholder': placeholderHidden, // Edge + '&:focus::-webkit-input-placeholder': placeholderVisible, + '&:focus::-moz-placeholder': placeholderVisible, // Firefox 19+ + '&:focus::-ms-input-placeholder': placeholderVisible, // Edge + }, + [`&.${inputBaseClasses.disabled}`]: { + opacity: 1, // Reset iOS opacity + WebkitTextFillColor: (theme.vars || theme).palette.text.disabled, // Fix opacity Safari bug + }, + variants: [ + { + props: ({ ownerState }) => !ownerState.disableInjectingGlobalStyles, + style: { + animationName: 'mui-auto-fill-cancel', + animationDuration: '10ms', + '&:-webkit-autofill': { + animationDuration: '5000s', + animationName: 'mui-auto-fill', + }, + }, }, - style: { - MozAppearance: 'textfield', // Improve type search style. + { + props: { + size: 'small', + }, + style: { + paddingTop: 1, + }, }, - }, - ], - }; -}); + { + props: ({ ownerState }) => ownerState.multiline, + style: { + height: 'auto', + resize: 'none', + padding: 0, + paddingTop: 0, + }, + }, + { + props: { + type: 'search', + }, + style: { + MozAppearance: 'textfield', // Improve type search style. + }, + }, + ], + }; + }), +); const InputGlobalStyles = globalCss({ '@keyframes mui-auto-fill': { from: { display: 'block' } }, diff --git a/packages/mui-material/src/InputLabel/InputLabel.js b/packages/mui-material/src/InputLabel/InputLabel.js index 71db13aecba3f4..e8fc58f3739d37 100644 --- a/packages/mui-material/src/InputLabel/InputLabel.js +++ b/packages/mui-material/src/InputLabel/InputLabel.js @@ -9,6 +9,7 @@ import FormLabel, { formLabelClasses } from '../FormLabel'; import capitalize from '../utils/capitalize'; import rootShouldForwardProp from '../styles/rootShouldForwardProp'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import { getInputLabelUtilityClasses } from './inputLabelClasses'; @@ -51,124 +52,126 @@ const InputLabelRoot = styled(FormLabel, { styles[ownerState.variant], ]; }, -})(({ theme }) => ({ - display: 'block', - transformOrigin: 'top left', - whiteSpace: 'nowrap', - overflow: 'hidden', - textOverflow: 'ellipsis', - maxWidth: '100%', - variants: [ - { - props: ({ ownerState }) => ownerState.formControl, - style: { - position: 'absolute', - left: 0, - top: 0, - // slight alteration to spec spacing to match visual spec result - transform: 'translate(0, 20px) scale(1)', +})( + memoTheme(({ theme }) => ({ + display: 'block', + transformOrigin: 'top left', + whiteSpace: 'nowrap', + overflow: 'hidden', + textOverflow: 'ellipsis', + maxWidth: '100%', + variants: [ + { + props: ({ ownerState }) => ownerState.formControl, + style: { + position: 'absolute', + left: 0, + top: 0, + // slight alteration to spec spacing to match visual spec result + transform: 'translate(0, 20px) scale(1)', + }, }, - }, - { - props: { - size: 'small', + { + props: { + size: 'small', + }, + style: { + // Compensation for the `Input.inputSizeSmall` style. + transform: 'translate(0, 17px) scale(1)', + }, }, - style: { - // Compensation for the `Input.inputSizeSmall` style. - transform: 'translate(0, 17px) scale(1)', + { + props: ({ ownerState }) => ownerState.shrink, + style: { + transform: 'translate(0, -1.5px) scale(0.75)', + transformOrigin: 'top left', + maxWidth: '133%', + }, }, - }, - { - props: ({ ownerState }) => ownerState.shrink, - style: { - transform: 'translate(0, -1.5px) scale(0.75)', - transformOrigin: 'top left', - maxWidth: '133%', + { + props: ({ ownerState }) => !ownerState.disableAnimation, + style: { + transition: theme.transitions.create(['color', 'transform', 'max-width'], { + duration: theme.transitions.duration.shorter, + easing: theme.transitions.easing.easeOut, + }), + }, }, - }, - { - props: ({ ownerState }) => !ownerState.disableAnimation, - style: { - transition: theme.transitions.create(['color', 'transform', 'max-width'], { - duration: theme.transitions.duration.shorter, - easing: theme.transitions.easing.easeOut, - }), + { + props: { + variant: 'filled', + }, + style: { + // Chrome's autofill feature gives the input field a yellow background. + // Since the input field is behind the label in the HTML tree, + // the input field is drawn last and hides the label with an opaque background color. + // zIndex: 1 will raise the label above opaque background-colors of input. + zIndex: 1, + pointerEvents: 'none', + transform: 'translate(12px, 16px) scale(1)', + maxWidth: 'calc(100% - 24px)', + }, }, - }, - { - props: { - variant: 'filled', + { + props: { + variant: 'filled', + size: 'small', + }, + style: { + transform: 'translate(12px, 13px) scale(1)', + }, }, - style: { - // Chrome's autofill feature gives the input field a yellow background. - // Since the input field is behind the label in the HTML tree, - // the input field is drawn last and hides the label with an opaque background color. - // zIndex: 1 will raise the label above opaque background-colors of input. - zIndex: 1, - pointerEvents: 'none', - transform: 'translate(12px, 16px) scale(1)', - maxWidth: 'calc(100% - 24px)', + { + props: ({ variant, ownerState }) => variant === 'filled' && ownerState.shrink, + style: { + userSelect: 'none', + pointerEvents: 'auto', + transform: 'translate(12px, 7px) scale(0.75)', + maxWidth: 'calc(133% - 24px)', + }, }, - }, - { - props: { - variant: 'filled', - size: 'small', + { + props: ({ variant, ownerState, size }) => + variant === 'filled' && ownerState.shrink && size === 'small', + style: { + transform: 'translate(12px, 4px) scale(0.75)', + }, }, - style: { - transform: 'translate(12px, 13px) scale(1)', + { + props: { + variant: 'outlined', + }, + style: { + // see comment above on filled.zIndex + zIndex: 1, + pointerEvents: 'none', + transform: 'translate(14px, 16px) scale(1)', + maxWidth: 'calc(100% - 24px)', + }, }, - }, - { - props: ({ variant, ownerState }) => variant === 'filled' && ownerState.shrink, - style: { - userSelect: 'none', - pointerEvents: 'auto', - transform: 'translate(12px, 7px) scale(0.75)', - maxWidth: 'calc(133% - 24px)', + { + props: { + variant: 'outlined', + size: 'small', + }, + style: { + transform: 'translate(14px, 9px) scale(1)', + }, }, - }, - { - props: ({ variant, ownerState, size }) => - variant === 'filled' && ownerState.shrink && size === 'small', - style: { - transform: 'translate(12px, 4px) scale(0.75)', + { + props: ({ variant, ownerState }) => variant === 'outlined' && ownerState.shrink, + style: { + userSelect: 'none', + pointerEvents: 'auto', + // Theoretically, we should have (8+5)*2/0.75 = 34px + // but it feels a better when it bleeds a bit on the left, so 32px. + maxWidth: 'calc(133% - 32px)', + transform: 'translate(14px, -9px) scale(0.75)', + }, }, - }, - { - props: { - variant: 'outlined', - }, - style: { - // see comment above on filled.zIndex - zIndex: 1, - pointerEvents: 'none', - transform: 'translate(14px, 16px) scale(1)', - maxWidth: 'calc(100% - 24px)', - }, - }, - { - props: { - variant: 'outlined', - size: 'small', - }, - style: { - transform: 'translate(14px, 9px) scale(1)', - }, - }, - { - props: ({ variant, ownerState }) => variant === 'outlined' && ownerState.shrink, - style: { - userSelect: 'none', - pointerEvents: 'auto', - // Theoretically, we should have (8+5)*2/0.75 = 34px - // but it feels a better when it bleeds a bit on the left, so 32px. - maxWidth: 'calc(133% - 32px)', - transform: 'translate(14px, -9px) scale(0.75)', - }, - }, - ], -})); + ], + })), +); const InputLabel = React.forwardRef(function InputLabel(inProps, ref) { const props = useDefaultProps({ name: 'MuiInputLabel', props: inProps }); diff --git a/packages/mui-material/src/LinearProgress/LinearProgress.js b/packages/mui-material/src/LinearProgress/LinearProgress.js index bc4366a91fa801..d3224fd41a2ef8 100644 --- a/packages/mui-material/src/LinearProgress/LinearProgress.js +++ b/packages/mui-material/src/LinearProgress/LinearProgress.js @@ -6,6 +6,7 @@ import composeClasses from '@mui/utils/composeClasses'; import { darken, lighten } from '@mui/system/colorManipulator'; import { useRtl } from '@mui/system/RtlProvider'; import { keyframes, css, styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import capitalize from '../utils/capitalize'; import { getLinearProgressUtilityClass } from './linearProgressClasses'; @@ -130,50 +131,53 @@ const LinearProgressRoot = styled('span', { styles[ownerState.variant], ]; }, -})(({ theme }) => ({ - position: 'relative', - overflow: 'hidden', - display: 'block', - height: 4, - // Fix Safari's bug during composition of different paint. - zIndex: 0, - '@media print': { - colorAdjust: 'exact', - }, - variants: [ - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main) - .map(([color]) => ({ - props: { color }, +})( + memoTheme(({ theme }) => ({ + position: 'relative', + overflow: 'hidden', + display: 'block', + height: 4, + // Fix Safari's bug during composition of different paint. + zIndex: 0, + '@media print': { + colorAdjust: 'exact', + }, + variants: [ + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main) + .map(([color]) => ({ + props: { color }, + style: { + backgroundColor: getColorShade(theme, color), + }, + })), + { + props: ({ ownerState }) => + ownerState.color === 'inherit' && ownerState.variant !== 'buffer', style: { - backgroundColor: getColorShade(theme, color), - }, - })), - { - props: ({ ownerState }) => ownerState.color === 'inherit' && ownerState.variant !== 'buffer', - style: { - '&::before': { - content: '""', - position: 'absolute', - left: 0, - top: 0, - right: 0, - bottom: 0, - backgroundColor: 'currentColor', - opacity: 0.3, + '&::before': { + content: '""', + position: 'absolute', + left: 0, + top: 0, + right: 0, + bottom: 0, + backgroundColor: 'currentColor', + opacity: 0.3, + }, }, }, - }, - { - props: { variant: 'buffer' }, - style: { backgroundColor: 'transparent' }, - }, - { - props: { variant: 'query' }, - style: { transform: 'rotate(180deg)' }, - }, - ], -})); + { + props: { variant: 'buffer' }, + style: { backgroundColor: 'transparent' }, + }, + { + props: { variant: 'query' }, + style: { transform: 'rotate(180deg)' }, + }, + ], + })), +); const LinearProgressDashed = styled('span', { name: 'MuiLinearProgress', @@ -184,7 +188,7 @@ const LinearProgressDashed = styled('span', { return [styles.dashed, styles[`dashedColor${capitalize(ownerState.color)}`]]; }, })( - ({ theme }) => ({ + memoTheme(({ theme }) => ({ position: 'absolute', marginTop: 0, height: '100%', @@ -211,7 +215,7 @@ const LinearProgressDashed = styled('span', { }; }), ], - }), + })), bufferAnimation || { // At runtime for Pigment CSS, `bufferAnimation` will be null and the generated keyframe will be used. animation: `${bufferKeyframe} 3s infinite linear`, @@ -233,64 +237,66 @@ const LinearProgressBar1 = styled('span', { ownerState.variant === 'buffer' && styles.bar1Buffer, ]; }, -})(({ theme }) => ({ - width: '100%', - position: 'absolute', - left: 0, - bottom: 0, - top: 0, - transition: 'transform 0.2s linear', - transformOrigin: 'left', - variants: [ - { - props: { - color: 'inherit', - }, - style: { - backgroundColor: 'currentColor', - }, - }, - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main) - .map(([color]) => ({ - props: { color }, +})( + memoTheme(({ theme }) => ({ + width: '100%', + position: 'absolute', + left: 0, + bottom: 0, + top: 0, + transition: 'transform 0.2s linear', + transformOrigin: 'left', + variants: [ + { + props: { + color: 'inherit', + }, style: { - backgroundColor: (theme.vars || theme).palette[color].main, + backgroundColor: 'currentColor', }, - })), - { - props: { - variant: 'determinate', - }, - style: { - transition: `transform .${TRANSITION_DURATION}s linear`, }, - }, - { - props: { - variant: 'buffer', + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main) + .map(([color]) => ({ + props: { color }, + style: { + backgroundColor: (theme.vars || theme).palette[color].main, + }, + })), + { + props: { + variant: 'determinate', + }, + style: { + transition: `transform .${TRANSITION_DURATION}s linear`, + }, }, - style: { - zIndex: 1, - transition: `transform .${TRANSITION_DURATION}s linear`, + { + props: { + variant: 'buffer', + }, + style: { + zIndex: 1, + transition: `transform .${TRANSITION_DURATION}s linear`, + }, }, - }, - { - props: ({ ownerState }) => - ownerState.variant === 'indeterminate' || ownerState.variant === 'query', - style: { - width: 'auto', + { + props: ({ ownerState }) => + ownerState.variant === 'indeterminate' || ownerState.variant === 'query', + style: { + width: 'auto', + }, }, - }, - { - props: ({ ownerState }) => - ownerState.variant === 'indeterminate' || ownerState.variant === 'query', - style: indeterminate1Animation || { - animation: `${indeterminate1Keyframe} 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite`, + { + props: ({ ownerState }) => + ownerState.variant === 'indeterminate' || ownerState.variant === 'query', + style: indeterminate1Animation || { + animation: `${indeterminate1Keyframe} 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite`, + }, }, - }, - ], -})); + ], + })), +); const LinearProgressBar2 = styled('span', { name: 'MuiLinearProgress', @@ -306,62 +312,65 @@ const LinearProgressBar2 = styled('span', { ownerState.variant === 'buffer' && styles.bar2Buffer, ]; }, -})(({ theme }) => ({ - width: '100%', - position: 'absolute', - left: 0, - bottom: 0, - top: 0, - transition: 'transform 0.2s linear', - transformOrigin: 'left', - variants: [ - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main) - .map(([color]) => ({ - props: { color }, +})( + memoTheme(({ theme }) => ({ + width: '100%', + position: 'absolute', + left: 0, + bottom: 0, + top: 0, + transition: 'transform 0.2s linear', + transformOrigin: 'left', + variants: [ + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main) + .map(([color]) => ({ + props: { color }, + style: { + '--LinearProgressBar2-barColor': (theme.vars || theme).palette[color].main, + }, + })), + { + props: ({ ownerState }) => + ownerState.variant !== 'buffer' && ownerState.color !== 'inherit', style: { - '--LinearProgressBar2-barColor': (theme.vars || theme).palette[color].main, + backgroundColor: 'var(--LinearProgressBar2-barColor, currentColor)', }, - })), - { - props: ({ ownerState }) => ownerState.variant !== 'buffer' && ownerState.color !== 'inherit', - style: { - backgroundColor: 'var(--LinearProgressBar2-barColor, currentColor)', - }, - }, - { - props: { - color: 'inherit', }, - style: { - opacity: 0.3, + { + props: { + color: 'inherit', + }, + style: { + opacity: 0.3, + }, }, - }, - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main) - .map(([color]) => ({ - props: { color, variant: 'buffer' }, + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main) + .map(([color]) => ({ + props: { color, variant: 'buffer' }, + style: { + backgroundColor: getColorShade(theme, color), + transition: `transform .${TRANSITION_DURATION}s linear`, + }, + })), + { + props: ({ ownerState }) => + ownerState.variant === 'indeterminate' || ownerState.variant === 'query', style: { - backgroundColor: getColorShade(theme, color), - transition: `transform .${TRANSITION_DURATION}s linear`, + width: 'auto', }, - })), - { - props: ({ ownerState }) => - ownerState.variant === 'indeterminate' || ownerState.variant === 'query', - style: { - width: 'auto', }, - }, - { - props: ({ ownerState }) => - ownerState.variant === 'indeterminate' || ownerState.variant === 'query', - style: indeterminate2Animation || { - animation: `${indeterminate2Keyframe} 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) 1.15s infinite`, + { + props: ({ ownerState }) => + ownerState.variant === 'indeterminate' || ownerState.variant === 'query', + style: indeterminate2Animation || { + animation: `${indeterminate2Keyframe} 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) 1.15s infinite`, + }, }, - }, - ], -})); + ], + })), +); /** * ## ARIA diff --git a/packages/mui-material/src/Link/Link.js b/packages/mui-material/src/Link/Link.js index a452e41828657e..456c5b20805a2e 100644 --- a/packages/mui-material/src/Link/Link.js +++ b/packages/mui-material/src/Link/Link.js @@ -8,6 +8,7 @@ import composeClasses from '@mui/utils/composeClasses'; import isFocusVisible from '@mui/utils/isFocusVisible'; import capitalize from '../utils/capitalize'; import { styled, useTheme } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import Typography from '../Typography'; import linkClasses, { getLinkUtilityClass } from './linkClasses'; @@ -52,108 +53,110 @@ const LinkRoot = styled(Typography, { ownerState.component === 'button' && styles.button, ]; }, -})(({ theme }) => { - return { - variants: [ - { - props: { - underline: 'none', - }, - style: { - textDecoration: 'none', +})( + memoTheme(({ theme }) => { + return { + variants: [ + { + props: { + underline: 'none', + }, + style: { + textDecoration: 'none', + }, }, - }, - { - props: { - underline: 'hover', + { + props: { + underline: 'hover', + }, + style: { + textDecoration: 'none', + '&:hover': { + textDecoration: 'underline', + }, + }, }, - style: { - textDecoration: 'none', - '&:hover': { + { + props: { + underline: 'always', + }, + style: { textDecoration: 'underline', + '&:hover': { + textDecorationColor: 'inherit', + }, }, }, - }, - { - props: { - underline: 'always', - }, - style: { - textDecoration: 'underline', - '&:hover': { - textDecorationColor: 'inherit', + { + props: ({ underline, ownerState }) => + underline === 'always' && ownerState.color !== 'inherit', + style: { + textDecorationColor: 'var(--Link-underlineColor)', }, }, - }, - { - props: ({ underline, ownerState }) => - underline === 'always' && ownerState.color !== 'inherit', - style: { - textDecorationColor: 'var(--Link-underlineColor)', - }, - }, - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main) - .map(([color]) => ({ - props: { underline: 'always', color }, + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main) + .map(([color]) => ({ + props: { underline: 'always', color }, + style: { + '--Link-underlineColor': theme.vars + ? `rgba(${theme.vars.palette[color].mainChannel} / 0.4)` + : alpha(theme.palette[color].main, 0.4), + }, + })), + { + props: { underline: 'always', color: 'textPrimary' }, style: { '--Link-underlineColor': theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / 0.4)` - : alpha(theme.palette[color].main, 0.4), + ? `rgba(${theme.vars.palette.text.primaryChannel} / 0.4)` + : alpha(theme.palette.text.primary, 0.4), }, - })), - { - props: { underline: 'always', color: 'textPrimary' }, - style: { - '--Link-underlineColor': theme.vars - ? `rgba(${theme.vars.palette.text.primaryChannel} / 0.4)` - : alpha(theme.palette.text.primary, 0.4), - }, - }, - { - props: { underline: 'always', color: 'textSecondary' }, - style: { - '--Link-underlineColor': theme.vars - ? `rgba(${theme.vars.palette.text.secondaryChannel} / 0.4)` - : alpha(theme.palette.text.secondary, 0.4), }, - }, - { - props: { underline: 'always', color: 'textDisabled' }, - style: { - '--Link-underlineColor': (theme.vars || theme).palette.text.disabled, + { + props: { underline: 'always', color: 'textSecondary' }, + style: { + '--Link-underlineColor': theme.vars + ? `rgba(${theme.vars.palette.text.secondaryChannel} / 0.4)` + : alpha(theme.palette.text.secondary, 0.4), + }, }, - }, - { - props: { - component: 'button', + { + props: { underline: 'always', color: 'textDisabled' }, + style: { + '--Link-underlineColor': (theme.vars || theme).palette.text.disabled, + }, }, - style: { - position: 'relative', - WebkitTapHighlightColor: 'transparent', - backgroundColor: 'transparent', // Reset default value - // We disable the focus ring for mouse, touch and keyboard users. - outline: 0, - border: 0, - margin: 0, // Remove the margin in Safari - borderRadius: 0, - padding: 0, // Remove the padding in Firefox - cursor: 'pointer', - userSelect: 'none', - verticalAlign: 'middle', - MozAppearance: 'none', // Reset - WebkitAppearance: 'none', // Reset - '&::-moz-focus-inner': { - borderStyle: 'none', // Remove Firefox dotted outline. + { + props: { + component: 'button', }, - [`&.${linkClasses.focusVisible}`]: { - outline: 'auto', + style: { + position: 'relative', + WebkitTapHighlightColor: 'transparent', + backgroundColor: 'transparent', // Reset default value + // We disable the focus ring for mouse, touch and keyboard users. + outline: 0, + border: 0, + margin: 0, // Remove the margin in Safari + borderRadius: 0, + padding: 0, // Remove the padding in Firefox + cursor: 'pointer', + userSelect: 'none', + verticalAlign: 'middle', + MozAppearance: 'none', // Reset + WebkitAppearance: 'none', // Reset + '&::-moz-focus-inner': { + borderStyle: 'none', // Remove Firefox dotted outline. + }, + [`&.${linkClasses.focusVisible}`]: { + outline: 'auto', + }, }, }, - }, - ], - }; -}); + ], + }; + }), +); const Link = React.forwardRef(function Link(inProps, ref) { const props = useDefaultProps({ diff --git a/packages/mui-material/src/ListItem/ListItem.js b/packages/mui-material/src/ListItem/ListItem.js index e435033a1f11c7..efb7fc11f42f44 100644 --- a/packages/mui-material/src/ListItem/ListItem.js +++ b/packages/mui-material/src/ListItem/ListItem.js @@ -7,6 +7,7 @@ import elementTypeAcceptingRef from '@mui/utils/elementTypeAcceptingRef'; import chainPropTypes from '@mui/utils/chainPropTypes'; import isHostComponent from '../utils/isHostComponent'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import isMuiElement from '../utils/isMuiElement'; import useForkRef from '../utils/useForkRef'; @@ -60,94 +61,96 @@ export const ListItemRoot = styled('div', { name: 'MuiListItem', slot: 'Root', overridesResolver, -})(({ theme }) => ({ - display: 'flex', - justifyContent: 'flex-start', - alignItems: 'center', - position: 'relative', - textDecoration: 'none', - width: '100%', - boxSizing: 'border-box', - textAlign: 'left', - variants: [ - { - props: ({ ownerState }) => !ownerState.disablePadding, - style: { - paddingTop: 8, - paddingBottom: 8, - }, - }, - { - props: ({ ownerState }) => !ownerState.disablePadding && ownerState.dense, - style: { - paddingTop: 4, - paddingBottom: 4, +})( + memoTheme(({ theme }) => ({ + display: 'flex', + justifyContent: 'flex-start', + alignItems: 'center', + position: 'relative', + textDecoration: 'none', + width: '100%', + boxSizing: 'border-box', + textAlign: 'left', + variants: [ + { + props: ({ ownerState }) => !ownerState.disablePadding, + style: { + paddingTop: 8, + paddingBottom: 8, + }, }, - }, - { - props: ({ ownerState }) => !ownerState.disablePadding && !ownerState.disableGutters, - style: { - paddingLeft: 16, - paddingRight: 16, + { + props: ({ ownerState }) => !ownerState.disablePadding && ownerState.dense, + style: { + paddingTop: 4, + paddingBottom: 4, + }, }, - }, - { - props: ({ ownerState }) => !ownerState.disablePadding && !!ownerState.secondaryAction, - style: { - // Add some space to avoid collision as `ListItemSecondaryAction` - // is absolutely positioned. - paddingRight: 48, + { + props: ({ ownerState }) => !ownerState.disablePadding && !ownerState.disableGutters, + style: { + paddingLeft: 16, + paddingRight: 16, + }, }, - }, - { - props: ({ ownerState }) => !!ownerState.secondaryAction, - style: { - [`& > .${listItemButtonClasses.root}`]: { + { + props: ({ ownerState }) => !ownerState.disablePadding && !!ownerState.secondaryAction, + style: { + // Add some space to avoid collision as `ListItemSecondaryAction` + // is absolutely positioned. paddingRight: 48, }, }, - }, - { - props: { - alignItems: 'flex-start', + { + props: ({ ownerState }) => !!ownerState.secondaryAction, + style: { + [`& > .${listItemButtonClasses.root}`]: { + paddingRight: 48, + }, + }, }, - style: { - alignItems: 'flex-start', + { + props: { + alignItems: 'flex-start', + }, + style: { + alignItems: 'flex-start', + }, }, - }, - { - props: ({ ownerState }) => ownerState.divider, - style: { - borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`, - backgroundClip: 'padding-box', + { + props: ({ ownerState }) => ownerState.divider, + style: { + borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`, + backgroundClip: 'padding-box', + }, }, - }, - { - props: ({ ownerState }) => ownerState.button, - style: { - transition: theme.transitions.create('background-color', { - duration: theme.transitions.duration.shortest, - }), - '&:hover': { - textDecoration: 'none', - backgroundColor: (theme.vars || theme).palette.action.hover, - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: 'transparent', + { + props: ({ ownerState }) => ownerState.button, + style: { + transition: theme.transitions.create('background-color', { + duration: theme.transitions.duration.shortest, + }), + '&:hover': { + textDecoration: 'none', + backgroundColor: (theme.vars || theme).palette.action.hover, + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: 'transparent', + }, }, }, }, - }, - { - props: ({ ownerState }) => ownerState.hasSecondaryAction, - style: { - // Add some space to avoid collision as `ListItemSecondaryAction` - // is absolutely positioned. - paddingRight: 48, + { + props: ({ ownerState }) => ownerState.hasSecondaryAction, + style: { + // Add some space to avoid collision as `ListItemSecondaryAction` + // is absolutely positioned. + paddingRight: 48, + }, }, - }, - ], -})); + ], + })), +); const ListItemContainer = styled('li', { name: 'MuiListItem', diff --git a/packages/mui-material/src/ListItemButton/ListItemButton.js b/packages/mui-material/src/ListItemButton/ListItemButton.js index 7c4f5e54573778..7db261fe0b1a24 100644 --- a/packages/mui-material/src/ListItemButton/ListItemButton.js +++ b/packages/mui-material/src/ListItemButton/ListItemButton.js @@ -5,6 +5,7 @@ import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { alpha } from '@mui/system/colorManipulator'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import rootShouldForwardProp from '../styles/rootShouldForwardProp'; import ButtonBase from '../ButtonBase'; @@ -53,94 +54,96 @@ const ListItemButtonRoot = styled(ButtonBase, { name: 'MuiListItemButton', slot: 'Root', overridesResolver, -})(({ theme }) => ({ - display: 'flex', - flexGrow: 1, - justifyContent: 'flex-start', - alignItems: 'center', - position: 'relative', - textDecoration: 'none', - minWidth: 0, - boxSizing: 'border-box', - textAlign: 'left', - paddingTop: 8, - paddingBottom: 8, - transition: theme.transitions.create('background-color', { - duration: theme.transitions.duration.shortest, - }), - '&:hover': { +})( + memoTheme(({ theme }) => ({ + display: 'flex', + flexGrow: 1, + justifyContent: 'flex-start', + alignItems: 'center', + position: 'relative', textDecoration: 'none', - backgroundColor: (theme.vars || theme).palette.action.hover, - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: 'transparent', + minWidth: 0, + boxSizing: 'border-box', + textAlign: 'left', + paddingTop: 8, + paddingBottom: 8, + transition: theme.transitions.create('background-color', { + duration: theme.transitions.duration.shortest, + }), + '&:hover': { + textDecoration: 'none', + backgroundColor: (theme.vars || theme).palette.action.hover, + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: 'transparent', + }, }, - }, - [`&.${listItemButtonClasses.selected}`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` - : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), - [`&.${listItemButtonClasses.focusVisible}`]: { + [`&.${listItemButtonClasses.selected}`]: { backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))` + ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` + : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), + [`&.${listItemButtonClasses.focusVisible}`]: { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))` + : alpha( + theme.palette.primary.main, + theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity, + ), + }, + }, + [`&.${listItemButtonClasses.selected}:hover`]: { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` : alpha( theme.palette.primary.main, - theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity, + theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, ), + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` + : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), + }, }, - }, - [`&.${listItemButtonClasses.selected}:hover`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` - : alpha( - theme.palette.primary.main, - theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, - ), - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` - : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), + [`&.${listItemButtonClasses.focusVisible}`]: { + backgroundColor: (theme.vars || theme).palette.action.focus, }, - }, - [`&.${listItemButtonClasses.focusVisible}`]: { - backgroundColor: (theme.vars || theme).palette.action.focus, - }, - [`&.${listItemButtonClasses.disabled}`]: { - opacity: (theme.vars || theme).palette.action.disabledOpacity, - }, - variants: [ - { - props: ({ ownerState }) => ownerState.divider, - style: { - borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`, - backgroundClip: 'padding-box', - }, + [`&.${listItemButtonClasses.disabled}`]: { + opacity: (theme.vars || theme).palette.action.disabledOpacity, }, - { - props: { - alignItems: 'flex-start', + variants: [ + { + props: ({ ownerState }) => ownerState.divider, + style: { + borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`, + backgroundClip: 'padding-box', + }, }, - style: { - alignItems: 'flex-start', + { + props: { + alignItems: 'flex-start', + }, + style: { + alignItems: 'flex-start', + }, }, - }, - { - props: ({ ownerState }) => !ownerState.disableGutters, - style: { - paddingLeft: 16, - paddingRight: 16, + { + props: ({ ownerState }) => !ownerState.disableGutters, + style: { + paddingLeft: 16, + paddingRight: 16, + }, }, - }, - { - props: ({ ownerState }) => ownerState.dense, - style: { - paddingTop: 4, - paddingBottom: 4, + { + props: ({ ownerState }) => ownerState.dense, + style: { + paddingTop: 4, + paddingBottom: 4, + }, }, - }, - ], -})); + ], + })), +); const ListItemButton = React.forwardRef(function ListItemButton(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiListItemButton' }); diff --git a/packages/mui-material/src/ListItemIcon/ListItemIcon.js b/packages/mui-material/src/ListItemIcon/ListItemIcon.js index 310259d5e5d81f..00cf8c2a869d7d 100644 --- a/packages/mui-material/src/ListItemIcon/ListItemIcon.js +++ b/packages/mui-material/src/ListItemIcon/ListItemIcon.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import { getListItemIconUtilityClass } from './listItemIconClasses'; import ListContext from '../List/ListContext'; @@ -26,22 +27,24 @@ const ListItemIconRoot = styled('div', { return [styles.root, ownerState.alignItems === 'flex-start' && styles.alignItemsFlexStart]; }, -})(({ theme }) => ({ - minWidth: 56, - color: (theme.vars || theme).palette.action.active, - flexShrink: 0, - display: 'inline-flex', - variants: [ - { - props: { - alignItems: 'flex-start', +})( + memoTheme(({ theme }) => ({ + minWidth: 56, + color: (theme.vars || theme).palette.action.active, + flexShrink: 0, + display: 'inline-flex', + variants: [ + { + props: { + alignItems: 'flex-start', + }, + style: { + marginTop: 8, + }, }, - style: { - marginTop: 8, - }, - }, - ], -})); + ], + })), +); /** * A simple wrapper to apply `List` styles to an `Icon` or `SvgIcon`. diff --git a/packages/mui-material/src/ListSubheader/ListSubheader.js b/packages/mui-material/src/ListSubheader/ListSubheader.js index 279c5e99f31da9..07ee6a50b3fafc 100644 --- a/packages/mui-material/src/ListSubheader/ListSubheader.js +++ b/packages/mui-material/src/ListSubheader/ListSubheader.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import capitalize from '../utils/capitalize'; import { getListSubheaderUtilityClass } from './listSubheaderClasses'; @@ -38,55 +39,57 @@ const ListSubheaderRoot = styled('li', { !ownerState.disableSticky && styles.sticky, ]; }, -})(({ theme }) => ({ - boxSizing: 'border-box', - lineHeight: '48px', - listStyle: 'none', - color: (theme.vars || theme).palette.text.secondary, - fontFamily: theme.typography.fontFamily, - fontWeight: theme.typography.fontWeightMedium, - fontSize: theme.typography.pxToRem(14), - variants: [ - { - props: { - color: 'primary', +})( + memoTheme(({ theme }) => ({ + boxSizing: 'border-box', + lineHeight: '48px', + listStyle: 'none', + color: (theme.vars || theme).palette.text.secondary, + fontFamily: theme.typography.fontFamily, + fontWeight: theme.typography.fontWeightMedium, + fontSize: theme.typography.pxToRem(14), + variants: [ + { + props: { + color: 'primary', + }, + style: { + color: (theme.vars || theme).palette.primary.main, + }, }, - style: { - color: (theme.vars || theme).palette.primary.main, + { + props: { + color: 'inherit', + }, + style: { + color: 'inherit', + }, }, - }, - { - props: { - color: 'inherit', + { + props: ({ ownerState }) => !ownerState.disableGutters, + style: { + paddingLeft: 16, + paddingRight: 16, + }, }, - style: { - color: 'inherit', + { + props: ({ ownerState }) => ownerState.inset, + style: { + paddingLeft: 72, + }, }, - }, - { - props: ({ ownerState }) => !ownerState.disableGutters, - style: { - paddingLeft: 16, - paddingRight: 16, + { + props: ({ ownerState }) => !ownerState.disableSticky, + style: { + position: 'sticky', + top: 0, + zIndex: 1, + backgroundColor: (theme.vars || theme).palette.background.paper, + }, }, - }, - { - props: ({ ownerState }) => ownerState.inset, - style: { - paddingLeft: 72, - }, - }, - { - props: ({ ownerState }) => !ownerState.disableSticky, - style: { - position: 'sticky', - top: 0, - zIndex: 1, - backgroundColor: (theme.vars || theme).palette.background.paper, - }, - }, - ], -})); + ], + })), +); const ListSubheader = React.forwardRef(function ListSubheader(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiListSubheader' }); diff --git a/packages/mui-material/src/MenuItem/MenuItem.js b/packages/mui-material/src/MenuItem/MenuItem.js index eb39af185ff660..8c3f5021265447 100644 --- a/packages/mui-material/src/MenuItem/MenuItem.js +++ b/packages/mui-material/src/MenuItem/MenuItem.js @@ -6,6 +6,7 @@ import composeClasses from '@mui/utils/composeClasses'; import { alpha } from '@mui/system/colorManipulator'; import rootShouldForwardProp from '../styles/rootShouldForwardProp'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import ListContext from '../List/ListContext'; import ButtonBase from '../ButtonBase'; @@ -53,113 +54,115 @@ const MenuItemRoot = styled(ButtonBase, { name: 'MuiMenuItem', slot: 'Root', overridesResolver, -})(({ theme }) => ({ - ...theme.typography.body1, - display: 'flex', - justifyContent: 'flex-start', - alignItems: 'center', - position: 'relative', - textDecoration: 'none', - minHeight: 48, - paddingTop: 6, - paddingBottom: 6, - boxSizing: 'border-box', - whiteSpace: 'nowrap', - '&:hover': { +})( + memoTheme(({ theme }) => ({ + ...theme.typography.body1, + display: 'flex', + justifyContent: 'flex-start', + alignItems: 'center', + position: 'relative', textDecoration: 'none', - backgroundColor: (theme.vars || theme).palette.action.hover, - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: 'transparent', + minHeight: 48, + paddingTop: 6, + paddingBottom: 6, + boxSizing: 'border-box', + whiteSpace: 'nowrap', + '&:hover': { + textDecoration: 'none', + backgroundColor: (theme.vars || theme).palette.action.hover, + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: 'transparent', + }, }, - }, - [`&.${menuItemClasses.selected}`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` - : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), - [`&.${menuItemClasses.focusVisible}`]: { + [`&.${menuItemClasses.selected}`]: { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` + : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), + [`&.${menuItemClasses.focusVisible}`]: { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))` + : alpha( + theme.palette.primary.main, + theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity, + ), + }, + }, + [`&.${menuItemClasses.selected}:hover`]: { backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))` + ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` : alpha( theme.palette.primary.main, - theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity, + theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, ), + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` + : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), + }, }, - }, - [`&.${menuItemClasses.selected}:hover`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` - : alpha( - theme.palette.primary.main, - theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, - ), - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` - : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), + [`&.${menuItemClasses.focusVisible}`]: { + backgroundColor: (theme.vars || theme).palette.action.focus, }, - }, - [`&.${menuItemClasses.focusVisible}`]: { - backgroundColor: (theme.vars || theme).palette.action.focus, - }, - [`&.${menuItemClasses.disabled}`]: { - opacity: (theme.vars || theme).palette.action.disabledOpacity, - }, - [`& + .${dividerClasses.root}`]: { - marginTop: theme.spacing(1), - marginBottom: theme.spacing(1), - }, - [`& + .${dividerClasses.inset}`]: { - marginLeft: 52, - }, - [`& .${listItemTextClasses.root}`]: { - marginTop: 0, - marginBottom: 0, - }, - [`& .${listItemTextClasses.inset}`]: { - paddingLeft: 36, - }, - [`& .${listItemIconClasses.root}`]: { - minWidth: 36, - }, - variants: [ - { - props: ({ ownerState }) => !ownerState.disableGutters, - style: { - paddingLeft: 16, - paddingRight: 16, - }, + [`&.${menuItemClasses.disabled}`]: { + opacity: (theme.vars || theme).palette.action.disabledOpacity, }, - { - props: ({ ownerState }) => ownerState.divider, - style: { - borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`, - backgroundClip: 'padding-box', - }, + [`& + .${dividerClasses.root}`]: { + marginTop: theme.spacing(1), + marginBottom: theme.spacing(1), + }, + [`& + .${dividerClasses.inset}`]: { + marginLeft: 52, + }, + [`& .${listItemTextClasses.root}`]: { + marginTop: 0, + marginBottom: 0, }, - { - props: ({ ownerState }) => !ownerState.dense, - style: { - [theme.breakpoints.up('sm')]: { - minHeight: 'auto', + [`& .${listItemTextClasses.inset}`]: { + paddingLeft: 36, + }, + [`& .${listItemIconClasses.root}`]: { + minWidth: 36, + }, + variants: [ + { + props: ({ ownerState }) => !ownerState.disableGutters, + style: { + paddingLeft: 16, + paddingRight: 16, }, }, - }, - { - props: ({ ownerState }) => ownerState.dense, - style: { - minHeight: 32, // https://m2.material.io/components/menus#specs > Dense - paddingTop: 4, - paddingBottom: 4, - ...theme.typography.body2, - [`& .${listItemIconClasses.root} svg`]: { - fontSize: '1.25rem', + { + props: ({ ownerState }) => ownerState.divider, + style: { + borderBottom: `1px solid ${(theme.vars || theme).palette.divider}`, + backgroundClip: 'padding-box', }, }, - }, - ], -})); + { + props: ({ ownerState }) => !ownerState.dense, + style: { + [theme.breakpoints.up('sm')]: { + minHeight: 'auto', + }, + }, + }, + { + props: ({ ownerState }) => ownerState.dense, + style: { + minHeight: 32, // https://m2.material.io/components/menus#specs > Dense + paddingTop: 4, + paddingBottom: 4, + ...theme.typography.body2, + [`& .${listItemIconClasses.root} svg`]: { + fontSize: '1.25rem', + }, + }, + }, + ], + })), +); const MenuItem = React.forwardRef(function MenuItem(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiMenuItem' }); diff --git a/packages/mui-material/src/MobileStepper/MobileStepper.js b/packages/mui-material/src/MobileStepper/MobileStepper.js index 302863de7e11f5..9a8a4974c14d62 100644 --- a/packages/mui-material/src/MobileStepper/MobileStepper.js +++ b/packages/mui-material/src/MobileStepper/MobileStepper.js @@ -8,6 +8,7 @@ import Paper from '../Paper'; import capitalize from '../utils/capitalize'; import LinearProgress from '../LinearProgress'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import slotShouldForwardProp from '../styles/slotShouldForwardProp'; import { getMobileStepperUtilityClass } from './mobileStepperClasses'; @@ -34,33 +35,35 @@ const MobileStepperRoot = styled(Paper, { return [styles.root, styles[`position${capitalize(ownerState.position)}`]]; }, -})(({ theme }) => ({ - display: 'flex', - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - background: (theme.vars || theme).palette.background.default, - padding: 8, - variants: [ - { - props: ({ position }) => position === 'top' || position === 'bottom', - style: { - position: 'fixed', - left: 0, - right: 0, - zIndex: (theme.vars || theme).zIndex.mobileStepper, +})( + memoTheme(({ theme }) => ({ + display: 'flex', + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + background: (theme.vars || theme).palette.background.default, + padding: 8, + variants: [ + { + props: ({ position }) => position === 'top' || position === 'bottom', + style: { + position: 'fixed', + left: 0, + right: 0, + zIndex: (theme.vars || theme).zIndex.mobileStepper, + }, }, - }, - { - props: { position: 'top' }, - style: { top: 0 }, - }, - { - props: { position: 'bottom' }, - style: { bottom: 0 }, - }, - ], -})); + { + props: { position: 'top' }, + style: { top: 0 }, + }, + { + props: { position: 'bottom' }, + style: { bottom: 0 }, + }, + ], + })), +); const MobileStepperDots = styled('div', { name: 'MuiMobileStepper', @@ -87,29 +90,31 @@ const MobileStepperDot = styled('div', { return [styles.dot, dotActive && styles.dotActive]; }, -})(({ theme }) => ({ - variants: [ - { - props: { variant: 'dots' }, - style: { - transition: theme.transitions.create('background-color', { - duration: theme.transitions.duration.shortest, - }), - backgroundColor: (theme.vars || theme).palette.action.disabled, - borderRadius: '50%', - width: 8, - height: 8, - margin: '0 2px', +})( + memoTheme(({ theme }) => ({ + variants: [ + { + props: { variant: 'dots' }, + style: { + transition: theme.transitions.create('background-color', { + duration: theme.transitions.duration.shortest, + }), + backgroundColor: (theme.vars || theme).palette.action.disabled, + borderRadius: '50%', + width: 8, + height: 8, + margin: '0 2px', + }, }, - }, - { - props: { variant: 'dots', dotActive: true }, - style: { - backgroundColor: (theme.vars || theme).palette.primary.main, + { + props: { variant: 'dots', dotActive: true }, + style: { + backgroundColor: (theme.vars || theme).palette.primary.main, + }, }, - }, - ], -})); + ], + })), +); const MobileStepperProgress = styled(LinearProgress, { name: 'MuiMobileStepper', diff --git a/packages/mui-material/src/Modal/Modal.js b/packages/mui-material/src/Modal/Modal.js index 7818c004b3e5e6..e248fe89e410be 100644 --- a/packages/mui-material/src/Modal/Modal.js +++ b/packages/mui-material/src/Modal/Modal.js @@ -8,6 +8,7 @@ import composeClasses from '@mui/utils/composeClasses'; import FocusTrap from '../Unstable_TrapFocus'; import Portal from '../Portal'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import Backdrop from '../Backdrop'; import useModal from './useModal'; @@ -34,22 +35,24 @@ const ModalRoot = styled('div', { return [styles.root, !ownerState.open && ownerState.exited && styles.hidden]; }, -})(({ theme }) => ({ - position: 'fixed', - zIndex: (theme.vars || theme).zIndex.modal, - right: 0, - bottom: 0, - top: 0, - left: 0, - variants: [ - { - props: ({ ownerState }) => !ownerState.open && ownerState.exited, - style: { - visibility: 'hidden', +})( + memoTheme(({ theme }) => ({ + position: 'fixed', + zIndex: (theme.vars || theme).zIndex.modal, + right: 0, + bottom: 0, + top: 0, + left: 0, + variants: [ + { + props: ({ ownerState }) => !ownerState.open && ownerState.exited, + style: { + visibility: 'hidden', + }, }, - }, - ], -})); + ], + })), +); const ModalBackdrop = styled(Backdrop, { name: 'MuiModal', diff --git a/packages/mui-material/src/OutlinedInput/NotchedOutline.js b/packages/mui-material/src/OutlinedInput/NotchedOutline.js index 46bf41738ea632..0dabd05e27b542 100644 --- a/packages/mui-material/src/OutlinedInput/NotchedOutline.js +++ b/packages/mui-material/src/OutlinedInput/NotchedOutline.js @@ -3,6 +3,7 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import rootShouldForwardProp from '../styles/rootShouldForwardProp'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; const NotchedOutlineRoot = styled('fieldset', { shouldForwardProp: rootShouldForwardProp })({ textAlign: 'left', @@ -22,7 +23,7 @@ const NotchedOutlineRoot = styled('fieldset', { shouldForwardProp: rootShouldFor }); const NotchedOutlineLegend = styled('legend', { shouldForwardProp: rootShouldForwardProp })( - ({ theme }) => ({ + memoTheme(({ theme }) => ({ float: 'unset', // Fix conflict with bootstrap width: 'auto', // Fix conflict with bootstrap overflow: 'hidden', // Fix Horizontal scroll when label too long @@ -73,7 +74,7 @@ const NotchedOutlineLegend = styled('legend', { shouldForwardProp: rootShouldFor }, }, ], - }), + })), ); /** diff --git a/packages/mui-material/src/OutlinedInput/OutlinedInput.js b/packages/mui-material/src/OutlinedInput/OutlinedInput.js index d3812becdfc070..8b16238ccef837 100644 --- a/packages/mui-material/src/OutlinedInput/OutlinedInput.js +++ b/packages/mui-material/src/OutlinedInput/OutlinedInput.js @@ -8,6 +8,7 @@ import useFormControl from '../FormControl/useFormControl'; import formControlState from '../FormControl/formControlState'; import rootShouldForwardProp from '../styles/rootShouldForwardProp'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import outlinedInputClasses, { getOutlinedInputUtilityClass } from './outlinedInputClasses'; import InputBase, { @@ -39,145 +40,151 @@ const OutlinedInputRoot = styled(InputBaseRoot, { name: 'MuiOutlinedInput', slot: 'Root', overridesResolver: inputBaseRootOverridesResolver, -})(({ theme }) => { - const borderColor = - theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)'; - return { - position: 'relative', - borderRadius: (theme.vars || theme).shape.borderRadius, - [`&:hover .${outlinedInputClasses.notchedOutline}`]: { - borderColor: (theme.vars || theme).palette.text.primary, - }, - [`&.${outlinedInputClasses.focused} .${outlinedInputClasses.notchedOutline}`]: { - borderWidth: 2, - }, - variants: [ - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main) - .map(([color]) => ({ - props: { color }, +})( + memoTheme(({ theme }) => { + const borderColor = + theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)'; + return { + position: 'relative', + borderRadius: (theme.vars || theme).shape.borderRadius, + [`&:hover .${outlinedInputClasses.notchedOutline}`]: { + borderColor: (theme.vars || theme).palette.text.primary, + }, + [`&.${outlinedInputClasses.focused} .${outlinedInputClasses.notchedOutline}`]: { + borderWidth: 2, + }, + variants: [ + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main) + .map(([color]) => ({ + props: { color }, + style: { + [`&.${outlinedInputClasses.focused} .${outlinedInputClasses.notchedOutline}`]: { + borderColor: (theme.vars || theme).palette[color].main, + }, + }, + })), + { + props: {}, // to overide the above style style: { - [`&.${outlinedInputClasses.focused} .${outlinedInputClasses.notchedOutline}`]: { - borderColor: (theme.vars || theme).palette[color].main, + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + [`&:hover .${outlinedInputClasses.notchedOutline}`]: { + borderColor: theme.vars + ? `rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.23)` + : borderColor, + }, }, - }, - })), - { - props: {}, // to overide the above style - style: { - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - [`&:hover .${outlinedInputClasses.notchedOutline}`]: { - borderColor: theme.vars - ? `rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.23)` - : borderColor, + [`&.${outlinedInputClasses.error} .${outlinedInputClasses.notchedOutline}`]: { + borderColor: (theme.vars || theme).palette.error.main, + }, + [`&.${outlinedInputClasses.disabled} .${outlinedInputClasses.notchedOutline}`]: { + borderColor: (theme.vars || theme).palette.action.disabled, }, - }, - [`&.${outlinedInputClasses.error} .${outlinedInputClasses.notchedOutline}`]: { - borderColor: (theme.vars || theme).palette.error.main, - }, - [`&.${outlinedInputClasses.disabled} .${outlinedInputClasses.notchedOutline}`]: { - borderColor: (theme.vars || theme).palette.action.disabled, }, }, - }, - { - props: ({ ownerState }) => ownerState.startAdornment, - style: { - paddingLeft: 14, + { + props: ({ ownerState }) => ownerState.startAdornment, + style: { + paddingLeft: 14, + }, }, - }, - { - props: ({ ownerState }) => ownerState.endAdornment, - style: { - paddingRight: 14, + { + props: ({ ownerState }) => ownerState.endAdornment, + style: { + paddingRight: 14, + }, }, - }, - { - props: ({ ownerState }) => ownerState.multiline, - style: { - padding: '16.5px 14px', + { + props: ({ ownerState }) => ownerState.multiline, + style: { + padding: '16.5px 14px', + }, }, - }, - { - props: ({ ownerState, size }) => ownerState.multiline && size === 'small', - style: { - padding: '8.5px 14px', + { + props: ({ ownerState, size }) => ownerState.multiline && size === 'small', + style: { + padding: '8.5px 14px', + }, }, - }, - ], - }; -}); + ], + }; + }), +); const NotchedOutlineRoot = styled(NotchedOutline, { name: 'MuiOutlinedInput', slot: 'NotchedOutline', overridesResolver: (props, styles) => styles.notchedOutline, -})(({ theme }) => { - const borderColor = - theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)'; - return { - borderColor: theme.vars - ? `rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.23)` - : borderColor, - }; -}); +})( + memoTheme(({ theme }) => { + const borderColor = + theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)'; + return { + borderColor: theme.vars + ? `rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.23)` + : borderColor, + }; + }), +); const OutlinedInputInput = styled(InputBaseInput, { name: 'MuiOutlinedInput', slot: 'Input', overridesResolver: inputBaseInputOverridesResolver, -})(({ theme }) => ({ - padding: '16.5px 14px', - ...(!theme.vars && { - '&:-webkit-autofill': { - WebkitBoxShadow: theme.palette.mode === 'light' ? null : '0 0 0 100px #266798 inset', - WebkitTextFillColor: theme.palette.mode === 'light' ? null : '#fff', - caretColor: theme.palette.mode === 'light' ? null : '#fff', - borderRadius: 'inherit', - }, - }), - ...(theme.vars && { - '&:-webkit-autofill': { - borderRadius: 'inherit', - }, - [theme.getColorSchemeSelector('dark')]: { +})( + memoTheme(({ theme }) => ({ + padding: '16.5px 14px', + ...(!theme.vars && { '&:-webkit-autofill': { - WebkitBoxShadow: '0 0 0 100px #266798 inset', - WebkitTextFillColor: '#fff', - caretColor: '#fff', + WebkitBoxShadow: theme.palette.mode === 'light' ? null : '0 0 0 100px #266798 inset', + WebkitTextFillColor: theme.palette.mode === 'light' ? null : '#fff', + caretColor: theme.palette.mode === 'light' ? null : '#fff', + borderRadius: 'inherit', }, - }, - }), - variants: [ - { - props: { - size: 'small', + }), + ...(theme.vars && { + '&:-webkit-autofill': { + borderRadius: 'inherit', }, - style: { - padding: '8.5px 14px', + [theme.getColorSchemeSelector('dark')]: { + '&:-webkit-autofill': { + WebkitBoxShadow: '0 0 0 100px #266798 inset', + WebkitTextFillColor: '#fff', + caretColor: '#fff', + }, + }, + }), + variants: [ + { + props: { + size: 'small', + }, + style: { + padding: '8.5px 14px', + }, }, - }, - { - props: ({ ownerState }) => ownerState.multiline, - style: { - padding: 0, + { + props: ({ ownerState }) => ownerState.multiline, + style: { + padding: 0, + }, }, - }, - { - props: ({ ownerState }) => ownerState.startAdornment, - style: { - paddingLeft: 0, + { + props: ({ ownerState }) => ownerState.startAdornment, + style: { + paddingLeft: 0, + }, }, - }, - { - props: ({ ownerState }) => ownerState.endAdornment, - style: { - paddingRight: 0, + { + props: ({ ownerState }) => ownerState.endAdornment, + style: { + paddingRight: 0, + }, }, - }, - ], -})); + ], + })), +); const OutlinedInput = React.forwardRef(function OutlinedInput(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiOutlinedInput' }); diff --git a/packages/mui-material/src/PaginationItem/PaginationItem.js b/packages/mui-material/src/PaginationItem/PaginationItem.js index 0a5aca797d497a..29b696cde6dcb2 100644 --- a/packages/mui-material/src/PaginationItem/PaginationItem.js +++ b/packages/mui-material/src/PaginationItem/PaginationItem.js @@ -14,6 +14,7 @@ import NavigateBeforeIcon from '../internal/svg-icons/NavigateBefore'; import NavigateNextIcon from '../internal/svg-icons/NavigateNext'; import useSlot from '../utils/useSlot'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; @@ -67,239 +68,245 @@ const PaginationItemEllipsis = styled('div', { name: 'MuiPaginationItem', slot: 'Root', overridesResolver, -})(({ theme }) => ({ - ...theme.typography.body2, - borderRadius: 32 / 2, - textAlign: 'center', - boxSizing: 'border-box', - minWidth: 32, - padding: '0 6px', - margin: '0 3px', - color: (theme.vars || theme).palette.text.primary, - height: 'auto', - [`&.${paginationItemClasses.disabled}`]: { - opacity: (theme.vars || theme).palette.action.disabledOpacity, - }, - variants: [ - { - props: { size: 'small' }, - style: { - minWidth: 26, - borderRadius: 26 / 2, - margin: '0 1px', - padding: '0 4px', - }, +})( + memoTheme(({ theme }) => ({ + ...theme.typography.body2, + borderRadius: 32 / 2, + textAlign: 'center', + boxSizing: 'border-box', + minWidth: 32, + padding: '0 6px', + margin: '0 3px', + color: (theme.vars || theme).palette.text.primary, + height: 'auto', + [`&.${paginationItemClasses.disabled}`]: { + opacity: (theme.vars || theme).palette.action.disabledOpacity, }, - { - props: { size: 'large' }, - style: { - minWidth: 40, - borderRadius: 40 / 2, - padding: '0 10px', - fontSize: theme.typography.pxToRem(15), + variants: [ + { + props: { size: 'small' }, + style: { + minWidth: 26, + borderRadius: 26 / 2, + margin: '0 1px', + padding: '0 4px', + }, }, - }, - ], -})); + { + props: { size: 'large' }, + style: { + minWidth: 40, + borderRadius: 40 / 2, + padding: '0 10px', + fontSize: theme.typography.pxToRem(15), + }, + }, + ], + })), +); const PaginationItemPage = styled(ButtonBase, { name: 'MuiPaginationItem', slot: 'Root', overridesResolver, -})(({ theme }) => ({ - ...theme.typography.body2, - borderRadius: 32 / 2, - textAlign: 'center', - boxSizing: 'border-box', - minWidth: 32, - height: 32, - padding: '0 6px', - margin: '0 3px', - color: (theme.vars || theme).palette.text.primary, - [`&.${paginationItemClasses.focusVisible}`]: { - backgroundColor: (theme.vars || theme).palette.action.focus, - }, - [`&.${paginationItemClasses.disabled}`]: { - opacity: (theme.vars || theme).palette.action.disabledOpacity, - }, - transition: theme.transitions.create(['color', 'background-color'], { - duration: theme.transitions.duration.short, - }), - '&:hover': { - backgroundColor: (theme.vars || theme).palette.action.hover, - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: 'transparent', +})( + memoTheme(({ theme }) => ({ + ...theme.typography.body2, + borderRadius: 32 / 2, + textAlign: 'center', + boxSizing: 'border-box', + minWidth: 32, + height: 32, + padding: '0 6px', + margin: '0 3px', + color: (theme.vars || theme).palette.text.primary, + [`&.${paginationItemClasses.focusVisible}`]: { + backgroundColor: (theme.vars || theme).palette.action.focus, }, - }, - [`&.${paginationItemClasses.selected}`]: { - backgroundColor: (theme.vars || theme).palette.action.selected, + [`&.${paginationItemClasses.disabled}`]: { + opacity: (theme.vars || theme).palette.action.disabledOpacity, + }, + transition: theme.transitions.create(['color', 'background-color'], { + duration: theme.transitions.duration.short, + }), '&:hover': { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.action.selectedChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` - : alpha( - theme.palette.action.selected, - theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, - ), + backgroundColor: (theme.vars || theme).palette.action.hover, // Reset on touch devices, it doesn't add specificity '@media (hover: none)': { - backgroundColor: (theme.vars || theme).palette.action.selected, + backgroundColor: 'transparent', }, }, - [`&.${paginationItemClasses.focusVisible}`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.action.selectedChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))` - : alpha( - theme.palette.action.selected, - theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity, - ), - }, - [`&.${paginationItemClasses.disabled}`]: { - opacity: 1, - color: (theme.vars || theme).palette.action.disabled, + [`&.${paginationItemClasses.selected}`]: { backgroundColor: (theme.vars || theme).palette.action.selected, - }, - }, - variants: [ - { - props: { size: 'small' }, - style: { - minWidth: 26, - height: 26, - borderRadius: 26 / 2, - margin: '0 1px', - padding: '0 4px', + '&:hover': { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.action.selectedChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` + : alpha( + theme.palette.action.selected, + theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, + ), + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: (theme.vars || theme).palette.action.selected, + }, }, - }, - { - props: { size: 'large' }, - style: { - minWidth: 40, - height: 40, - borderRadius: 40 / 2, - padding: '0 10px', - fontSize: theme.typography.pxToRem(15), + [`&.${paginationItemClasses.focusVisible}`]: { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.action.selectedChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.focusOpacity}))` + : alpha( + theme.palette.action.selected, + theme.palette.action.selectedOpacity + theme.palette.action.focusOpacity, + ), }, - }, - { - props: { shape: 'rounded' }, - style: { - borderRadius: (theme.vars || theme).shape.borderRadius, + [`&.${paginationItemClasses.disabled}`]: { + opacity: 1, + color: (theme.vars || theme).palette.action.disabled, + backgroundColor: (theme.vars || theme).palette.action.selected, }, }, - { - props: { variant: 'outlined' }, - style: { - border: theme.vars - ? `1px solid rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.23)` - : `1px solid ${ - theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)' - }`, - [`&.${paginationItemClasses.selected}`]: { - [`&.${paginationItemClasses.disabled}`]: { - borderColor: (theme.vars || theme).palette.action.disabledBackground, - color: (theme.vars || theme).palette.action.disabled, - }, + variants: [ + { + props: { size: 'small' }, + style: { + minWidth: 26, + height: 26, + borderRadius: 26 / 2, + margin: '0 1px', + padding: '0 4px', }, }, - }, - { - props: { variant: 'text' }, - style: { - [`&.${paginationItemClasses.selected}`]: { - [`&.${paginationItemClasses.disabled}`]: { - color: (theme.vars || theme).palette.action.disabled, - }, + { + props: { size: 'large' }, + style: { + minWidth: 40, + height: 40, + borderRadius: 40 / 2, + padding: '0 10px', + fontSize: theme.typography.pxToRem(15), }, }, - }, - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main && value.dark && value.contrastText) - .map(([color]) => ({ - props: { variant: 'text', color }, + { + props: { shape: 'rounded' }, style: { + borderRadius: (theme.vars || theme).shape.borderRadius, + }, + }, + { + props: { variant: 'outlined' }, + style: { + border: theme.vars + ? `1px solid rgba(${theme.vars.palette.common.onBackgroundChannel} / 0.23)` + : `1px solid ${ + theme.palette.mode === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)' + }`, [`&.${paginationItemClasses.selected}`]: { - color: (theme.vars || theme).palette[color].contrastText, - backgroundColor: (theme.vars || theme).palette[color].main, - '&:hover': { - backgroundColor: (theme.vars || theme).palette[color].dark, - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: (theme.vars || theme).palette[color].main, - }, - }, - [`&.${paginationItemClasses.focusVisible}`]: { - backgroundColor: (theme.vars || theme).palette[color].dark, - }, [`&.${paginationItemClasses.disabled}`]: { + borderColor: (theme.vars || theme).palette.action.disabledBackground, color: (theme.vars || theme).palette.action.disabled, }, }, }, - })), - ...Object.entries(theme.palette) - .filter(([, value]) => value && value.main && value.light) - .map(([color]) => ({ - props: { variant: 'outlined', color }, + }, + { + props: { variant: 'text' }, style: { [`&.${paginationItemClasses.selected}`]: { - color: (theme.vars || theme).palette[color].main, - border: `1px solid ${ - theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / 0.5)` - : alpha(theme.palette[color].main, 0.5) - }`, - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.activatedOpacity})` - : alpha(theme.palette[color].main, theme.palette.action.activatedOpacity), - '&:hover': { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / calc(${theme.vars.palette.action.activatedOpacity} + ${theme.vars.palette.action.focusOpacity}))` - : alpha( - theme.palette[color].main, - theme.palette.action.activatedOpacity + theme.palette.action.focusOpacity, - ), - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: 'transparent', + [`&.${paginationItemClasses.disabled}`]: { + color: (theme.vars || theme).palette.action.disabled, + }, + }, + }, + }, + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main && value.dark && value.contrastText) + .map(([color]) => ({ + props: { variant: 'text', color }, + style: { + [`&.${paginationItemClasses.selected}`]: { + color: (theme.vars || theme).palette[color].contrastText, + backgroundColor: (theme.vars || theme).palette[color].main, + '&:hover': { + backgroundColor: (theme.vars || theme).palette[color].dark, + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: (theme.vars || theme).palette[color].main, + }, + }, + [`&.${paginationItemClasses.focusVisible}`]: { + backgroundColor: (theme.vars || theme).palette[color].dark, + }, + [`&.${paginationItemClasses.disabled}`]: { + color: (theme.vars || theme).palette.action.disabled, }, }, - [`&.${paginationItemClasses.focusVisible}`]: { + }, + })), + ...Object.entries(theme.palette) + .filter(([, value]) => value && value.main && value.light) + .map(([color]) => ({ + props: { variant: 'outlined', color }, + style: { + [`&.${paginationItemClasses.selected}`]: { + color: (theme.vars || theme).palette[color].main, + border: `1px solid ${ + theme.vars + ? `rgba(${theme.vars.palette[color].mainChannel} / 0.5)` + : alpha(theme.palette[color].main, 0.5) + }`, backgroundColor: theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / calc(${theme.vars.palette.action.activatedOpacity} + ${theme.vars.palette.action.focusOpacity}))` - : alpha( - theme.palette[color].main, - theme.palette.action.activatedOpacity + theme.palette.action.focusOpacity, - ), + ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.activatedOpacity})` + : alpha(theme.palette[color].main, theme.palette.action.activatedOpacity), + '&:hover': { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette[color].mainChannel} / calc(${theme.vars.palette.action.activatedOpacity} + ${theme.vars.palette.action.focusOpacity}))` + : alpha( + theme.palette[color].main, + theme.palette.action.activatedOpacity + theme.palette.action.focusOpacity, + ), + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: 'transparent', + }, + }, + [`&.${paginationItemClasses.focusVisible}`]: { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette[color].mainChannel} / calc(${theme.vars.palette.action.activatedOpacity} + ${theme.vars.palette.action.focusOpacity}))` + : alpha( + theme.palette[color].main, + theme.palette.action.activatedOpacity + theme.palette.action.focusOpacity, + ), + }, }, }, - }, - })), - ], -})); + })), + ], + })), +); const PaginationItemPageIcon = styled('div', { name: 'MuiPaginationItem', slot: 'Icon', overridesResolver: (props, styles) => styles.icon, -})(({ theme }) => ({ - fontSize: theme.typography.pxToRem(20), - margin: '0 -8px', - variants: [ - { - props: { size: 'small' }, - style: { - fontSize: theme.typography.pxToRem(18), +})( + memoTheme(({ theme }) => ({ + fontSize: theme.typography.pxToRem(20), + margin: '0 -8px', + variants: [ + { + props: { size: 'small' }, + style: { + fontSize: theme.typography.pxToRem(18), + }, }, - }, - { - props: { size: 'large' }, - style: { - fontSize: theme.typography.pxToRem(22), + { + props: { size: 'large' }, + style: { + fontSize: theme.typography.pxToRem(22), + }, }, - }, - ], -})); + ], + })), +); const PaginationItem = React.forwardRef(function PaginationItem(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiPaginationItem' }); diff --git a/packages/mui-material/src/Paper/Paper.js b/packages/mui-material/src/Paper/Paper.js index 3b42dce0db18dd..9ae2f32861649e 100644 --- a/packages/mui-material/src/Paper/Paper.js +++ b/packages/mui-material/src/Paper/Paper.js @@ -7,6 +7,7 @@ import chainPropTypes from '@mui/utils/chainPropTypes'; import composeClasses from '@mui/utils/composeClasses'; import { alpha } from '@mui/system/colorManipulator'; import { styled, useTheme } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import getOverlayAlpha from '../styles/getOverlayAlpha'; import { getPaperUtilityClass } from './paperClasses'; @@ -39,36 +40,38 @@ const PaperRoot = styled('div', { ownerState.variant === 'elevation' && styles[`elevation${ownerState.elevation}`], ]; }, -})(({ theme }) => ({ - backgroundColor: (theme.vars || theme).palette.background.paper, - color: (theme.vars || theme).palette.text.primary, - transition: theme.transitions.create('box-shadow'), - variants: [ - { - props: ({ ownerState }) => !ownerState.square, - style: { - borderRadius: theme.shape.borderRadius, +})( + memoTheme(({ theme }) => ({ + backgroundColor: (theme.vars || theme).palette.background.paper, + color: (theme.vars || theme).palette.text.primary, + transition: theme.transitions.create('box-shadow'), + variants: [ + { + props: ({ ownerState }) => !ownerState.square, + style: { + borderRadius: theme.shape.borderRadius, + }, }, - }, - { - props: { - variant: 'outlined', + { + props: { + variant: 'outlined', + }, + style: { + border: `1px solid ${(theme.vars || theme).palette.divider}`, + }, }, - style: { - border: `1px solid ${(theme.vars || theme).palette.divider}`, + { + props: { + variant: 'elevation', + }, + style: { + boxShadow: 'var(--Paper-shadow)', + backgroundImage: 'var(--Paper-overlay)', + }, }, - }, - { - props: { - variant: 'elevation', - }, - style: { - boxShadow: 'var(--Paper-shadow)', - backgroundImage: 'var(--Paper-overlay)', - }, - }, - ], -})); + ], + })), +); const Paper = React.forwardRef(function Paper(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiPaper' }); diff --git a/packages/mui-material/src/Radio/Radio.js b/packages/mui-material/src/Radio/Radio.js index d3b81667586245..40e47b90100cc1 100644 --- a/packages/mui-material/src/Radio/Radio.js +++ b/packages/mui-material/src/Radio/Radio.js @@ -13,6 +13,7 @@ import useRadioGroup from '../RadioGroup/useRadioGroup'; import radioClasses, { getRadioUtilityClass } from './radioClasses'; import rootShouldForwardProp from '../styles/rootShouldForwardProp'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; @@ -42,58 +43,60 @@ const RadioRoot = styled(SwitchBase, { styles[`color${capitalize(ownerState.color)}`], ]; }, -})(({ theme }) => ({ - color: (theme.vars || theme).palette.text.secondary, - [`&.${radioClasses.disabled}`]: { - color: (theme.vars || theme).palette.action.disabled, - }, - variants: [ - { - props: { color: 'default', disableRipple: false }, - style: { - '&:hover': { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.action.activeChannel} / ${theme.vars.palette.action.hoverOpacity})` - : alpha(theme.palette.action.active, theme.palette.action.hoverOpacity), - }, - }, +})( + memoTheme(({ theme }) => ({ + color: (theme.vars || theme).palette.text.secondary, + [`&.${radioClasses.disabled}`]: { + color: (theme.vars || theme).palette.action.disabled, }, - ...Object.entries(theme.palette) - .filter(([, palette]) => palette && palette.main) - .map(([color]) => ({ - props: { color, disableRipple: false }, + variants: [ + { + props: { color: 'default', disableRipple: false }, style: { '&:hover': { backgroundColor: theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.hoverOpacity})` - : alpha(theme.palette[color].main, theme.palette.action.hoverOpacity), + ? `rgba(${theme.vars.palette.action.activeChannel} / ${theme.vars.palette.action.hoverOpacity})` + : alpha(theme.palette.action.active, theme.palette.action.hoverOpacity), }, }, - })), - ...Object.entries(theme.palette) - .filter(([, palette]) => palette && palette.main) - .map(([color]) => ({ - props: { color }, - style: { - [`&.${radioClasses.checked}`]: { - color: (theme.vars || theme).palette[color].main, + }, + ...Object.entries(theme.palette) + .filter(([, palette]) => palette && palette.main) + .map(([color]) => ({ + props: { color, disableRipple: false }, + style: { + '&:hover': { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.hoverOpacity})` + : alpha(theme.palette[color].main, theme.palette.action.hoverOpacity), + }, }, - }, - })), - { - // Should be last to override other colors - props: { disableRipple: false }, - style: { - // Reset on touch devices, it doesn't add specificity - '&:hover': { - '@media (hover: none)': { - backgroundColor: 'transparent', + })), + ...Object.entries(theme.palette) + .filter(([, palette]) => palette && palette.main) + .map(([color]) => ({ + props: { color }, + style: { + [`&.${radioClasses.checked}`]: { + color: (theme.vars || theme).palette[color].main, + }, + }, + })), + { + // Should be last to override other colors + props: { disableRipple: false }, + style: { + // Reset on touch devices, it doesn't add specificity + '&:hover': { + '@media (hover: none)': { + backgroundColor: 'transparent', + }, }, }, }, - }, - ], -})); + ], + })), +); function areEqualValues(a, b) { if (typeof b === 'object' && b !== null) { diff --git a/packages/mui-material/src/Radio/RadioButtonIcon.js b/packages/mui-material/src/Radio/RadioButtonIcon.js index 7db83617bf8e97..ac9cb9892a4c3e 100644 --- a/packages/mui-material/src/Radio/RadioButtonIcon.js +++ b/packages/mui-material/src/Radio/RadioButtonIcon.js @@ -5,6 +5,7 @@ import RadioButtonUncheckedIcon from '../internal/svg-icons/RadioButtonUnchecked import RadioButtonCheckedIcon from '../internal/svg-icons/RadioButtonChecked'; import rootShouldForwardProp from '../styles/rootShouldForwardProp'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; const RadioButtonIconRoot = styled('span', { shouldForwardProp: rootShouldForwardProp })({ position: 'relative', @@ -16,27 +17,29 @@ const RadioButtonIconBackground = styled(RadioButtonUncheckedIcon)({ transform: 'scale(1)', }); -const RadioButtonIconDot = styled(RadioButtonCheckedIcon)(({ theme }) => ({ - left: 0, - position: 'absolute', - transform: 'scale(0)', - transition: theme.transitions.create('transform', { - easing: theme.transitions.easing.easeIn, - duration: theme.transitions.duration.shortest, - }), - variants: [ - { - props: { checked: true }, - style: { - transform: 'scale(1)', - transition: theme.transitions.create('transform', { - easing: theme.transitions.easing.easeOut, - duration: theme.transitions.duration.shortest, - }), +const RadioButtonIconDot = styled(RadioButtonCheckedIcon)( + memoTheme(({ theme }) => ({ + left: 0, + position: 'absolute', + transform: 'scale(0)', + transition: theme.transitions.create('transform', { + easing: theme.transitions.easing.easeIn, + duration: theme.transitions.duration.shortest, + }), + variants: [ + { + props: { checked: true }, + style: { + transform: 'scale(1)', + transition: theme.transitions.create('transform', { + easing: theme.transitions.easing.easeOut, + duration: theme.transitions.duration.shortest, + }), + }, }, - }, - ], -})); + ], + })), +); /** * @ignore - internal component. diff --git a/packages/mui-material/src/Rating/Rating.js b/packages/mui-material/src/Rating/Rating.js index dde4f099e9fa0b..04d81d5f585b66 100644 --- a/packages/mui-material/src/Rating/Rating.js +++ b/packages/mui-material/src/Rating/Rating.js @@ -12,6 +12,7 @@ import { capitalize, useForkRef, useControlled, unstable_useId as useId } from ' import Star from '../internal/svg-icons/Star'; import StarBorder from '../internal/svg-icons/StarBorder'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import slotShouldForwardProp from '../styles/slotShouldForwardProp'; import ratingClasses, { getRatingUtilityClass } from './ratingClasses'; @@ -69,50 +70,52 @@ const RatingRoot = styled('span', { ownerState.readOnly && styles.readOnly, ]; }, -})(({ theme }) => ({ - display: 'inline-flex', - // Required to position the pristine input absolutely - position: 'relative', - fontSize: theme.typography.pxToRem(24), - color: '#faaf00', - cursor: 'pointer', - textAlign: 'left', - width: 'min-content', - WebkitTapHighlightColor: 'transparent', - [`&.${ratingClasses.disabled}`]: { - opacity: (theme.vars || theme).palette.action.disabledOpacity, - pointerEvents: 'none', - }, - [`&.${ratingClasses.focusVisible} .${ratingClasses.iconActive}`]: { - outline: '1px solid #999', - }, - [`& .${ratingClasses.visuallyHidden}`]: visuallyHidden, - variants: [ - { - props: { - size: 'small', - }, - style: { - fontSize: theme.typography.pxToRem(18), - }, +})( + memoTheme(({ theme }) => ({ + display: 'inline-flex', + // Required to position the pristine input absolutely + position: 'relative', + fontSize: theme.typography.pxToRem(24), + color: '#faaf00', + cursor: 'pointer', + textAlign: 'left', + width: 'min-content', + WebkitTapHighlightColor: 'transparent', + [`&.${ratingClasses.disabled}`]: { + opacity: (theme.vars || theme).palette.action.disabledOpacity, + pointerEvents: 'none', }, - { - props: { - size: 'large', + [`&.${ratingClasses.focusVisible} .${ratingClasses.iconActive}`]: { + outline: '1px solid #999', + }, + [`& .${ratingClasses.visuallyHidden}`]: visuallyHidden, + variants: [ + { + props: { + size: 'small', + }, + style: { + fontSize: theme.typography.pxToRem(18), + }, }, - style: { - fontSize: theme.typography.pxToRem(30), + { + props: { + size: 'large', + }, + style: { + fontSize: theme.typography.pxToRem(30), + }, }, - }, - { - // TODO v6: use the .Mui-readOnly global state class - props: ({ ownerState }) => ownerState.readOnly, - style: { - pointerEvents: 'none', + { + // TODO v6: use the .Mui-readOnly global state class + props: ({ ownerState }) => ownerState.readOnly, + style: { + pointerEvents: 'none', + }, }, - }, - ], -})); + ], + })), +); const RatingLabel = styled('label', { name: 'MuiRating', @@ -152,30 +155,32 @@ const RatingIcon = styled('span', { ownerState.iconActive && styles.iconActive, ]; }, -})(({ theme }) => ({ - // Fit wrapper to actual icon size. - display: 'flex', - transition: theme.transitions.create('transform', { - duration: theme.transitions.duration.shortest, - }), - // Fix mouseLeave issue. - // https://github.com/facebook/react/issues/4492 - pointerEvents: 'none', - variants: [ - { - props: ({ ownerState }) => ownerState.iconActive, - style: { - transform: 'scale(1.2)', +})( + memoTheme(({ theme }) => ({ + // Fit wrapper to actual icon size. + display: 'flex', + transition: theme.transitions.create('transform', { + duration: theme.transitions.duration.shortest, + }), + // Fix mouseLeave issue. + // https://github.com/facebook/react/issues/4492 + pointerEvents: 'none', + variants: [ + { + props: ({ ownerState }) => ownerState.iconActive, + style: { + transform: 'scale(1.2)', + }, }, - }, - { - props: ({ ownerState }) => ownerState.iconEmpty, - style: { - color: (theme.vars || theme).palette.action.disabled, + { + props: ({ ownerState }) => ownerState.iconEmpty, + style: { + color: (theme.vars || theme).palette.action.disabled, + }, }, - }, - ], -})); + ], + })), +); const RatingDecimal = styled('span', { name: 'MuiRating', diff --git a/packages/mui-material/src/ScopedCssBaseline/ScopedCssBaseline.js b/packages/mui-material/src/ScopedCssBaseline/ScopedCssBaseline.js index dc550061daf163..cccb5493ba0515 100644 --- a/packages/mui-material/src/ScopedCssBaseline/ScopedCssBaseline.js +++ b/packages/mui-material/src/ScopedCssBaseline/ScopedCssBaseline.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import { html, body } from '../CssBaseline/CssBaseline'; import { getScopedCssBaselineUtilityClass } from './scopedCssBaselineClasses'; @@ -22,39 +23,41 @@ const ScopedCssBaselineRoot = styled('div', { name: 'MuiScopedCssBaseline', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})(({ theme }) => { - const colorSchemeStyles = {}; - if (theme.colorSchemes) { - Object.entries(theme.colorSchemes).forEach(([key, scheme]) => { - const selector = theme.getColorSchemeSelector(key); - if (selector.startsWith('@')) { - colorSchemeStyles[selector] = { - colorScheme: scheme.palette?.mode, - }; - } else { - colorSchemeStyles[`&${selector.replace(/\s*&/, '')}`] = { - colorScheme: scheme.palette?.mode, - }; - } - }); - } - return { - ...html(theme, false), - ...body(theme), - '& *, & *::before, & *::after': { - boxSizing: 'inherit', - }, - '& strong, & b': { - fontWeight: theme.typography.fontWeightBold, - }, - variants: [ - { - props: { enableColorScheme: true }, - style: theme.vars ? colorSchemeStyles : { colorScheme: theme.palette.mode }, +})( + memoTheme(({ theme }) => { + const colorSchemeStyles = {}; + if (theme.colorSchemes) { + Object.entries(theme.colorSchemes).forEach(([key, scheme]) => { + const selector = theme.getColorSchemeSelector(key); + if (selector.startsWith('@')) { + colorSchemeStyles[selector] = { + colorScheme: scheme.palette?.mode, + }; + } else { + colorSchemeStyles[`&${selector.replace(/\s*&/, '')}`] = { + colorScheme: scheme.palette?.mode, + }; + } + }); + } + return { + ...html(theme, false), + ...body(theme), + '& *, & *::before, & *::after': { + boxSizing: 'inherit', }, - ], - }; -}); + '& strong, & b': { + fontWeight: theme.typography.fontWeightBold, + }, + variants: [ + { + props: { enableColorScheme: true }, + style: theme.vars ? colorSchemeStyles : { colorScheme: theme.palette.mode }, + }, + ], + }; + }), +); const ScopedCssBaseline = React.forwardRef(function ScopedCssBaseline(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiScopedCssBaseline' }); diff --git a/packages/mui-material/src/Skeleton/Skeleton.js b/packages/mui-material/src/Skeleton/Skeleton.js index 9321d08c2afbda..e172a81bd3f890 100644 --- a/packages/mui-material/src/Skeleton/Skeleton.js +++ b/packages/mui-material/src/Skeleton/Skeleton.js @@ -5,6 +5,7 @@ import PropTypes from 'prop-types'; import composeClasses from '@mui/utils/composeClasses'; import { alpha, unstable_getUnit as getUnit, unstable_toUnitless as toUnitless } from '../styles'; import { keyframes, css, styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import { getSkeletonUtilityClass } from './skeletonClasses'; @@ -86,117 +87,119 @@ const SkeletonRoot = styled('span', { ownerState.hasChildren && !ownerState.height && styles.heightAuto, ]; }, -})(({ theme }) => { - const radiusUnit = getUnit(theme.shape.borderRadius) || 'px'; - const radiusValue = toUnitless(theme.shape.borderRadius); +})( + memoTheme(({ theme }) => { + const radiusUnit = getUnit(theme.shape.borderRadius) || 'px'; + const radiusValue = toUnitless(theme.shape.borderRadius); - return { - display: 'block', - // Create a "on paper" color with sufficient contrast retaining the color - backgroundColor: theme.vars - ? theme.vars.palette.Skeleton.bg - : alpha(theme.palette.text.primary, theme.palette.mode === 'light' ? 0.11 : 0.13), - height: '1.2em', - variants: [ - { - props: { - variant: 'text', - }, - style: { - marginTop: 0, - marginBottom: 0, - height: 'auto', - transformOrigin: '0 55%', - transform: 'scale(1, 0.60)', - borderRadius: `${radiusValue}${radiusUnit}/${Math.round((radiusValue / 0.6) * 10) / 10}${ - radiusUnit - }`, - '&:empty:before': { - content: '"\\00a0"', + return { + display: 'block', + // Create a "on paper" color with sufficient contrast retaining the color + backgroundColor: theme.vars + ? theme.vars.palette.Skeleton.bg + : alpha(theme.palette.text.primary, theme.palette.mode === 'light' ? 0.11 : 0.13), + height: '1.2em', + variants: [ + { + props: { + variant: 'text', + }, + style: { + marginTop: 0, + marginBottom: 0, + height: 'auto', + transformOrigin: '0 55%', + transform: 'scale(1, 0.60)', + borderRadius: `${radiusValue}${radiusUnit}/${Math.round((radiusValue / 0.6) * 10) / 10}${ + radiusUnit + }`, + '&:empty:before': { + content: '"\\00a0"', + }, }, }, - }, - { - props: { - variant: 'circular', - }, - style: { - borderRadius: '50%', - }, - }, - { - props: { - variant: 'rounded', - }, - style: { - borderRadius: (theme.vars || theme).shape.borderRadius, - }, - }, - { - props: ({ ownerState }) => ownerState.hasChildren, - style: { - '& > *': { - visibility: 'hidden', + { + props: { + variant: 'circular', + }, + style: { + borderRadius: '50%', }, }, - }, - { - props: ({ ownerState }) => ownerState.hasChildren && !ownerState.width, - style: { - maxWidth: 'fit-content', + { + props: { + variant: 'rounded', + }, + style: { + borderRadius: (theme.vars || theme).shape.borderRadius, + }, }, - }, - { - props: ({ ownerState }) => ownerState.hasChildren && !ownerState.height, - style: { - height: 'auto', + { + props: ({ ownerState }) => ownerState.hasChildren, + style: { + '& > *': { + visibility: 'hidden', + }, + }, }, - }, - { - props: { - animation: 'pulse', + { + props: ({ ownerState }) => ownerState.hasChildren && !ownerState.width, + style: { + maxWidth: 'fit-content', + }, }, - style: pulseAnimation || { - animation: `${pulseKeyframe} 2s ease-in-out 0.5s infinite`, + { + props: ({ ownerState }) => ownerState.hasChildren && !ownerState.height, + style: { + height: 'auto', + }, }, - }, - { - props: { - animation: 'wave', + { + props: { + animation: 'pulse', + }, + style: pulseAnimation || { + animation: `${pulseKeyframe} 2s ease-in-out 0.5s infinite`, + }, }, - style: { - position: 'relative', - overflow: 'hidden', - /* Fix bug in Safari https://bugs.webkit.org/show_bug.cgi?id=68196 */ - WebkitMaskImage: '-webkit-radial-gradient(white, black)', - '&::after': { - background: `linear-gradient( + { + props: { + animation: 'wave', + }, + style: { + position: 'relative', + overflow: 'hidden', + /* Fix bug in Safari https://bugs.webkit.org/show_bug.cgi?id=68196 */ + WebkitMaskImage: '-webkit-radial-gradient(white, black)', + '&::after': { + background: `linear-gradient( 90deg, transparent, ${(theme.vars || theme).palette.action.hover}, transparent )`, - content: '""', - position: 'absolute', - transform: 'translateX(-100%)' /* Avoid flash during server-side hydration */, - bottom: 0, - left: 0, - right: 0, - top: 0, + content: '""', + position: 'absolute', + transform: 'translateX(-100%)' /* Avoid flash during server-side hydration */, + bottom: 0, + left: 0, + right: 0, + top: 0, + }, }, }, - }, - { - props: { - animation: 'wave', - }, - style: waveAnimation || { - animation: `${waveKeyframe} 2s linear 0.5s infinite`, + { + props: { + animation: 'wave', + }, + style: waveAnimation || { + animation: `${waveKeyframe} 2s linear 0.5s infinite`, + }, }, - }, - ], - }; -}); + ], + }; + }), +); const Skeleton = React.forwardRef(function Skeleton(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiSkeleton' }); diff --git a/packages/mui-material/src/Slider/Slider.js b/packages/mui-material/src/Slider/Slider.js index c07fa70870cb9c..e65ba70e710943 100644 --- a/packages/mui-material/src/Slider/Slider.js +++ b/packages/mui-material/src/Slider/Slider.js @@ -10,6 +10,7 @@ import useSlotProps from '@mui/utils/useSlotProps'; import { useSlider, valueToPercent } from './useSlider'; import isHostComponent from '../utils/isHostComponent'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import slotShouldForwardProp from '../styles/slotShouldForwardProp'; import shouldSpreadAdditionalProps from '../utils/shouldSpreadAdditionalProps'; @@ -37,88 +38,90 @@ export const SliderRoot = styled('span', { ownerState.track === false && styles.trackFalse, ]; }, -})(({ theme }) => ({ - borderRadius: 12, - boxSizing: 'content-box', - display: 'inline-block', - position: 'relative', - cursor: 'pointer', - touchAction: 'none', - WebkitTapHighlightColor: 'transparent', - '@media print': { - colorAdjust: 'exact', - }, - [`&.${sliderClasses.disabled}`]: { - pointerEvents: 'none', - cursor: 'default', - color: (theme.vars || theme).palette.grey[400], - }, - [`&.${sliderClasses.dragging}`]: { - [`& .${sliderClasses.thumb}, & .${sliderClasses.track}`]: { - transition: 'none', +})( + memoTheme(({ theme }) => ({ + borderRadius: 12, + boxSizing: 'content-box', + display: 'inline-block', + position: 'relative', + cursor: 'pointer', + touchAction: 'none', + WebkitTapHighlightColor: 'transparent', + '@media print': { + colorAdjust: 'exact', }, - }, - variants: [ - ...Object.entries(theme.palette) - .filter(([, palette]) => palette && palette.main) - .map(([color]) => ({ - props: { color }, + [`&.${sliderClasses.disabled}`]: { + pointerEvents: 'none', + cursor: 'default', + color: (theme.vars || theme).palette.grey[400], + }, + [`&.${sliderClasses.dragging}`]: { + [`& .${sliderClasses.thumb}, & .${sliderClasses.track}`]: { + transition: 'none', + }, + }, + variants: [ + ...Object.entries(theme.palette) + .filter(([, palette]) => palette && palette.main) + .map(([color]) => ({ + props: { color }, + style: { + color: (theme.vars || theme).palette[color].main, + }, + })), + { + props: { orientation: 'horizontal' }, style: { - color: (theme.vars || theme).palette[color].main, - }, - })), - { - props: { orientation: 'horizontal' }, - style: { - height: 4, - width: '100%', - padding: '13px 0', - // The primary input mechanism of the device includes a pointing device of limited accuracy. - '@media (pointer: coarse)': { - // Reach 42px touch target, about ~8mm on screen. - padding: '20px 0', + height: 4, + width: '100%', + padding: '13px 0', + // The primary input mechanism of the device includes a pointing device of limited accuracy. + '@media (pointer: coarse)': { + // Reach 42px touch target, about ~8mm on screen. + padding: '20px 0', + }, }, }, - }, - { - props: { orientation: 'horizontal', size: 'small' }, - style: { - height: 2, + { + props: { orientation: 'horizontal', size: 'small' }, + style: { + height: 2, + }, }, - }, - { - props: { orientation: 'horizontal', marked: true }, - style: { - marginBottom: 20, + { + props: { orientation: 'horizontal', marked: true }, + style: { + marginBottom: 20, + }, }, - }, - { - props: { orientation: 'vertical' }, - style: { - height: '100%', - width: 4, - padding: '0 13px', - // The primary input mechanism of the device includes a pointing device of limited accuracy. - '@media (pointer: coarse)': { - // Reach 42px touch target, about ~8mm on screen. - padding: '0 20px', + { + props: { orientation: 'vertical' }, + style: { + height: '100%', + width: 4, + padding: '0 13px', + // The primary input mechanism of the device includes a pointing device of limited accuracy. + '@media (pointer: coarse)': { + // Reach 42px touch target, about ~8mm on screen. + padding: '0 20px', + }, }, }, - }, - { - props: { orientation: 'vertical', size: 'small' }, - style: { - width: 2, + { + props: { orientation: 'vertical', size: 'small' }, + style: { + width: 2, + }, }, - }, - { - props: { orientation: 'vertical', marked: true }, - style: { - marginRight: 44, + { + props: { orientation: 'vertical', marked: true }, + style: { + marginRight: 44, + }, }, - }, - ], -})); + ], + })), +); export const SliderRail = styled('span', { name: 'MuiSlider', @@ -162,255 +165,261 @@ export const SliderTrack = styled('span', { name: 'MuiSlider', slot: 'Track', overridesResolver: (props, styles) => styles.track, -})(({ theme }) => { - return { - display: 'block', +})( + memoTheme(({ theme }) => { + return { + display: 'block', + position: 'absolute', + borderRadius: 'inherit', + border: '1px solid currentColor', + backgroundColor: 'currentColor', + transition: theme.transitions.create(['left', 'width', 'bottom', 'height'], { + duration: theme.transitions.duration.shortest, + }), + variants: [ + { + props: { size: 'small' }, + style: { + border: 'none', + }, + }, + { + props: { orientation: 'horizontal' }, + style: { + height: 'inherit', + top: '50%', + transform: 'translateY(-50%)', + }, + }, + { + props: { orientation: 'vertical' }, + style: { + width: 'inherit', + left: '50%', + transform: 'translateX(-50%)', + }, + }, + { + props: { track: false }, + style: { + display: 'none', + }, + }, + ...Object.entries(theme.palette) + .filter(([, palette]) => palette && palette.main) + .map(([color]) => ({ + props: { color, track: 'inverted' }, + style: { + ...(theme.vars + ? { + backgroundColor: theme.vars.palette.Slider[`${color}Track`], + borderColor: theme.vars.palette.Slider[`${color}Track`], + } + : { + backgroundColor: lighten(theme.palette[color].main, 0.62), + borderColor: lighten(theme.palette[color].main, 0.62), + ...theme.applyStyles('dark', { + backgroundColor: darken(theme.palette[color].main, 0.5), + }), + ...theme.applyStyles('dark', { + borderColor: darken(theme.palette[color].main, 0.5), + }), + }), + }, + })), + ], + }; + }), +); + +export const SliderThumb = styled('span', { + name: 'MuiSlider', + slot: 'Thumb', + overridesResolver: (props, styles) => { + const { ownerState } = props; + return [ + styles.thumb, + styles[`thumbColor${capitalize(ownerState.color)}`], + ownerState.size !== 'medium' && styles[`thumbSize${capitalize(ownerState.size)}`], + ]; + }, +})( + memoTheme(({ theme }) => ({ position: 'absolute', - borderRadius: 'inherit', - border: '1px solid currentColor', + width: 20, + height: 20, + boxSizing: 'border-box', + borderRadius: '50%', + outline: 0, backgroundColor: 'currentColor', - transition: theme.transitions.create(['left', 'width', 'bottom', 'height'], { + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + transition: theme.transitions.create(['box-shadow', 'left', 'bottom'], { duration: theme.transitions.duration.shortest, }), + '&::before': { + position: 'absolute', + content: '""', + borderRadius: 'inherit', + width: '100%', + height: '100%', + boxShadow: (theme.vars || theme).shadows[2], + }, + '&::after': { + position: 'absolute', + content: '""', + borderRadius: '50%', + // 42px is the hit target + width: 42, + height: 42, + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + }, + [`&.${sliderClasses.disabled}`]: { + '&:hover': { + boxShadow: 'none', + }, + }, variants: [ { props: { size: 'small' }, style: { - border: 'none', + width: 12, + height: 12, + '&::before': { + boxShadow: 'none', + }, }, }, { props: { orientation: 'horizontal' }, style: { - height: 'inherit', top: '50%', - transform: 'translateY(-50%)', + transform: 'translate(-50%, -50%)', }, }, { props: { orientation: 'vertical' }, style: { - width: 'inherit', left: '50%', - transform: 'translateX(-50%)', - }, - }, - { - props: { track: false }, - style: { - display: 'none', + transform: 'translate(-50%, 50%)', }, }, ...Object.entries(theme.palette) .filter(([, palette]) => palette && palette.main) .map(([color]) => ({ - props: { color, track: 'inverted' }, + props: { color }, style: { - ...(theme.vars - ? { - backgroundColor: theme.vars.palette.Slider[`${color}Track`], - borderColor: theme.vars.palette.Slider[`${color}Track`], - } - : { - backgroundColor: lighten(theme.palette[color].main, 0.62), - borderColor: lighten(theme.palette[color].main, 0.62), - ...theme.applyStyles('dark', { - backgroundColor: darken(theme.palette[color].main, 0.5), + [`&:hover, &.${sliderClasses.focusVisible}`]: { + ...(theme.vars + ? { + boxShadow: `0px 0px 0px 8px rgba(${theme.vars.palette[color].mainChannel} / 0.16)`, + } + : { + boxShadow: `0px 0px 0px 8px ${alpha(theme.palette[color].main, 0.16)}`, }), - ...theme.applyStyles('dark', { - borderColor: darken(theme.palette[color].main, 0.5), + '@media (hover: none)': { + boxShadow: 'none', + }, + }, + [`&.${sliderClasses.active}`]: { + ...(theme.vars + ? { + boxShadow: `0px 0px 0px 14px rgba(${theme.vars.palette[color].mainChannel} / 0.16)`, + } + : { + boxShadow: `0px 0px 0px 14px ${alpha(theme.palette[color].main, 0.16)}`, }), - }), + }, }, })), ], - }; -}); + })), +); -export const SliderThumb = styled('span', { +export const SliderValueLabel = styled(BaseSliderValueLabel, { name: 'MuiSlider', - slot: 'Thumb', - overridesResolver: (props, styles) => { - const { ownerState } = props; - return [ - styles.thumb, - styles[`thumbColor${capitalize(ownerState.color)}`], - ownerState.size !== 'medium' && styles[`thumbSize${capitalize(ownerState.size)}`], - ]; - }, -})(({ theme }) => ({ - position: 'absolute', - width: 20, - height: 20, - boxSizing: 'border-box', - borderRadius: '50%', - outline: 0, - backgroundColor: 'currentColor', - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - transition: theme.transitions.create(['box-shadow', 'left', 'bottom'], { - duration: theme.transitions.duration.shortest, - }), - '&::before': { - position: 'absolute', - content: '""', - borderRadius: 'inherit', - width: '100%', - height: '100%', - boxShadow: (theme.vars || theme).shadows[2], - }, - '&::after': { + slot: 'ValueLabel', + overridesResolver: (props, styles) => styles.valueLabel, +})( + memoTheme(({ theme }) => ({ + zIndex: 1, + whiteSpace: 'nowrap', + ...theme.typography.body2, + fontWeight: 500, + transition: theme.transitions.create(['transform'], { + duration: theme.transitions.duration.shortest, + }), position: 'absolute', - content: '""', - borderRadius: '50%', - // 42px is the hit target - width: 42, - height: 42, - top: '50%', - left: '50%', - transform: 'translate(-50%, -50%)', - }, - [`&.${sliderClasses.disabled}`]: { - '&:hover': { - boxShadow: 'none', - }, - }, - variants: [ - { - props: { size: 'small' }, - style: { - width: 12, - height: 12, - '&::before': { - boxShadow: 'none', - }, - }, - }, - { - props: { orientation: 'horizontal' }, - style: { - top: '50%', - transform: 'translate(-50%, -50%)', - }, - }, - { - props: { orientation: 'vertical' }, - style: { - left: '50%', - transform: 'translate(-50%, 50%)', - }, - }, - ...Object.entries(theme.palette) - .filter(([, palette]) => palette && palette.main) - .map(([color]) => ({ - props: { color }, + backgroundColor: (theme.vars || theme).palette.grey[600], + borderRadius: 2, + color: (theme.vars || theme).palette.common.white, + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + padding: '0.25rem 0.75rem', + variants: [ + { + props: { orientation: 'horizontal' }, style: { - [`&:hover, &.${sliderClasses.focusVisible}`]: { - ...(theme.vars - ? { - boxShadow: `0px 0px 0px 8px rgba(${theme.vars.palette[color].mainChannel} / 0.16)`, - } - : { - boxShadow: `0px 0px 0px 8px ${alpha(theme.palette[color].main, 0.16)}`, - }), - '@media (hover: none)': { - boxShadow: 'none', - }, + transform: 'translateY(-100%) scale(0)', + top: '-10px', + transformOrigin: 'bottom center', + '&::before': { + position: 'absolute', + content: '""', + width: 8, + height: 8, + transform: 'translate(-50%, 50%) rotate(45deg)', + backgroundColor: 'inherit', + bottom: 0, + left: '50%', }, - [`&.${sliderClasses.active}`]: { - ...(theme.vars - ? { - boxShadow: `0px 0px 0px 14px rgba(${theme.vars.palette[color].mainChannel} / 0.16)`, - } - : { - boxShadow: `0px 0px 0px 14px ${alpha(theme.palette[color].main, 0.16)}`, - }), + [`&.${sliderClasses.valueLabelOpen}`]: { + transform: 'translateY(-100%) scale(1)', }, }, - })), - ], -})); - -export const SliderValueLabel = styled(BaseSliderValueLabel, { - name: 'MuiSlider', - slot: 'ValueLabel', - overridesResolver: (props, styles) => styles.valueLabel, -})(({ theme }) => ({ - zIndex: 1, - whiteSpace: 'nowrap', - ...theme.typography.body2, - fontWeight: 500, - transition: theme.transitions.create(['transform'], { - duration: theme.transitions.duration.shortest, - }), - position: 'absolute', - backgroundColor: (theme.vars || theme).palette.grey[600], - borderRadius: 2, - color: (theme.vars || theme).palette.common.white, - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - padding: '0.25rem 0.75rem', - variants: [ - { - props: { orientation: 'horizontal' }, - style: { - transform: 'translateY(-100%) scale(0)', - top: '-10px', - transformOrigin: 'bottom center', - '&::before': { - position: 'absolute', - content: '""', - width: 8, - height: 8, - transform: 'translate(-50%, 50%) rotate(45deg)', - backgroundColor: 'inherit', - bottom: 0, - left: '50%', - }, - [`&.${sliderClasses.valueLabelOpen}`]: { - transform: 'translateY(-100%) scale(1)', - }, }, - }, - { - props: { orientation: 'vertical' }, - style: { - transform: 'translateY(-50%) scale(0)', - right: '30px', - top: '50%', - transformOrigin: 'right center', - '&::before': { - position: 'absolute', - content: '""', - width: 8, - height: 8, - transform: 'translate(-50%, -50%) rotate(45deg)', - backgroundColor: 'inherit', - right: -8, + { + props: { orientation: 'vertical' }, + style: { + transform: 'translateY(-50%) scale(0)', + right: '30px', top: '50%', - }, - [`&.${sliderClasses.valueLabelOpen}`]: { - transform: 'translateY(-50%) scale(1)', + transformOrigin: 'right center', + '&::before': { + position: 'absolute', + content: '""', + width: 8, + height: 8, + transform: 'translate(-50%, -50%) rotate(45deg)', + backgroundColor: 'inherit', + right: -8, + top: '50%', + }, + [`&.${sliderClasses.valueLabelOpen}`]: { + transform: 'translateY(-50%) scale(1)', + }, }, }, - }, - { - props: { size: 'small' }, - style: { - fontSize: theme.typography.pxToRem(12), - padding: '0.25rem 0.5rem', + { + props: { size: 'small' }, + style: { + fontSize: theme.typography.pxToRem(12), + padding: '0.25rem 0.5rem', + }, }, - }, - { - props: { orientation: 'vertical', size: 'small' }, - style: { - right: '20px', + { + props: { orientation: 'vertical', size: 'small' }, + style: { + right: '20px', + }, }, - }, - ], -})); + ], + })), +); export const SliderMark = styled('span', { name: 'MuiSlider', @@ -421,76 +430,80 @@ export const SliderMark = styled('span', { return [styles.mark, markActive && styles.markActive]; }, -})(({ theme }) => ({ - position: 'absolute', - width: 2, - height: 2, - borderRadius: 1, - backgroundColor: 'currentColor', - variants: [ - { - props: { orientation: 'horizontal' }, - style: { - top: '50%', - transform: 'translate(-1px, -50%)', +})( + memoTheme(({ theme }) => ({ + position: 'absolute', + width: 2, + height: 2, + borderRadius: 1, + backgroundColor: 'currentColor', + variants: [ + { + props: { orientation: 'horizontal' }, + style: { + top: '50%', + transform: 'translate(-1px, -50%)', + }, }, - }, - { - props: { orientation: 'vertical' }, - style: { - left: '50%', - transform: 'translate(-50%, 1px)', + { + props: { orientation: 'vertical' }, + style: { + left: '50%', + transform: 'translate(-50%, 1px)', + }, }, - }, - { - props: { markActive: true }, - style: { - backgroundColor: (theme.vars || theme).palette.background.paper, - opacity: 0.8, + { + props: { markActive: true }, + style: { + backgroundColor: (theme.vars || theme).palette.background.paper, + opacity: 0.8, + }, }, - }, - ], -})); + ], + })), +); export const SliderMarkLabel = styled('span', { name: 'MuiSlider', slot: 'MarkLabel', shouldForwardProp: (prop) => slotShouldForwardProp(prop) && prop !== 'markLabelActive', overridesResolver: (props, styles) => styles.markLabel, -})(({ theme }) => ({ - ...theme.typography.body2, - color: (theme.vars || theme).palette.text.secondary, - position: 'absolute', - whiteSpace: 'nowrap', - variants: [ - { - props: { orientation: 'horizontal' }, - style: { - top: 30, - transform: 'translateX(-50%)', - '@media (pointer: coarse)': { - top: 40, +})( + memoTheme(({ theme }) => ({ + ...theme.typography.body2, + color: (theme.vars || theme).palette.text.secondary, + position: 'absolute', + whiteSpace: 'nowrap', + variants: [ + { + props: { orientation: 'horizontal' }, + style: { + top: 30, + transform: 'translateX(-50%)', + '@media (pointer: coarse)': { + top: 40, + }, }, }, - }, - { - props: { orientation: 'vertical' }, - style: { - left: 36, - transform: 'translateY(50%)', - '@media (pointer: coarse)': { - left: 44, + { + props: { orientation: 'vertical' }, + style: { + left: 36, + transform: 'translateY(50%)', + '@media (pointer: coarse)': { + left: 44, + }, }, }, - }, - { - props: { markLabelActive: true }, - style: { - color: (theme.vars || theme).palette.text.primary, + { + props: { markLabelActive: true }, + style: { + color: (theme.vars || theme).palette.text.primary, + }, }, - }, - ], -})); + ], + })), +); const useUtilityClasses = (ownerState) => { const { disabled, dragging, marked, orientation, track, classes, color, size } = ownerState; diff --git a/packages/mui-material/src/Snackbar/Snackbar.js b/packages/mui-material/src/Snackbar/Snackbar.js index 7c3152165293be..40d0bf31d04691 100644 --- a/packages/mui-material/src/Snackbar/Snackbar.js +++ b/packages/mui-material/src/Snackbar/Snackbar.js @@ -6,6 +6,7 @@ import useSlotProps from '@mui/utils/useSlotProps'; import useSnackbar from './useSnackbar'; import ClickAwayListener from '../ClickAwayListener'; import { styled, useTheme } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import capitalize from '../utils/capitalize'; import Grow from '../Grow'; @@ -40,55 +41,57 @@ const SnackbarRoot = styled('div', { ], ]; }, -})(({ theme }) => ({ - zIndex: (theme.vars || theme).zIndex.snackbar, - position: 'fixed', - display: 'flex', - left: 8, - right: 8, - justifyContent: 'center', - alignItems: 'center', - variants: [ - { - props: ({ ownerState }) => ownerState.anchorOrigin.vertical === 'top', - style: { top: 8, [theme.breakpoints.up('sm')]: { top: 24 } }, - }, - { - props: ({ ownerState }) => ownerState.anchorOrigin.vertical !== 'top', - style: { bottom: 8, [theme.breakpoints.up('sm')]: { bottom: 24 } }, - }, - { - props: ({ ownerState }) => ownerState.anchorOrigin.horizontal === 'left', - style: { - justifyContent: 'flex-start', - [theme.breakpoints.up('sm')]: { - left: 24, - right: 'auto', +})( + memoTheme(({ theme }) => ({ + zIndex: (theme.vars || theme).zIndex.snackbar, + position: 'fixed', + display: 'flex', + left: 8, + right: 8, + justifyContent: 'center', + alignItems: 'center', + variants: [ + { + props: ({ ownerState }) => ownerState.anchorOrigin.vertical === 'top', + style: { top: 8, [theme.breakpoints.up('sm')]: { top: 24 } }, + }, + { + props: ({ ownerState }) => ownerState.anchorOrigin.vertical !== 'top', + style: { bottom: 8, [theme.breakpoints.up('sm')]: { bottom: 24 } }, + }, + { + props: ({ ownerState }) => ownerState.anchorOrigin.horizontal === 'left', + style: { + justifyContent: 'flex-start', + [theme.breakpoints.up('sm')]: { + left: 24, + right: 'auto', + }, }, }, - }, - { - props: ({ ownerState }) => ownerState.anchorOrigin.horizontal === 'right', - style: { - justifyContent: 'flex-end', - [theme.breakpoints.up('sm')]: { - right: 24, - left: 'auto', + { + props: ({ ownerState }) => ownerState.anchorOrigin.horizontal === 'right', + style: { + justifyContent: 'flex-end', + [theme.breakpoints.up('sm')]: { + right: 24, + left: 'auto', + }, }, }, - }, - { - props: ({ ownerState }) => ownerState.anchorOrigin.horizontal === 'center', - style: { - [theme.breakpoints.up('sm')]: { - left: '50%', - right: 'auto', - transform: 'translateX(-50%)', + { + props: ({ ownerState }) => ownerState.anchorOrigin.horizontal === 'center', + style: { + [theme.breakpoints.up('sm')]: { + left: '50%', + right: 'auto', + transform: 'translateX(-50%)', + }, }, }, - }, - ], -})); + ], + })), +); const Snackbar = React.forwardRef(function Snackbar(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiSnackbar' }); diff --git a/packages/mui-material/src/SnackbarContent/SnackbarContent.js b/packages/mui-material/src/SnackbarContent/SnackbarContent.js index da761faad762f0..ef31e98cdfe390 100644 --- a/packages/mui-material/src/SnackbarContent/SnackbarContent.js +++ b/packages/mui-material/src/SnackbarContent/SnackbarContent.js @@ -5,6 +5,7 @@ import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { emphasize } from '@mui/system/colorManipulator'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import Paper from '../Paper'; import { getSnackbarContentUtilityClass } from './snackbarContentClasses'; @@ -25,28 +26,30 @@ const SnackbarContentRoot = styled(Paper, { name: 'MuiSnackbarContent', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})(({ theme }) => { - const emphasis = theme.palette.mode === 'light' ? 0.8 : 0.98; - const backgroundColor = emphasize(theme.palette.background.default, emphasis); +})( + memoTheme(({ theme }) => { + const emphasis = theme.palette.mode === 'light' ? 0.8 : 0.98; + const backgroundColor = emphasize(theme.palette.background.default, emphasis); - return { - ...theme.typography.body2, - color: theme.vars - ? theme.vars.palette.SnackbarContent.color - : theme.palette.getContrastText(backgroundColor), - backgroundColor: theme.vars ? theme.vars.palette.SnackbarContent.bg : backgroundColor, - display: 'flex', - alignItems: 'center', - flexWrap: 'wrap', - padding: '6px 16px', - borderRadius: (theme.vars || theme).shape.borderRadius, - flexGrow: 1, - [theme.breakpoints.up('sm')]: { - flexGrow: 'initial', - minWidth: 288, - }, - }; -}); + return { + ...theme.typography.body2, + color: theme.vars + ? theme.vars.palette.SnackbarContent.color + : theme.palette.getContrastText(backgroundColor), + backgroundColor: theme.vars ? theme.vars.palette.SnackbarContent.bg : backgroundColor, + display: 'flex', + alignItems: 'center', + flexWrap: 'wrap', + padding: '6px 16px', + borderRadius: (theme.vars || theme).shape.borderRadius, + flexGrow: 1, + [theme.breakpoints.up('sm')]: { + flexGrow: 'initial', + minWidth: 288, + }, + }; + }), +); const SnackbarContentMessage = styled('div', { name: 'MuiSnackbarContent', diff --git a/packages/mui-material/src/SpeedDial/SpeedDial.js b/packages/mui-material/src/SpeedDial/SpeedDial.js index f130cf4876855d..378962f80fb0fc 100644 --- a/packages/mui-material/src/SpeedDial/SpeedDial.js +++ b/packages/mui-material/src/SpeedDial/SpeedDial.js @@ -7,6 +7,7 @@ import composeClasses from '@mui/utils/composeClasses'; import useTimeout from '@mui/utils/useTimeout'; import clamp from '@mui/utils/clamp'; import { styled, useTheme } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import Zoom from '../Zoom'; import Fab from '../Fab'; @@ -50,74 +51,76 @@ const SpeedDialRoot = styled('div', { return [styles.root, styles[`direction${capitalize(ownerState.direction)}`]]; }, -})(({ theme }) => ({ - zIndex: (theme.vars || theme).zIndex.speedDial, - display: 'flex', - alignItems: 'center', - pointerEvents: 'none', - variants: [ - { - props: { - direction: 'up', - }, - style: { - flexDirection: 'column-reverse', - [`& .${speedDialClasses.actions}`]: { +})( + memoTheme(({ theme }) => ({ + zIndex: (theme.vars || theme).zIndex.speedDial, + display: 'flex', + alignItems: 'center', + pointerEvents: 'none', + variants: [ + { + props: { + direction: 'up', + }, + style: { flexDirection: 'column-reverse', - marginBottom: -dialRadius, - paddingBottom: spacingActions + dialRadius, + [`& .${speedDialClasses.actions}`]: { + flexDirection: 'column-reverse', + marginBottom: -dialRadius, + paddingBottom: spacingActions + dialRadius, + }, }, }, - }, - { - props: { - direction: 'down', - }, - style: { - flexDirection: 'column', - [`& .${speedDialClasses.actions}`]: { + { + props: { + direction: 'down', + }, + style: { flexDirection: 'column', - marginTop: -dialRadius, - paddingTop: spacingActions + dialRadius, + [`& .${speedDialClasses.actions}`]: { + flexDirection: 'column', + marginTop: -dialRadius, + paddingTop: spacingActions + dialRadius, + }, }, }, - }, - { - props: { - direction: 'left', - }, - style: { - flexDirection: 'row-reverse', - [`& .${speedDialClasses.actions}`]: { + { + props: { + direction: 'left', + }, + style: { flexDirection: 'row-reverse', - marginRight: -dialRadius, - paddingRight: spacingActions + dialRadius, + [`& .${speedDialClasses.actions}`]: { + flexDirection: 'row-reverse', + marginRight: -dialRadius, + paddingRight: spacingActions + dialRadius, + }, }, }, - }, - { - props: { - direction: 'right', - }, - style: { - flexDirection: 'row', - [`& .${speedDialClasses.actions}`]: { + { + props: { + direction: 'right', + }, + style: { flexDirection: 'row', - marginLeft: -dialRadius, - paddingLeft: spacingActions + dialRadius, + [`& .${speedDialClasses.actions}`]: { + flexDirection: 'row', + marginLeft: -dialRadius, + paddingLeft: spacingActions + dialRadius, + }, }, }, - }, - ], -})); + ], + })), +); const SpeedDialFab = styled(Fab, { name: 'MuiSpeedDial', slot: 'Fab', overridesResolver: (props, styles) => styles.fab, -})(() => ({ +})({ pointerEvents: 'auto', -})); +}); const SpeedDialActions = styled('div', { name: 'MuiSpeedDial', diff --git a/packages/mui-material/src/SpeedDialAction/SpeedDialAction.js b/packages/mui-material/src/SpeedDialAction/SpeedDialAction.js index e93a42155ccddc..ef75983bd42d54 100644 --- a/packages/mui-material/src/SpeedDialAction/SpeedDialAction.js +++ b/packages/mui-material/src/SpeedDialAction/SpeedDialAction.js @@ -6,6 +6,7 @@ import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { emphasize } from '@mui/system/colorManipulator'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import Fab from '../Fab'; import Tooltip from '../Tooltip'; @@ -37,29 +38,31 @@ const SpeedDialActionFab = styled(Fab, { return [styles.fab, !ownerState.open && styles.fabClosed]; }, -})(({ theme }) => ({ - margin: 8, - color: (theme.vars || theme).palette.text.secondary, - backgroundColor: (theme.vars || theme).palette.background.paper, - '&:hover': { - backgroundColor: theme.vars - ? theme.vars.palette.SpeedDialAction.fabHoverBg - : emphasize(theme.palette.background.paper, 0.15), - }, - transition: `${theme.transitions.create('transform', { - duration: theme.transitions.duration.shorter, - })}, opacity 0.8s`, - opacity: 1, - variants: [ - { - props: ({ ownerState }) => !ownerState.open, - style: { - opacity: 0, - transform: 'scale(0)', - }, +})( + memoTheme(({ theme }) => ({ + margin: 8, + color: (theme.vars || theme).palette.text.secondary, + backgroundColor: (theme.vars || theme).palette.background.paper, + '&:hover': { + backgroundColor: theme.vars + ? theme.vars.palette.SpeedDialAction.fabHoverBg + : emphasize(theme.palette.background.paper, 0.15), }, - ], -})); + transition: `${theme.transitions.create('transform', { + duration: theme.transitions.duration.shorter, + })}, opacity 0.8s`, + opacity: 1, + variants: [ + { + props: ({ ownerState }) => !ownerState.open, + style: { + opacity: 0, + transform: 'scale(0)', + }, + }, + ], + })), +); const SpeedDialActionStaticTooltip = styled('span', { name: 'MuiSpeedDialAction', @@ -73,67 +76,71 @@ const SpeedDialActionStaticTooltip = styled('span', { styles[`tooltipPlacement${capitalize(ownerState.tooltipPlacement)}`], ]; }, -})(({ theme }) => ({ - position: 'relative', - display: 'flex', - alignItems: 'center', - [`& .${speedDialActionClasses.staticTooltipLabel}`]: { - transition: theme.transitions.create(['transform', 'opacity'], { - duration: theme.transitions.duration.shorter, - }), - opacity: 1, - }, - variants: [ - { - props: ({ ownerState }) => !ownerState.open, - style: { - [`& .${speedDialActionClasses.staticTooltipLabel}`]: { - opacity: 0, - transform: 'scale(0.5)', - }, - }, +})( + memoTheme(({ theme }) => ({ + position: 'relative', + display: 'flex', + alignItems: 'center', + [`& .${speedDialActionClasses.staticTooltipLabel}`]: { + transition: theme.transitions.create(['transform', 'opacity'], { + duration: theme.transitions.duration.shorter, + }), + opacity: 1, }, - { - props: { - tooltipPlacement: 'left', - }, - style: { - [`& .${speedDialActionClasses.staticTooltipLabel}`]: { - transformOrigin: '100% 50%', - right: '100%', - marginRight: 8, + variants: [ + { + props: ({ ownerState }) => !ownerState.open, + style: { + [`& .${speedDialActionClasses.staticTooltipLabel}`]: { + opacity: 0, + transform: 'scale(0.5)', + }, }, }, - }, - { - props: { - tooltipPlacement: 'right', + { + props: { + tooltipPlacement: 'left', + }, + style: { + [`& .${speedDialActionClasses.staticTooltipLabel}`]: { + transformOrigin: '100% 50%', + right: '100%', + marginRight: 8, + }, + }, }, - style: { - [`& .${speedDialActionClasses.staticTooltipLabel}`]: { - transformOrigin: '0% 50%', - left: '100%', - marginLeft: 8, + { + props: { + tooltipPlacement: 'right', + }, + style: { + [`& .${speedDialActionClasses.staticTooltipLabel}`]: { + transformOrigin: '0% 50%', + left: '100%', + marginLeft: 8, + }, }, }, - }, - ], -})); + ], + })), +); const SpeedDialActionStaticTooltipLabel = styled('span', { name: 'MuiSpeedDialAction', slot: 'StaticTooltipLabel', overridesResolver: (props, styles) => styles.staticTooltipLabel, -})(({ theme }) => ({ - position: 'absolute', - ...theme.typography.body1, - backgroundColor: (theme.vars || theme).palette.background.paper, - borderRadius: (theme.vars || theme).shape.borderRadius, - boxShadow: (theme.vars || theme).shadows[1], - color: (theme.vars || theme).palette.text.secondary, - padding: '4px 16px', - wordBreak: 'keep-all', -})); +})( + memoTheme(({ theme }) => ({ + position: 'absolute', + ...theme.typography.body1, + backgroundColor: (theme.vars || theme).palette.background.paper, + borderRadius: (theme.vars || theme).shape.borderRadius, + boxShadow: (theme.vars || theme).shadows[1], + color: (theme.vars || theme).palette.text.secondary, + padding: '4px 16px', + wordBreak: 'keep-all', + })), +); const SpeedDialAction = React.forwardRef(function SpeedDialAction(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiSpeedDialAction' }); diff --git a/packages/mui-material/src/SpeedDialIcon/SpeedDialIcon.js b/packages/mui-material/src/SpeedDialIcon/SpeedDialIcon.js index 9943a79ee0a1d3..73c4c66477e375 100644 --- a/packages/mui-material/src/SpeedDialIcon/SpeedDialIcon.js +++ b/packages/mui-material/src/SpeedDialIcon/SpeedDialIcon.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import AddIcon from '../internal/svg-icons/Add'; import speedDialIconClasses, { getSpeedDialIconUtilityClass } from './speedDialIconClasses'; @@ -38,49 +39,51 @@ const SpeedDialIconRoot = styled('span', { styles.root, ]; }, -})(({ theme }) => ({ - height: 24, - [`& .${speedDialIconClasses.icon}`]: { - transition: theme.transitions.create(['transform', 'opacity'], { - duration: theme.transitions.duration.short, - }), - }, - [`& .${speedDialIconClasses.openIcon}`]: { - position: 'absolute', - transition: theme.transitions.create(['transform', 'opacity'], { - duration: theme.transitions.duration.short, - }), - opacity: 0, - transform: 'rotate(-45deg)', - }, - variants: [ - { - props: ({ ownerState }) => ownerState.open, - style: { - [`& .${speedDialIconClasses.icon}`]: { - transform: 'rotate(45deg)', +})( + memoTheme(({ theme }) => ({ + height: 24, + [`& .${speedDialIconClasses.icon}`]: { + transition: theme.transitions.create(['transform', 'opacity'], { + duration: theme.transitions.duration.short, + }), + }, + [`& .${speedDialIconClasses.openIcon}`]: { + position: 'absolute', + transition: theme.transitions.create(['transform', 'opacity'], { + duration: theme.transitions.duration.short, + }), + opacity: 0, + transform: 'rotate(-45deg)', + }, + variants: [ + { + props: ({ ownerState }) => ownerState.open, + style: { + [`& .${speedDialIconClasses.icon}`]: { + transform: 'rotate(45deg)', + }, }, }, - }, - { - props: ({ ownerState }) => ownerState.open && ownerState.openIcon, - style: { - [`& .${speedDialIconClasses.icon}`]: { - opacity: 0, + { + props: ({ ownerState }) => ownerState.open && ownerState.openIcon, + style: { + [`& .${speedDialIconClasses.icon}`]: { + opacity: 0, + }, }, }, - }, - { - props: ({ ownerState }) => ownerState.open, - style: { - [`& .${speedDialIconClasses.openIcon}`]: { - transform: 'rotate(0deg)', - opacity: 1, + { + props: ({ ownerState }) => ownerState.open, + style: { + [`& .${speedDialIconClasses.openIcon}`]: { + transform: 'rotate(0deg)', + opacity: 1, + }, }, }, - }, - ], -})); + ], + })), +); const SpeedDialIcon = React.forwardRef(function SpeedDialIcon(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiSpeedDialIcon' }); diff --git a/packages/mui-material/src/StepConnector/StepConnector.js b/packages/mui-material/src/StepConnector/StepConnector.js index 3d6f439096668b..dfa308f4d49979 100644 --- a/packages/mui-material/src/StepConnector/StepConnector.js +++ b/packages/mui-material/src/StepConnector/StepConnector.js @@ -5,6 +5,7 @@ import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import capitalize from '../utils/capitalize'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import StepperContext from '../Stepper/StepperContext'; import StepContext from '../Step/StepContext'; @@ -70,31 +71,33 @@ const StepConnectorLine = styled('span', { return [styles.line, styles[`line${capitalize(ownerState.orientation)}`]]; }, -})(({ theme }) => { - const borderColor = - theme.palette.mode === 'light' ? theme.palette.grey[400] : theme.palette.grey[600]; - return { - display: 'block', - borderColor: theme.vars ? theme.vars.palette.StepConnector.border : borderColor, - variants: [ - { - props: { orientation: 'horizontal' }, - style: { - borderTopStyle: 'solid', - borderTopWidth: 1, +})( + memoTheme(({ theme }) => { + const borderColor = + theme.palette.mode === 'light' ? theme.palette.grey[400] : theme.palette.grey[600]; + return { + display: 'block', + borderColor: theme.vars ? theme.vars.palette.StepConnector.border : borderColor, + variants: [ + { + props: { orientation: 'horizontal' }, + style: { + borderTopStyle: 'solid', + borderTopWidth: 1, + }, }, - }, - { - props: { orientation: 'vertical' }, - style: { - borderLeftStyle: 'solid', - borderLeftWidth: 1, - minHeight: 24, + { + props: { orientation: 'vertical' }, + style: { + borderLeftStyle: 'solid', + borderLeftWidth: 1, + minHeight: 24, + }, }, - }, - ], - }; -}); + ], + }; + }), +); const StepConnector = React.forwardRef(function StepConnector(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiStepConnector' }); diff --git a/packages/mui-material/src/StepContent/StepContent.js b/packages/mui-material/src/StepContent/StepContent.js index 8584ea779da836..f806bacde0c685 100644 --- a/packages/mui-material/src/StepContent/StepContent.js +++ b/packages/mui-material/src/StepContent/StepContent.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import Collapse from '../Collapse'; import StepperContext from '../Stepper/StepperContext'; @@ -26,24 +27,26 @@ const StepContentRoot = styled('div', { return [styles.root, ownerState.last && styles.last]; }, -})(({ theme }) => ({ - marginLeft: 12, // half icon - paddingLeft: 8 + 12, // margin + half icon - paddingRight: 8, - borderLeft: theme.vars - ? `1px solid ${theme.vars.palette.StepContent.border}` - : `1px solid ${ - theme.palette.mode === 'light' ? theme.palette.grey[400] : theme.palette.grey[600] - }`, - variants: [ - { - props: { last: true }, - style: { - borderLeft: 'none', +})( + memoTheme(({ theme }) => ({ + marginLeft: 12, // half icon + paddingLeft: 8 + 12, // margin + half icon + paddingRight: 8, + borderLeft: theme.vars + ? `1px solid ${theme.vars.palette.StepContent.border}` + : `1px solid ${ + theme.palette.mode === 'light' ? theme.palette.grey[400] : theme.palette.grey[600] + }`, + variants: [ + { + props: { last: true }, + style: { + borderLeft: 'none', + }, }, - }, - ], -})); + ], + })), +); const StepContentTransition = styled(Collapse, { name: 'MuiStepContent', diff --git a/packages/mui-material/src/StepIcon/StepIcon.js b/packages/mui-material/src/StepIcon/StepIcon.js index f51d3c070ef061..8a4ea813242e15 100644 --- a/packages/mui-material/src/StepIcon/StepIcon.js +++ b/packages/mui-material/src/StepIcon/StepIcon.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import CheckCircle from '../internal/svg-icons/CheckCircle'; import Warning from '../internal/svg-icons/Warning'; @@ -25,32 +26,36 @@ const StepIconRoot = styled(SvgIcon, { name: 'MuiStepIcon', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})(({ theme }) => ({ - display: 'block', - transition: theme.transitions.create('color', { - duration: theme.transitions.duration.shortest, - }), - color: (theme.vars || theme).palette.text.disabled, - [`&.${stepIconClasses.completed}`]: { - color: (theme.vars || theme).palette.primary.main, - }, - [`&.${stepIconClasses.active}`]: { - color: (theme.vars || theme).palette.primary.main, - }, - [`&.${stepIconClasses.error}`]: { - color: (theme.vars || theme).palette.error.main, - }, -})); +})( + memoTheme(({ theme }) => ({ + display: 'block', + transition: theme.transitions.create('color', { + duration: theme.transitions.duration.shortest, + }), + color: (theme.vars || theme).palette.text.disabled, + [`&.${stepIconClasses.completed}`]: { + color: (theme.vars || theme).palette.primary.main, + }, + [`&.${stepIconClasses.active}`]: { + color: (theme.vars || theme).palette.primary.main, + }, + [`&.${stepIconClasses.error}`]: { + color: (theme.vars || theme).palette.error.main, + }, + })), +); const StepIconText = styled('text', { name: 'MuiStepIcon', slot: 'Text', overridesResolver: (props, styles) => styles.text, -})(({ theme }) => ({ - fill: (theme.vars || theme).palette.primary.contrastText, - fontSize: theme.typography.caption.fontSize, - fontFamily: theme.typography.fontFamily, -})); +})( + memoTheme(({ theme }) => ({ + fill: (theme.vars || theme).palette.primary.contrastText, + fontSize: theme.typography.caption.fontSize, + fontFamily: theme.typography.fontFamily, + })), +); const StepIcon = React.forwardRef(function StepIcon(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiStepIcon' }); diff --git a/packages/mui-material/src/StepLabel/StepLabel.js b/packages/mui-material/src/StepLabel/StepLabel.js index b09ae961ca293b..e706f9151c810e 100644 --- a/packages/mui-material/src/StepLabel/StepLabel.js +++ b/packages/mui-material/src/StepLabel/StepLabel.js @@ -7,6 +7,7 @@ import StepContext from '../Step/StepContext'; import StepIcon from '../StepIcon'; import StepperContext from '../Stepper/StepperContext'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import stepLabelClasses, { getStepLabelUtilityClass } from './stepLabelClasses'; import useSlot from '../utils/useSlot'; @@ -76,27 +77,29 @@ const StepLabelLabel = styled('span', { name: 'MuiStepLabel', slot: 'Label', overridesResolver: (props, styles) => styles.label, -})(({ theme }) => ({ - ...theme.typography.body2, - display: 'block', - transition: theme.transitions.create('color', { - duration: theme.transitions.duration.shortest, - }), - [`&.${stepLabelClasses.active}`]: { - color: (theme.vars || theme).palette.text.primary, - fontWeight: 500, - }, - [`&.${stepLabelClasses.completed}`]: { - color: (theme.vars || theme).palette.text.primary, - fontWeight: 500, - }, - [`&.${stepLabelClasses.alternativeLabel}`]: { - marginTop: 16, - }, - [`&.${stepLabelClasses.error}`]: { - color: (theme.vars || theme).palette.error.main, - }, -})); +})( + memoTheme(({ theme }) => ({ + ...theme.typography.body2, + display: 'block', + transition: theme.transitions.create('color', { + duration: theme.transitions.duration.shortest, + }), + [`&.${stepLabelClasses.active}`]: { + color: (theme.vars || theme).palette.text.primary, + fontWeight: 500, + }, + [`&.${stepLabelClasses.completed}`]: { + color: (theme.vars || theme).palette.text.primary, + fontWeight: 500, + }, + [`&.${stepLabelClasses.alternativeLabel}`]: { + marginTop: 16, + }, + [`&.${stepLabelClasses.error}`]: { + color: (theme.vars || theme).palette.error.main, + }, + })), +); const StepLabelIconContainer = styled('span', { name: 'MuiStepLabel', @@ -115,13 +118,15 @@ const StepLabelLabelContainer = styled('span', { name: 'MuiStepLabel', slot: 'LabelContainer', overridesResolver: (props, styles) => styles.labelContainer, -})(({ theme }) => ({ - width: '100%', - color: (theme.vars || theme).palette.text.secondary, - [`&.${stepLabelClasses.alternativeLabel}`]: { - textAlign: 'center', - }, -})); +})( + memoTheme(({ theme }) => ({ + width: '100%', + color: (theme.vars || theme).palette.text.secondary, + [`&.${stepLabelClasses.alternativeLabel}`]: { + textAlign: 'center', + }, + })), +); const StepLabel = React.forwardRef(function StepLabel(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiStepLabel' }); diff --git a/packages/mui-material/src/SvgIcon/SvgIcon.js b/packages/mui-material/src/SvgIcon/SvgIcon.js index 04d38dac8b3c27..cec089c7716bf2 100644 --- a/packages/mui-material/src/SvgIcon/SvgIcon.js +++ b/packages/mui-material/src/SvgIcon/SvgIcon.js @@ -5,6 +5,7 @@ import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import capitalize from '../utils/capitalize'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import { getSvgIconUtilityClass } from './svgIconClasses'; @@ -34,61 +35,63 @@ const SvgIconRoot = styled('svg', { styles[`fontSize${capitalize(ownerState.fontSize)}`], ]; }, -})(({ theme }) => ({ - userSelect: 'none', - width: '1em', - height: '1em', - display: 'inline-block', - flexShrink: 0, - transition: theme.transitions?.create?.('fill', { - duration: (theme.vars ?? theme).transitions?.duration?.shorter, - }), - variants: [ - { - props: (props) => !props.hasSvgAsChild, - style: { - // the will define the property that has `currentColor` - // for example heroicons uses fill="none" and stroke="currentColor" - fill: 'currentColor', +})( + memoTheme(({ theme }) => ({ + userSelect: 'none', + width: '1em', + height: '1em', + display: 'inline-block', + flexShrink: 0, + transition: theme.transitions?.create?.('fill', { + duration: (theme.vars ?? theme).transitions?.duration?.shorter, + }), + variants: [ + { + props: (props) => !props.hasSvgAsChild, + style: { + // the will define the property that has `currentColor` + // for example heroicons uses fill="none" and stroke="currentColor" + fill: 'currentColor', + }, }, - }, - { - props: { fontSize: 'inherit' }, - style: { fontSize: 'inherit' }, - }, - { - props: { fontSize: 'small' }, - style: { fontSize: theme.typography?.pxToRem?.(20) || '1.25rem' }, - }, - { - props: { fontSize: 'medium' }, - style: { fontSize: theme.typography?.pxToRem?.(24) || '1.5rem' }, - }, - { - props: { fontSize: 'large' }, - style: { fontSize: theme.typography?.pxToRem?.(35) || '2.1875rem' }, - }, - // TODO v5 deprecate color prop, v6 remove for sx - ...Object.entries((theme.vars ?? theme).palette) - .filter(([, value]) => value && value.main) - .map(([color]) => ({ - props: { color }, - style: { color: (theme.vars ?? theme).palette?.[color]?.main }, - })), - { - props: { color: 'action' }, - style: { color: (theme.vars ?? theme).palette?.action?.active }, - }, - { - props: { color: 'disabled' }, - style: { color: (theme.vars ?? theme).palette?.action?.disabled }, - }, - { - props: { color: 'inherit' }, - style: { color: undefined }, - }, - ], -})); + { + props: { fontSize: 'inherit' }, + style: { fontSize: 'inherit' }, + }, + { + props: { fontSize: 'small' }, + style: { fontSize: theme.typography?.pxToRem?.(20) || '1.25rem' }, + }, + { + props: { fontSize: 'medium' }, + style: { fontSize: theme.typography?.pxToRem?.(24) || '1.5rem' }, + }, + { + props: { fontSize: 'large' }, + style: { fontSize: theme.typography?.pxToRem?.(35) || '2.1875rem' }, + }, + // TODO v5 deprecate color prop, v6 remove for sx + ...Object.entries((theme.vars ?? theme).palette) + .filter(([, value]) => value && value.main) + .map(([color]) => ({ + props: { color }, + style: { color: (theme.vars ?? theme).palette?.[color]?.main }, + })), + { + props: { color: 'action' }, + style: { color: (theme.vars ?? theme).palette?.action?.active }, + }, + { + props: { color: 'disabled' }, + style: { color: (theme.vars ?? theme).palette?.action?.disabled }, + }, + { + props: { color: 'inherit' }, + style: { color: undefined }, + }, + ], + })), +); const SvgIcon = React.forwardRef(function SvgIcon(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiSvgIcon' }); diff --git a/packages/mui-material/src/SwipeableDrawer/SwipeArea.js b/packages/mui-material/src/SwipeableDrawer/SwipeArea.js index c3855344bc11c4..69ca18085f2fcb 100644 --- a/packages/mui-material/src/SwipeableDrawer/SwipeArea.js +++ b/packages/mui-material/src/SwipeableDrawer/SwipeArea.js @@ -3,55 +3,58 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import clsx from 'clsx'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import rootShouldForwardProp from '../styles/rootShouldForwardProp'; import capitalize from '../utils/capitalize'; import { isHorizontal } from '../Drawer/Drawer'; -const SwipeAreaRoot = styled('div', { shouldForwardProp: rootShouldForwardProp })(({ theme }) => ({ - position: 'fixed', - top: 0, - left: 0, - bottom: 0, - zIndex: theme.zIndex.drawer - 1, - variants: [ - { - props: { - anchor: 'left', +const SwipeAreaRoot = styled('div', { shouldForwardProp: rootShouldForwardProp })( + memoTheme(({ theme }) => ({ + position: 'fixed', + top: 0, + left: 0, + bottom: 0, + zIndex: theme.zIndex.drawer - 1, + variants: [ + { + props: { + anchor: 'left', + }, + style: { + right: 'auto', + }, }, - style: { - right: 'auto', + { + props: { + anchor: 'right', + }, + style: { + left: 'auto', + right: 0, + }, }, - }, - { - props: { - anchor: 'right', + { + props: { + anchor: 'top', + }, + style: { + bottom: 'auto', + right: 0, + }, }, - style: { - left: 'auto', - right: 0, + { + props: { + anchor: 'bottom', + }, + style: { + top: 'auto', + bottom: 0, + right: 0, + }, }, - }, - { - props: { - anchor: 'top', - }, - style: { - bottom: 'auto', - right: 0, - }, - }, - { - props: { - anchor: 'bottom', - }, - style: { - top: 'auto', - bottom: 0, - right: 0, - }, - }, - ], -})); + ], + })), +); /** * @ignore - internal component. diff --git a/packages/mui-material/src/Switch/Switch.js b/packages/mui-material/src/Switch/Switch.js index f69e5e7ffb799c..1a0fe4a1ecea9e 100644 --- a/packages/mui-material/src/Switch/Switch.js +++ b/packages/mui-material/src/Switch/Switch.js @@ -9,6 +9,7 @@ import { alpha, darken, lighten } from '@mui/system/colorManipulator'; import capitalize from '../utils/capitalize'; import SwitchBase from '../internal/SwitchBase'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import switchClasses, { getSwitchUtilityClass } from './switchClasses'; @@ -105,7 +106,7 @@ const SwitchSwitchBase = styled(SwitchBase, { ]; }, })( - ({ theme }) => ({ + memoTheme(({ theme }) => ({ position: 'absolute', top: 0, left: 0, @@ -136,8 +137,8 @@ const SwitchSwitchBase = styled(SwitchBase, { left: '-100%', width: '300%', }, - }), - ({ theme }) => ({ + })), + memoTheme(({ theme }) => ({ '&:hover': { backgroundColor: theme.vars ? `rgba(${theme.vars.palette.action.activeChannel} / ${theme.vars.palette.action.hoverOpacity})` @@ -179,40 +180,44 @@ const SwitchSwitchBase = styled(SwitchBase, { }, })), ], - }), + })), ); const SwitchTrack = styled('span', { name: 'MuiSwitch', slot: 'Track', overridesResolver: (props, styles) => styles.track, -})(({ theme }) => ({ - height: '100%', - width: '100%', - borderRadius: 14 / 2, - zIndex: -1, - transition: theme.transitions.create(['opacity', 'background-color'], { - duration: theme.transitions.duration.shortest, - }), - backgroundColor: theme.vars - ? theme.vars.palette.common.onBackground - : `${theme.palette.mode === 'light' ? theme.palette.common.black : theme.palette.common.white}`, - opacity: theme.vars - ? theme.vars.opacity.switchTrack - : `${theme.palette.mode === 'light' ? 0.38 : 0.3}`, -})); +})( + memoTheme(({ theme }) => ({ + height: '100%', + width: '100%', + borderRadius: 14 / 2, + zIndex: -1, + transition: theme.transitions.create(['opacity', 'background-color'], { + duration: theme.transitions.duration.shortest, + }), + backgroundColor: theme.vars + ? theme.vars.palette.common.onBackground + : `${theme.palette.mode === 'light' ? theme.palette.common.black : theme.palette.common.white}`, + opacity: theme.vars + ? theme.vars.opacity.switchTrack + : `${theme.palette.mode === 'light' ? 0.38 : 0.3}`, + })), +); const SwitchThumb = styled('span', { name: 'MuiSwitch', slot: 'Thumb', overridesResolver: (props, styles) => styles.thumb, -})(({ theme }) => ({ - boxShadow: (theme.vars || theme).shadows[1], - backgroundColor: 'currentColor', - width: 20, - height: 20, - borderRadius: '50%', -})); +})( + memoTheme(({ theme }) => ({ + boxShadow: (theme.vars || theme).shadows[1], + backgroundColor: 'currentColor', + width: 20, + height: 20, + borderRadius: '50%', + })), +); const Switch = React.forwardRef(function Switch(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiSwitch' }); diff --git a/packages/mui-material/src/Tab/Tab.js b/packages/mui-material/src/Tab/Tab.js index ed3fd8ac3a3cf6..4833faca922237 100644 --- a/packages/mui-material/src/Tab/Tab.js +++ b/packages/mui-material/src/Tab/Tab.js @@ -6,6 +6,7 @@ import composeClasses from '@mui/utils/composeClasses'; import ButtonBase from '../ButtonBase'; import capitalize from '../utils/capitalize'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import unsupportedProp from '../utils/unsupportedProp'; import tabClasses, { getTabUtilityClass } from './tabClasses'; @@ -49,140 +50,142 @@ const TabRoot = styled(ButtonBase, { }, ]; }, -})(({ theme }) => ({ - ...theme.typography.button, - maxWidth: 360, - minWidth: 90, - position: 'relative', - minHeight: 48, - flexShrink: 0, - padding: '12px 16px', - overflow: 'hidden', - whiteSpace: 'normal', - textAlign: 'center', - lineHeight: 1.25, - variants: [ - { - props: ({ ownerState }) => - ownerState.label && - (ownerState.iconPosition === 'top' || ownerState.iconPosition === 'bottom'), - style: { - flexDirection: 'column', - }, - }, - { - props: ({ ownerState }) => - ownerState.label && - ownerState.iconPosition !== 'top' && - ownerState.iconPosition !== 'bottom', - style: { - flexDirection: 'row', +})( + memoTheme(({ theme }) => ({ + ...theme.typography.button, + maxWidth: 360, + minWidth: 90, + position: 'relative', + minHeight: 48, + flexShrink: 0, + padding: '12px 16px', + overflow: 'hidden', + whiteSpace: 'normal', + textAlign: 'center', + lineHeight: 1.25, + variants: [ + { + props: ({ ownerState }) => + ownerState.label && + (ownerState.iconPosition === 'top' || ownerState.iconPosition === 'bottom'), + style: { + flexDirection: 'column', + }, }, - }, - { - props: ({ ownerState }) => ownerState.icon && ownerState.label, - style: { - minHeight: 72, - paddingTop: 9, - paddingBottom: 9, + { + props: ({ ownerState }) => + ownerState.label && + ownerState.iconPosition !== 'top' && + ownerState.iconPosition !== 'bottom', + style: { + flexDirection: 'row', + }, }, - }, - { - props: ({ ownerState, iconPosition }) => - ownerState.icon && ownerState.label && iconPosition === 'top', - style: { - [`& > .${tabClasses.icon}`]: { - marginBottom: 6, + { + props: ({ ownerState }) => ownerState.icon && ownerState.label, + style: { + minHeight: 72, + paddingTop: 9, + paddingBottom: 9, }, }, - }, - { - props: ({ ownerState, iconPosition }) => - ownerState.icon && ownerState.label && iconPosition === 'bottom', - style: { - [`& > .${tabClasses.icon}`]: { - marginTop: 6, + { + props: ({ ownerState, iconPosition }) => + ownerState.icon && ownerState.label && iconPosition === 'top', + style: { + [`& > .${tabClasses.icon}`]: { + marginBottom: 6, + }, }, }, - }, - { - props: ({ ownerState, iconPosition }) => - ownerState.icon && ownerState.label && iconPosition === 'start', - style: { - [`& > .${tabClasses.icon}`]: { - marginRight: theme.spacing(1), + { + props: ({ ownerState, iconPosition }) => + ownerState.icon && ownerState.label && iconPosition === 'bottom', + style: { + [`& > .${tabClasses.icon}`]: { + marginTop: 6, + }, }, }, - }, - { - props: ({ ownerState, iconPosition }) => - ownerState.icon && ownerState.label && iconPosition === 'end', - style: { - [`& > .${tabClasses.icon}`]: { - marginLeft: theme.spacing(1), + { + props: ({ ownerState, iconPosition }) => + ownerState.icon && ownerState.label && iconPosition === 'start', + style: { + [`& > .${tabClasses.icon}`]: { + marginRight: theme.spacing(1), + }, }, }, - }, - { - props: { - textColor: 'inherit', + { + props: ({ ownerState, iconPosition }) => + ownerState.icon && ownerState.label && iconPosition === 'end', + style: { + [`& > .${tabClasses.icon}`]: { + marginLeft: theme.spacing(1), + }, + }, }, - style: { - color: 'inherit', - opacity: 0.6, // same opacity as theme.palette.text.secondary - [`&.${tabClasses.selected}`]: { - opacity: 1, + { + props: { + textColor: 'inherit', }, - [`&.${tabClasses.disabled}`]: { - opacity: (theme.vars || theme).palette.action.disabledOpacity, + style: { + color: 'inherit', + opacity: 0.6, // same opacity as theme.palette.text.secondary + [`&.${tabClasses.selected}`]: { + opacity: 1, + }, + [`&.${tabClasses.disabled}`]: { + opacity: (theme.vars || theme).palette.action.disabledOpacity, + }, }, }, - }, - { - props: { - textColor: 'primary', - }, - style: { - color: (theme.vars || theme).palette.text.secondary, - [`&.${tabClasses.selected}`]: { - color: (theme.vars || theme).palette.primary.main, + { + props: { + textColor: 'primary', }, - [`&.${tabClasses.disabled}`]: { - color: (theme.vars || theme).palette.text.disabled, + style: { + color: (theme.vars || theme).palette.text.secondary, + [`&.${tabClasses.selected}`]: { + color: (theme.vars || theme).palette.primary.main, + }, + [`&.${tabClasses.disabled}`]: { + color: (theme.vars || theme).palette.text.disabled, + }, }, }, - }, - { - props: { - textColor: 'secondary', - }, - style: { - color: (theme.vars || theme).palette.text.secondary, - [`&.${tabClasses.selected}`]: { - color: (theme.vars || theme).palette.secondary.main, + { + props: { + textColor: 'secondary', }, - [`&.${tabClasses.disabled}`]: { - color: (theme.vars || theme).palette.text.disabled, + style: { + color: (theme.vars || theme).palette.text.secondary, + [`&.${tabClasses.selected}`]: { + color: (theme.vars || theme).palette.secondary.main, + }, + [`&.${tabClasses.disabled}`]: { + color: (theme.vars || theme).palette.text.disabled, + }, }, }, - }, - { - props: ({ ownerState }) => ownerState.fullWidth, - style: { - flexShrink: 1, - flexGrow: 1, - flexBasis: 0, - maxWidth: 'none', + { + props: ({ ownerState }) => ownerState.fullWidth, + style: { + flexShrink: 1, + flexGrow: 1, + flexBasis: 0, + maxWidth: 'none', + }, }, - }, - { - props: ({ ownerState }) => ownerState.wrapped, - style: { - fontSize: theme.typography.pxToRem(12), + { + props: ({ ownerState }) => ownerState.wrapped, + style: { + fontSize: theme.typography.pxToRem(12), + }, }, - }, - ], -})); + ], + })), +); const Tab = React.forwardRef(function Tab(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiTab' }); diff --git a/packages/mui-material/src/Table/Table.js b/packages/mui-material/src/Table/Table.js index 60ddc6b4626b95..245f66f1880c44 100644 --- a/packages/mui-material/src/Table/Table.js +++ b/packages/mui-material/src/Table/Table.js @@ -5,6 +5,7 @@ import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import TableContext from './TableContext'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import { getTableUtilityClass } from './tableClasses'; @@ -26,27 +27,29 @@ const TableRoot = styled('table', { return [styles.root, ownerState.stickyHeader && styles.stickyHeader]; }, -})(({ theme }) => ({ - display: 'table', - width: '100%', - borderCollapse: 'collapse', - borderSpacing: 0, - '& caption': { - ...theme.typography.body2, - padding: theme.spacing(2), - color: (theme.vars || theme).palette.text.secondary, - textAlign: 'left', - captionSide: 'bottom', - }, - variants: [ - { - props: ({ ownerState }) => ownerState.stickyHeader, - style: { - borderCollapse: 'separate', - }, +})( + memoTheme(({ theme }) => ({ + display: 'table', + width: '100%', + borderCollapse: 'collapse', + borderSpacing: 0, + '& caption': { + ...theme.typography.body2, + padding: theme.spacing(2), + color: (theme.vars || theme).palette.text.secondary, + textAlign: 'left', + captionSide: 'bottom', }, - ], -})); + variants: [ + { + props: ({ ownerState }) => ownerState.stickyHeader, + style: { + borderCollapse: 'separate', + }, + }, + ], + })), +); const defaultComponent = 'table'; diff --git a/packages/mui-material/src/TableCell/TableCell.js b/packages/mui-material/src/TableCell/TableCell.js index b4180528e0e370..62ca6d73a42932 100644 --- a/packages/mui-material/src/TableCell/TableCell.js +++ b/packages/mui-material/src/TableCell/TableCell.js @@ -8,6 +8,7 @@ import capitalize from '../utils/capitalize'; import TableContext from '../Table/TableContext'; import Tablelvl2Context from '../Table/Tablelvl2Context'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import tableCellClasses, { getTableCellUtilityClass } from './tableCellClasses'; @@ -43,127 +44,129 @@ const TableCellRoot = styled('td', { ownerState.stickyHeader && styles.stickyHeader, ]; }, -})(({ theme }) => ({ - ...theme.typography.body2, - display: 'table-cell', - verticalAlign: 'inherit', - // Workaround for a rendering bug with spanned columns in Chrome 62.0. - // Removes the alpha (sets it to 1), and lightens or darkens the theme color. - borderBottom: theme.vars - ? `1px solid ${theme.vars.palette.TableCell.border}` - : `1px solid +})( + memoTheme(({ theme }) => ({ + ...theme.typography.body2, + display: 'table-cell', + verticalAlign: 'inherit', + // Workaround for a rendering bug with spanned columns in Chrome 62.0. + // Removes the alpha (sets it to 1), and lightens or darkens the theme color. + borderBottom: theme.vars + ? `1px solid ${theme.vars.palette.TableCell.border}` + : `1px solid ${ theme.palette.mode === 'light' ? lighten(alpha(theme.palette.divider, 1), 0.88) : darken(alpha(theme.palette.divider, 1), 0.68) }`, - textAlign: 'left', - padding: 16, - variants: [ - { - props: { - variant: 'head', - }, - style: { - color: (theme.vars || theme).palette.text.primary, - lineHeight: theme.typography.pxToRem(24), - fontWeight: theme.typography.fontWeightMedium, - }, - }, - { - props: { - variant: 'body', - }, - style: { - color: (theme.vars || theme).palette.text.primary, - }, - }, - { - props: { - variant: 'footer', + textAlign: 'left', + padding: 16, + variants: [ + { + props: { + variant: 'head', + }, + style: { + color: (theme.vars || theme).palette.text.primary, + lineHeight: theme.typography.pxToRem(24), + fontWeight: theme.typography.fontWeightMedium, + }, }, - style: { - color: (theme.vars || theme).palette.text.secondary, - lineHeight: theme.typography.pxToRem(21), - fontSize: theme.typography.pxToRem(12), + { + props: { + variant: 'body', + }, + style: { + color: (theme.vars || theme).palette.text.primary, + }, }, - }, - { - props: { - size: 'small', + { + props: { + variant: 'footer', + }, + style: { + color: (theme.vars || theme).palette.text.secondary, + lineHeight: theme.typography.pxToRem(21), + fontSize: theme.typography.pxToRem(12), + }, }, - style: { - padding: '6px 16px', - [`&.${tableCellClasses.paddingCheckbox}`]: { - width: 24, // prevent the checkbox column from growing - padding: '0 12px 0 16px', - '& > *': { - padding: 0, + { + props: { + size: 'small', + }, + style: { + padding: '6px 16px', + [`&.${tableCellClasses.paddingCheckbox}`]: { + width: 24, // prevent the checkbox column from growing + padding: '0 12px 0 16px', + '& > *': { + padding: 0, + }, }, }, }, - }, - { - props: { - padding: 'checkbox', - }, - style: { - width: 48, // prevent the checkbox column from growing - padding: '0 0 0 4px', - }, - }, - { - props: { - padding: 'none', - }, - style: { - padding: 0, - }, - }, - { - props: { - align: 'left', - }, - style: { - textAlign: 'left', - }, - }, - { - props: { - align: 'center', + { + props: { + padding: 'checkbox', + }, + style: { + width: 48, // prevent the checkbox column from growing + padding: '0 0 0 4px', + }, }, - style: { - textAlign: 'center', + { + props: { + padding: 'none', + }, + style: { + padding: 0, + }, }, - }, - { - props: { - align: 'right', + { + props: { + align: 'left', + }, + style: { + textAlign: 'left', + }, }, - style: { - textAlign: 'right', - flexDirection: 'row-reverse', + { + props: { + align: 'center', + }, + style: { + textAlign: 'center', + }, }, - }, - { - props: { - align: 'justify', + { + props: { + align: 'right', + }, + style: { + textAlign: 'right', + flexDirection: 'row-reverse', + }, }, - style: { - textAlign: 'justify', + { + props: { + align: 'justify', + }, + style: { + textAlign: 'justify', + }, }, - }, - { - props: ({ ownerState }) => ownerState.stickyHeader, - style: { - position: 'sticky', - top: 0, - zIndex: 2, - backgroundColor: (theme.vars || theme).palette.background.default, + { + props: ({ ownerState }) => ownerState.stickyHeader, + style: { + position: 'sticky', + top: 0, + zIndex: 2, + backgroundColor: (theme.vars || theme).palette.background.default, + }, }, - }, - ], -})); + ], + })), +); /** * The component renders a `` element when the parent context is a header diff --git a/packages/mui-material/src/TablePagination/TablePagination.js b/packages/mui-material/src/TablePagination/TablePagination.js index ee8c1e7cd8b047..a1dcd83742388f 100644 --- a/packages/mui-material/src/TablePagination/TablePagination.js +++ b/packages/mui-material/src/TablePagination/TablePagination.js @@ -7,6 +7,7 @@ import chainPropTypes from '@mui/utils/chainPropTypes'; import composeClasses from '@mui/utils/composeClasses'; import isHostComponent from '../utils/isHostComponent'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import InputBase from '../InputBase'; import MenuItem from '../MenuItem'; @@ -21,15 +22,17 @@ const TablePaginationRoot = styled(TableCell, { name: 'MuiTablePagination', slot: 'Root', overridesResolver: (props, styles) => styles.root, -})(({ theme }) => ({ - overflow: 'auto', - color: (theme.vars || theme).palette.text.primary, - fontSize: theme.typography.pxToRem(14), - // Increase the specificity to override TableCell. - '&:last-child': { - padding: 0, - }, -})); +})( + memoTheme(({ theme }) => ({ + overflow: 'auto', + color: (theme.vars || theme).palette.text.primary, + fontSize: theme.typography.pxToRem(14), + // Increase the specificity to override TableCell. + '&:last-child': { + padding: 0, + }, + })), +); const TablePaginationToolbar = styled(Toolbar, { name: 'MuiTablePagination', @@ -38,21 +41,23 @@ const TablePaginationToolbar = styled(Toolbar, { [`& .${tablePaginationClasses.actions}`]: styles.actions, ...styles.toolbar, }), -})(({ theme }) => ({ - minHeight: 52, - paddingRight: 2, - [`${theme.breakpoints.up('xs')} and (orientation: landscape)`]: { - minHeight: 52, - }, - [theme.breakpoints.up('sm')]: { +})( + memoTheme(({ theme }) => ({ minHeight: 52, paddingRight: 2, - }, - [`& .${tablePaginationClasses.actions}`]: { - flexShrink: 0, - marginLeft: 20, - }, -})); + [`${theme.breakpoints.up('xs')} and (orientation: landscape)`]: { + minHeight: 52, + }, + [theme.breakpoints.up('sm')]: { + minHeight: 52, + paddingRight: 2, + }, + [`& .${tablePaginationClasses.actions}`]: { + flexShrink: 0, + marginLeft: 20, + }, + })), +); const TablePaginationSpacer = styled('div', { name: 'MuiTablePagination', @@ -66,10 +71,12 @@ const TablePaginationSelectLabel = styled('p', { name: 'MuiTablePagination', slot: 'SelectLabel', overridesResolver: (props, styles) => styles.selectLabel, -})(({ theme }) => ({ - ...theme.typography.body2, - flexShrink: 0, -})); +})( + memoTheme(({ theme }) => ({ + ...theme.typography.body2, + flexShrink: 0, + })), +); const TablePaginationSelect = styled(Select, { name: 'MuiTablePagination', @@ -104,10 +111,12 @@ const TablePaginationDisplayedRows = styled('p', { name: 'MuiTablePagination', slot: 'DisplayedRows', overridesResolver: (props, styles) => styles.displayedRows, -})(({ theme }) => ({ - ...theme.typography.body2, - flexShrink: 0, -})); +})( + memoTheme(({ theme }) => ({ + ...theme.typography.body2, + flexShrink: 0, + })), +); function defaultLabelDisplayedRows({ from, to, count }) { return `${from}–${to} of ${count !== -1 ? count : `more than ${to}`}`; diff --git a/packages/mui-material/src/TableRow/TableRow.js b/packages/mui-material/src/TableRow/TableRow.js index eec9ee944c429c..af03616cb04a10 100644 --- a/packages/mui-material/src/TableRow/TableRow.js +++ b/packages/mui-material/src/TableRow/TableRow.js @@ -6,6 +6,7 @@ import composeClasses from '@mui/utils/composeClasses'; import { alpha } from '@mui/system/colorManipulator'; import Tablelvl2Context from '../Table/Tablelvl2Context'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import tableRowClasses, { getTableRowUtilityClass } from './tableRowClasses'; @@ -27,29 +28,31 @@ const TableRowRoot = styled('tr', { return [styles.root, ownerState.head && styles.head, ownerState.footer && styles.footer]; }, -})(({ theme }) => ({ - color: 'inherit', - display: 'table-row', - verticalAlign: 'middle', - // We disable the focus ring for mouse, touch and keyboard users. - outline: 0, - [`&.${tableRowClasses.hover}:hover`]: { - backgroundColor: (theme.vars || theme).palette.action.hover, - }, - [`&.${tableRowClasses.selected}`]: { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` - : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), - '&:hover': { +})( + memoTheme(({ theme }) => ({ + color: 'inherit', + display: 'table-row', + verticalAlign: 'middle', + // We disable the focus ring for mouse, touch and keyboard users. + outline: 0, + [`&.${tableRowClasses.hover}:hover`]: { + backgroundColor: (theme.vars || theme).palette.action.hover, + }, + [`&.${tableRowClasses.selected}`]: { backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` - : alpha( - theme.palette.primary.main, - theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, - ), + ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` + : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), + '&:hover': { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` + : alpha( + theme.palette.primary.main, + theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, + ), + }, }, - }, -})); + })), +); const defaultComponent = 'tr'; /** diff --git a/packages/mui-material/src/TableSortLabel/TableSortLabel.js b/packages/mui-material/src/TableSortLabel/TableSortLabel.js index dee42f5355b249..24001473257836 100644 --- a/packages/mui-material/src/TableSortLabel/TableSortLabel.js +++ b/packages/mui-material/src/TableSortLabel/TableSortLabel.js @@ -6,6 +6,7 @@ import * as React from 'react'; import ButtonBase from '../ButtonBase'; import ArrowDownwardIcon from '../internal/svg-icons/ArrowDownward'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import capitalize from '../utils/capitalize'; import tableSortLabelClasses, { getTableSortLabelUtilityClass } from './tableSortLabelClasses'; @@ -29,29 +30,31 @@ const TableSortLabelRoot = styled(ButtonBase, { return [styles.root, ownerState.active && styles.active]; }, -})(({ theme }) => ({ - cursor: 'pointer', - display: 'inline-flex', - justifyContent: 'flex-start', - flexDirection: 'inherit', - alignItems: 'center', - '&:focus': { - color: (theme.vars || theme).palette.text.secondary, - }, - '&:hover': { - color: (theme.vars || theme).palette.text.secondary, - [`& .${tableSortLabelClasses.icon}`]: { - opacity: 0.5, +})( + memoTheme(({ theme }) => ({ + cursor: 'pointer', + display: 'inline-flex', + justifyContent: 'flex-start', + flexDirection: 'inherit', + alignItems: 'center', + '&:focus': { + color: (theme.vars || theme).palette.text.secondary, }, - }, - [`&.${tableSortLabelClasses.active}`]: { - color: (theme.vars || theme).palette.text.primary, - [`& .${tableSortLabelClasses.icon}`]: { - opacity: 1, + '&:hover': { color: (theme.vars || theme).palette.text.secondary, + [`& .${tableSortLabelClasses.icon}`]: { + opacity: 0.5, + }, }, - }, -})); + [`&.${tableSortLabelClasses.active}`]: { + color: (theme.vars || theme).palette.text.primary, + [`& .${tableSortLabelClasses.icon}`]: { + opacity: 1, + color: (theme.vars || theme).palette.text.secondary, + }, + }, + })), +); const TableSortLabelIcon = styled('span', { name: 'MuiTableSortLabel', @@ -61,34 +64,36 @@ const TableSortLabelIcon = styled('span', { return [styles.icon, styles[`iconDirection${capitalize(ownerState.direction)}`]]; }, -})(({ theme }) => ({ - fontSize: 18, - marginRight: 4, - marginLeft: 4, - opacity: 0, - transition: theme.transitions.create(['opacity', 'transform'], { - duration: theme.transitions.duration.shorter, - }), - userSelect: 'none', - variants: [ - { - props: { - direction: 'desc', - }, - style: { - transform: 'rotate(0deg)', +})( + memoTheme(({ theme }) => ({ + fontSize: 18, + marginRight: 4, + marginLeft: 4, + opacity: 0, + transition: theme.transitions.create(['opacity', 'transform'], { + duration: theme.transitions.duration.shorter, + }), + userSelect: 'none', + variants: [ + { + props: { + direction: 'desc', + }, + style: { + transform: 'rotate(0deg)', + }, }, - }, - { - props: { - direction: 'asc', + { + props: { + direction: 'asc', + }, + style: { + transform: 'rotate(180deg)', + }, }, - style: { - transform: 'rotate(180deg)', - }, - }, - ], -})); + ], + })), +); /** * A button based label for placing inside `TableCell` for column sorting. diff --git a/packages/mui-material/src/Tabs/Tabs.js b/packages/mui-material/src/Tabs/Tabs.js index c250c4a5d8ae24..a982190157573c 100644 --- a/packages/mui-material/src/Tabs/Tabs.js +++ b/packages/mui-material/src/Tabs/Tabs.js @@ -8,6 +8,7 @@ import composeClasses from '@mui/utils/composeClasses'; import { useRtl } from '@mui/system/RtlProvider'; import useSlotProps from '@mui/utils/useSlotProps'; import { styled, useTheme } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import debounce from '../utils/debounce'; import animate from '../internal/animate'; @@ -112,31 +113,33 @@ const TabsRoot = styled('div', { ownerState.vertical && styles.vertical, ]; }, -})(({ theme }) => ({ - overflow: 'hidden', - minHeight: 48, - // Add iOS momentum scrolling for iOS < 13.0 - WebkitOverflowScrolling: 'touch', - display: 'flex', - variants: [ - { - props: ({ ownerState }) => ownerState.vertical, - style: { - flexDirection: 'column', +})( + memoTheme(({ theme }) => ({ + overflow: 'hidden', + minHeight: 48, + // Add iOS momentum scrolling for iOS < 13.0 + WebkitOverflowScrolling: 'touch', + display: 'flex', + variants: [ + { + props: ({ ownerState }) => ownerState.vertical, + style: { + flexDirection: 'column', + }, }, - }, - { - props: ({ ownerState }) => ownerState.scrollButtonsHideMobile, - style: { - [`& .${tabsClasses.scrollButtons}`]: { - [theme.breakpoints.down('sm')]: { - display: 'none', + { + props: ({ ownerState }) => ownerState.scrollButtonsHideMobile, + style: { + [`& .${tabsClasses.scrollButtons}`]: { + [theme.breakpoints.down('sm')]: { + display: 'none', + }, }, }, }, - }, - ], -})); + ], + })), +); const TabsScroller = styled('div', { name: 'MuiTabs', @@ -224,39 +227,41 @@ const TabsIndicator = styled('span', { name: 'MuiTabs', slot: 'Indicator', overridesResolver: (props, styles) => styles.indicator, -})(({ theme }) => ({ - position: 'absolute', - height: 2, - bottom: 0, - width: '100%', - transition: theme.transitions.create(), - variants: [ - { - props: { - indicatorColor: 'primary', - }, - style: { - backgroundColor: (theme.vars || theme).palette.primary.main, - }, - }, - { - props: { - indicatorColor: 'secondary', +})( + memoTheme(({ theme }) => ({ + position: 'absolute', + height: 2, + bottom: 0, + width: '100%', + transition: theme.transitions.create(), + variants: [ + { + props: { + indicatorColor: 'primary', + }, + style: { + backgroundColor: (theme.vars || theme).palette.primary.main, + }, }, - style: { - backgroundColor: (theme.vars || theme).palette.secondary.main, + { + props: { + indicatorColor: 'secondary', + }, + style: { + backgroundColor: (theme.vars || theme).palette.secondary.main, + }, }, - }, - { - props: ({ ownerState }) => ownerState.vertical, - style: { - height: '100%', - width: 2, - right: 0, + { + props: ({ ownerState }) => ownerState.vertical, + style: { + height: '100%', + width: 2, + right: 0, + }, }, - }, - ], -})); + ], + })), +); const TabsScrollbarSize = styled(ScrollbarSize)({ overflowX: 'auto', diff --git a/packages/mui-material/src/ToggleButton/ToggleButton.js b/packages/mui-material/src/ToggleButton/ToggleButton.js index 4515537658200d..92df06fcd7f0ae 100644 --- a/packages/mui-material/src/ToggleButton/ToggleButton.js +++ b/packages/mui-material/src/ToggleButton/ToggleButton.js @@ -9,6 +9,7 @@ import { alpha } from '@mui/system/colorManipulator'; import ButtonBase from '../ButtonBase'; import capitalize from '../utils/capitalize'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import toggleButtonClasses, { getToggleButtonUtilityClass } from './toggleButtonClasses'; import ToggleButtonGroupContext from '../ToggleButtonGroup/ToggleButtonGroupContext'; @@ -40,101 +41,103 @@ const ToggleButtonRoot = styled(ButtonBase, { return [styles.root, styles[`size${capitalize(ownerState.size)}`]]; }, -})(({ theme }) => ({ - ...theme.typography.button, - borderRadius: (theme.vars || theme).shape.borderRadius, - padding: 11, - border: `1px solid ${(theme.vars || theme).palette.divider}`, - color: (theme.vars || theme).palette.action.active, - [`&.${toggleButtonClasses.disabled}`]: { - color: (theme.vars || theme).palette.action.disabled, - border: `1px solid ${(theme.vars || theme).palette.action.disabledBackground}`, - }, - '&:hover': { - textDecoration: 'none', - // Reset on mouse devices - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.text.primaryChannel} / ${theme.vars.palette.action.hoverOpacity})` - : alpha(theme.palette.text.primary, theme.palette.action.hoverOpacity), - '@media (hover: none)': { - backgroundColor: 'transparent', +})( + memoTheme(({ theme }) => ({ + ...theme.typography.button, + borderRadius: (theme.vars || theme).shape.borderRadius, + padding: 11, + border: `1px solid ${(theme.vars || theme).palette.divider}`, + color: (theme.vars || theme).palette.action.active, + [`&.${toggleButtonClasses.disabled}`]: { + color: (theme.vars || theme).palette.action.disabled, + border: `1px solid ${(theme.vars || theme).palette.action.disabledBackground}`, }, - }, - variants: [ - { - props: { color: 'standard' }, - style: { - [`&.${toggleButtonClasses.selected}`]: { - color: (theme.vars || theme).palette.text.primary, - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.text.primaryChannel} / ${theme.vars.palette.action.selectedOpacity})` - : alpha(theme.palette.text.primary, theme.palette.action.selectedOpacity), - '&:hover': { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.text.primaryChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` - : alpha( - theme.palette.text.primary, - theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, - ), - // Reset on touch devices, it doesn't add specificity - '@media (hover: none)': { - backgroundColor: theme.vars - ? `rgba(${theme.vars.palette.text.primaryChannel} / ${theme.vars.palette.action.selectedOpacity})` - : alpha(theme.palette.text.primary, theme.palette.action.selectedOpacity), - }, - }, - }, + '&:hover': { + textDecoration: 'none', + // Reset on mouse devices + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette.text.primaryChannel} / ${theme.vars.palette.action.hoverOpacity})` + : alpha(theme.palette.text.primary, theme.palette.action.hoverOpacity), + '@media (hover: none)': { + backgroundColor: 'transparent', }, }, - ...Object.entries(theme.palette) - .filter(([, palette]) => palette && palette.main) - .map(([color]) => ({ - props: { color }, + variants: [ + { + props: { color: 'standard' }, style: { [`&.${toggleButtonClasses.selected}`]: { - color: (theme.vars || theme).palette[color].main, + color: (theme.vars || theme).palette.text.primary, backgroundColor: theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.selectedOpacity})` - : alpha(theme.palette[color].main, theme.palette.action.selectedOpacity), + ? `rgba(${theme.vars.palette.text.primaryChannel} / ${theme.vars.palette.action.selectedOpacity})` + : alpha(theme.palette.text.primary, theme.palette.action.selectedOpacity), '&:hover': { backgroundColor: theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` + ? `rgba(${theme.vars.palette.text.primaryChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` : alpha( - theme.palette[color].main, + theme.palette.text.primary, theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, ), // Reset on touch devices, it doesn't add specificity '@media (hover: none)': { backgroundColor: theme.vars - ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.selectedOpacity})` - : alpha(theme.palette[color].main, theme.palette.action.selectedOpacity), + ? `rgba(${theme.vars.palette.text.primaryChannel} / ${theme.vars.palette.action.selectedOpacity})` + : alpha(theme.palette.text.primary, theme.palette.action.selectedOpacity), }, }, }, }, - })), - { - props: { fullWidth: true }, - style: { - width: '100%', }, - }, - { - props: { size: 'small' }, - style: { - padding: 7, - fontSize: theme.typography.pxToRem(13), + ...Object.entries(theme.palette) + .filter(([, palette]) => palette && palette.main) + .map(([color]) => ({ + props: { color }, + style: { + [`&.${toggleButtonClasses.selected}`]: { + color: (theme.vars || theme).palette[color].main, + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.selectedOpacity})` + : alpha(theme.palette[color].main, theme.palette.action.selectedOpacity), + '&:hover': { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette[color].mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` + : alpha( + theme.palette[color].main, + theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity, + ), + // Reset on touch devices, it doesn't add specificity + '@media (hover: none)': { + backgroundColor: theme.vars + ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.selectedOpacity})` + : alpha(theme.palette[color].main, theme.palette.action.selectedOpacity), + }, + }, + }, + }, + })), + { + props: { fullWidth: true }, + style: { + width: '100%', + }, }, - }, - { - props: { size: 'large' }, - style: { - padding: 15, - fontSize: theme.typography.pxToRem(15), + { + props: { size: 'small' }, + style: { + padding: 7, + fontSize: theme.typography.pxToRem(13), + }, }, - }, - ], -})); + { + props: { size: 'large' }, + style: { + padding: 15, + fontSize: theme.typography.pxToRem(15), + }, + }, + ], + })), +); const ToggleButton = React.forwardRef(function ToggleButton(inProps, ref) { // props priority: `inProps` > `contextProps` > `themeDefaultProps` diff --git a/packages/mui-material/src/ToggleButtonGroup/ToggleButtonGroup.js b/packages/mui-material/src/ToggleButtonGroup/ToggleButtonGroup.js index a817027acf3fc2..c782232c1f3f26 100644 --- a/packages/mui-material/src/ToggleButtonGroup/ToggleButtonGroup.js +++ b/packages/mui-material/src/ToggleButtonGroup/ToggleButtonGroup.js @@ -6,6 +6,7 @@ import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import getValidReactChildren from '@mui/utils/getValidReactChildren'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import capitalize from '../utils/capitalize'; import toggleButtonGroupClasses, { @@ -55,73 +56,77 @@ const ToggleButtonGroupRoot = styled('div', { ownerState.fullWidth && styles.fullWidth, ]; }, -})(({ theme }) => ({ - display: 'inline-flex', - borderRadius: (theme.vars || theme).shape.borderRadius, - variants: [ - { - props: { orientation: 'vertical' }, - style: { - flexDirection: 'column', - [`& .${toggleButtonGroupClasses.grouped}`]: { - [`&.${toggleButtonGroupClasses.selected} + .${toggleButtonGroupClasses.grouped}.${toggleButtonGroupClasses.selected}`]: +})( + memoTheme(({ theme }) => ({ + display: 'inline-flex', + borderRadius: (theme.vars || theme).shape.borderRadius, + variants: [ + { + props: { orientation: 'vertical' }, + style: { + flexDirection: 'column', + [`& .${toggleButtonGroupClasses.grouped}`]: { + [`&.${toggleButtonGroupClasses.selected} + .${toggleButtonGroupClasses.grouped}.${toggleButtonGroupClasses.selected}`]: + { + borderTop: 0, + marginTop: 0, + }, + }, + [`& .${toggleButtonGroupClasses.firstButton},& .${toggleButtonGroupClasses.middleButton}`]: { - borderTop: 0, - marginTop: 0, + borderBottomLeftRadius: 0, + borderBottomRightRadius: 0, + }, + [`& .${toggleButtonGroupClasses.lastButton},& .${toggleButtonGroupClasses.middleButton}`]: + { + marginTop: -1, + borderTop: '1px solid transparent', + borderTopLeftRadius: 0, + borderTopRightRadius: 0, + }, + [`& .${toggleButtonGroupClasses.lastButton}.${toggleButtonClasses.disabled},& .${toggleButtonGroupClasses.middleButton}.${toggleButtonClasses.disabled}`]: + { + borderTop: '1px solid transparent', }, }, - [`& .${toggleButtonGroupClasses.firstButton},& .${toggleButtonGroupClasses.middleButton}`]: - { - borderBottomLeftRadius: 0, - borderBottomRightRadius: 0, - }, - [`& .${toggleButtonGroupClasses.lastButton},& .${toggleButtonGroupClasses.middleButton}`]: { - marginTop: -1, - borderTop: '1px solid transparent', - borderTopLeftRadius: 0, - borderTopRightRadius: 0, - }, - [`& .${toggleButtonGroupClasses.lastButton}.${toggleButtonClasses.disabled},& .${toggleButtonGroupClasses.middleButton}.${toggleButtonClasses.disabled}`]: - { - borderTop: '1px solid transparent', - }, }, - }, - { - props: { fullWidth: true }, - style: { - width: '100%', + { + props: { fullWidth: true }, + style: { + width: '100%', + }, }, - }, - { - props: { orientation: 'horizontal' }, - style: { - [`& .${toggleButtonGroupClasses.grouped}`]: { - [`&.${toggleButtonGroupClasses.selected} + .${toggleButtonGroupClasses.grouped}.${toggleButtonGroupClasses.selected}`]: + { + props: { orientation: 'horizontal' }, + style: { + [`& .${toggleButtonGroupClasses.grouped}`]: { + [`&.${toggleButtonGroupClasses.selected} + .${toggleButtonGroupClasses.grouped}.${toggleButtonGroupClasses.selected}`]: + { + borderLeft: 0, + marginLeft: 0, + }, + }, + [`& .${toggleButtonGroupClasses.firstButton},& .${toggleButtonGroupClasses.middleButton}`]: { - borderLeft: 0, - marginLeft: 0, + borderTopRightRadius: 0, + borderBottomRightRadius: 0, + }, + [`& .${toggleButtonGroupClasses.lastButton},& .${toggleButtonGroupClasses.middleButton}`]: + { + marginLeft: -1, + borderLeft: '1px solid transparent', + borderTopLeftRadius: 0, + borderBottomLeftRadius: 0, + }, + [`& .${toggleButtonGroupClasses.lastButton}.${toggleButtonClasses.disabled},& .${toggleButtonGroupClasses.middleButton}.${toggleButtonClasses.disabled}`]: + { + borderLeft: '1px solid transparent', }, }, - [`& .${toggleButtonGroupClasses.firstButton},& .${toggleButtonGroupClasses.middleButton}`]: - { - borderTopRightRadius: 0, - borderBottomRightRadius: 0, - }, - [`& .${toggleButtonGroupClasses.lastButton},& .${toggleButtonGroupClasses.middleButton}`]: { - marginLeft: -1, - borderLeft: '1px solid transparent', - borderTopLeftRadius: 0, - borderBottomLeftRadius: 0, - }, - [`& .${toggleButtonGroupClasses.lastButton}.${toggleButtonClasses.disabled},& .${toggleButtonGroupClasses.middleButton}.${toggleButtonClasses.disabled}`]: - { - borderLeft: '1px solid transparent', - }, }, - }, - ], -})); + ], + })), +); const ToggleButtonGroup = React.forwardRef(function ToggleButtonGroup(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiToggleButtonGroup' }); diff --git a/packages/mui-material/src/Toolbar/Toolbar.js b/packages/mui-material/src/Toolbar/Toolbar.js index 3e6458f477c6f8..dbfde2fb54eb23 100644 --- a/packages/mui-material/src/Toolbar/Toolbar.js +++ b/packages/mui-material/src/Toolbar/Toolbar.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { styled } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import { getToolbarUtilityClass } from './toolbarClasses'; @@ -25,38 +26,40 @@ const ToolbarRoot = styled('div', { return [styles.root, !ownerState.disableGutters && styles.gutters, styles[ownerState.variant]]; }, -})(({ theme }) => ({ - position: 'relative', - display: 'flex', - alignItems: 'center', - variants: [ - { - props: ({ ownerState }) => !ownerState.disableGutters, - style: { - paddingLeft: theme.spacing(2), - paddingRight: theme.spacing(2), - [theme.breakpoints.up('sm')]: { - paddingLeft: theme.spacing(3), - paddingRight: theme.spacing(3), +})( + memoTheme(({ theme }) => ({ + position: 'relative', + display: 'flex', + alignItems: 'center', + variants: [ + { + props: ({ ownerState }) => !ownerState.disableGutters, + style: { + paddingLeft: theme.spacing(2), + paddingRight: theme.spacing(2), + [theme.breakpoints.up('sm')]: { + paddingLeft: theme.spacing(3), + paddingRight: theme.spacing(3), + }, }, }, - }, - { - props: { - variant: 'dense', - }, - style: { - minHeight: 48, + { + props: { + variant: 'dense', + }, + style: { + minHeight: 48, + }, }, - }, - { - props: { - variant: 'regular', + { + props: { + variant: 'regular', + }, + style: theme.mixins.toolbar, }, - style: theme.mixins.toolbar, - }, - ], -})); + ], + })), +); const Toolbar = React.forwardRef(function Toolbar(inProps, ref) { const props = useDefaultProps({ props: inProps, name: 'MuiToolbar' }); diff --git a/packages/mui-material/src/Tooltip/Tooltip.js b/packages/mui-material/src/Tooltip/Tooltip.js index d846a4126b7b4e..905679cc94c138 100644 --- a/packages/mui-material/src/Tooltip/Tooltip.js +++ b/packages/mui-material/src/Tooltip/Tooltip.js @@ -11,6 +11,7 @@ import isFocusVisible from '@mui/utils/isFocusVisible'; import appendOwnerState from '@mui/utils/appendOwnerState'; import getReactNodeRef from '@mui/utils/getReactNodeRef'; import { styled, useTheme } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import capitalize from '../utils/capitalize'; import Grow from '../Grow'; @@ -55,93 +56,95 @@ const TooltipPopper = styled(Popper, { !ownerState.open && styles.popperClose, ]; }, -})(({ theme }) => ({ - zIndex: (theme.vars || theme).zIndex.tooltip, - pointerEvents: 'none', - variants: [ - { - props: ({ ownerState }) => !ownerState.disableInteractive, - style: { - pointerEvents: 'auto', +})( + memoTheme(({ theme }) => ({ + zIndex: (theme.vars || theme).zIndex.tooltip, + pointerEvents: 'none', + variants: [ + { + props: ({ ownerState }) => !ownerState.disableInteractive, + style: { + pointerEvents: 'auto', + }, }, - }, - { - props: ({ open }) => !open, - style: { - pointerEvents: 'none', + { + props: ({ open }) => !open, + style: { + pointerEvents: 'none', + }, }, - }, - { - props: ({ ownerState }) => ownerState.arrow, - style: { - [`&[data-popper-placement*="bottom"] .${tooltipClasses.arrow}`]: { - top: 0, - marginTop: '-0.71em', - '&::before': { - transformOrigin: '0 100%', + { + props: ({ ownerState }) => ownerState.arrow, + style: { + [`&[data-popper-placement*="bottom"] .${tooltipClasses.arrow}`]: { + top: 0, + marginTop: '-0.71em', + '&::before': { + transformOrigin: '0 100%', + }, }, - }, - [`&[data-popper-placement*="top"] .${tooltipClasses.arrow}`]: { - bottom: 0, - marginBottom: '-0.71em', - '&::before': { - transformOrigin: '100% 0', + [`&[data-popper-placement*="top"] .${tooltipClasses.arrow}`]: { + bottom: 0, + marginBottom: '-0.71em', + '&::before': { + transformOrigin: '100% 0', + }, }, - }, - [`&[data-popper-placement*="right"] .${tooltipClasses.arrow}`]: { - height: '1em', - width: '0.71em', - '&::before': { - transformOrigin: '100% 100%', + [`&[data-popper-placement*="right"] .${tooltipClasses.arrow}`]: { + height: '1em', + width: '0.71em', + '&::before': { + transformOrigin: '100% 100%', + }, }, - }, - [`&[data-popper-placement*="left"] .${tooltipClasses.arrow}`]: { - height: '1em', - width: '0.71em', - '&::before': { - transformOrigin: '0 0', + [`&[data-popper-placement*="left"] .${tooltipClasses.arrow}`]: { + height: '1em', + width: '0.71em', + '&::before': { + transformOrigin: '0 0', + }, }, }, }, - }, - { - props: ({ ownerState }) => ownerState.arrow && !ownerState.isRtl, - style: { - [`&[data-popper-placement*="right"] .${tooltipClasses.arrow}`]: { - left: 0, - marginLeft: '-0.71em', + { + props: ({ ownerState }) => ownerState.arrow && !ownerState.isRtl, + style: { + [`&[data-popper-placement*="right"] .${tooltipClasses.arrow}`]: { + left: 0, + marginLeft: '-0.71em', + }, }, }, - }, - { - props: ({ ownerState }) => ownerState.arrow && !!ownerState.isRtl, - style: { - [`&[data-popper-placement*="right"] .${tooltipClasses.arrow}`]: { - right: 0, - marginRight: '-0.71em', + { + props: ({ ownerState }) => ownerState.arrow && !!ownerState.isRtl, + style: { + [`&[data-popper-placement*="right"] .${tooltipClasses.arrow}`]: { + right: 0, + marginRight: '-0.71em', + }, }, }, - }, - { - props: ({ ownerState }) => ownerState.arrow && !ownerState.isRtl, - style: { - [`&[data-popper-placement*="left"] .${tooltipClasses.arrow}`]: { - right: 0, - marginRight: '-0.71em', + { + props: ({ ownerState }) => ownerState.arrow && !ownerState.isRtl, + style: { + [`&[data-popper-placement*="left"] .${tooltipClasses.arrow}`]: { + right: 0, + marginRight: '-0.71em', + }, }, }, - }, - { - props: ({ ownerState }) => ownerState.arrow && !!ownerState.isRtl, - style: { - [`&[data-popper-placement*="left"] .${tooltipClasses.arrow}`]: { - left: 0, - marginLeft: '-0.71em', + { + props: ({ ownerState }) => ownerState.arrow && !!ownerState.isRtl, + style: { + [`&[data-popper-placement*="left"] .${tooltipClasses.arrow}`]: { + left: 0, + marginLeft: '-0.71em', + }, }, }, - }, - ], -})); + ], + })), +); const TooltipTooltip = styled('div', { name: 'MuiTooltip', @@ -156,134 +159,138 @@ const TooltipTooltip = styled('div', { styles[`tooltipPlacement${capitalize(ownerState.placement.split('-')[0])}`], ]; }, -})(({ theme }) => ({ - backgroundColor: theme.vars - ? theme.vars.palette.Tooltip.bg - : alpha(theme.palette.grey[700], 0.92), - borderRadius: (theme.vars || theme).shape.borderRadius, - color: (theme.vars || theme).palette.common.white, - fontFamily: theme.typography.fontFamily, - padding: '4px 8px', - fontSize: theme.typography.pxToRem(11), - maxWidth: 300, - margin: 2, - wordWrap: 'break-word', - fontWeight: theme.typography.fontWeightMedium, - [`.${tooltipClasses.popper}[data-popper-placement*="left"] &`]: { - transformOrigin: 'right center', - }, - [`.${tooltipClasses.popper}[data-popper-placement*="right"] &`]: { - transformOrigin: 'left center', - }, - [`.${tooltipClasses.popper}[data-popper-placement*="top"] &`]: { - transformOrigin: 'center bottom', - marginBottom: '14px', - }, - [`.${tooltipClasses.popper}[data-popper-placement*="bottom"] &`]: { - transformOrigin: 'center top', - marginTop: '14px', - }, - variants: [ - { - props: ({ ownerState }) => ownerState.arrow, - style: { - position: 'relative', - margin: 0, - }, +})( + memoTheme(({ theme }) => ({ + backgroundColor: theme.vars + ? theme.vars.palette.Tooltip.bg + : alpha(theme.palette.grey[700], 0.92), + borderRadius: (theme.vars || theme).shape.borderRadius, + color: (theme.vars || theme).palette.common.white, + fontFamily: theme.typography.fontFamily, + padding: '4px 8px', + fontSize: theme.typography.pxToRem(11), + maxWidth: 300, + margin: 2, + wordWrap: 'break-word', + fontWeight: theme.typography.fontWeightMedium, + [`.${tooltipClasses.popper}[data-popper-placement*="left"] &`]: { + transformOrigin: 'right center', }, - { - props: ({ ownerState }) => ownerState.touch, - style: { - padding: '8px 16px', - fontSize: theme.typography.pxToRem(14), - lineHeight: `${round(16 / 14)}em`, - fontWeight: theme.typography.fontWeightRegular, - }, + [`.${tooltipClasses.popper}[data-popper-placement*="right"] &`]: { + transformOrigin: 'left center', }, - { - props: ({ ownerState }) => !ownerState.isRtl, - style: { - [`.${tooltipClasses.popper}[data-popper-placement*="left"] &`]: { - marginRight: '14px', - }, - [`.${tooltipClasses.popper}[data-popper-placement*="right"] &`]: { - marginLeft: '14px', - }, - }, + [`.${tooltipClasses.popper}[data-popper-placement*="top"] &`]: { + transformOrigin: 'center bottom', + marginBottom: '14px', }, - { - props: ({ ownerState }) => !ownerState.isRtl && ownerState.touch, - style: { - [`.${tooltipClasses.popper}[data-popper-placement*="left"] &`]: { - marginRight: '24px', + [`.${tooltipClasses.popper}[data-popper-placement*="bottom"] &`]: { + transformOrigin: 'center top', + marginTop: '14px', + }, + variants: [ + { + props: ({ ownerState }) => ownerState.arrow, + style: { + position: 'relative', + margin: 0, }, - [`.${tooltipClasses.popper}[data-popper-placement*="right"] &`]: { - marginLeft: '24px', + }, + { + props: ({ ownerState }) => ownerState.touch, + style: { + padding: '8px 16px', + fontSize: theme.typography.pxToRem(14), + lineHeight: `${round(16 / 14)}em`, + fontWeight: theme.typography.fontWeightRegular, }, }, - }, - { - props: ({ ownerState }) => !!ownerState.isRtl, - style: { - [`.${tooltipClasses.popper}[data-popper-placement*="left"] &`]: { - marginLeft: '14px', + { + props: ({ ownerState }) => !ownerState.isRtl, + style: { + [`.${tooltipClasses.popper}[data-popper-placement*="left"] &`]: { + marginRight: '14px', + }, + [`.${tooltipClasses.popper}[data-popper-placement*="right"] &`]: { + marginLeft: '14px', + }, }, - [`.${tooltipClasses.popper}[data-popper-placement*="right"] &`]: { - marginRight: '14px', + }, + { + props: ({ ownerState }) => !ownerState.isRtl && ownerState.touch, + style: { + [`.${tooltipClasses.popper}[data-popper-placement*="left"] &`]: { + marginRight: '24px', + }, + [`.${tooltipClasses.popper}[data-popper-placement*="right"] &`]: { + marginLeft: '24px', + }, }, }, - }, - { - props: ({ ownerState }) => !!ownerState.isRtl && ownerState.touch, - style: { - [`.${tooltipClasses.popper}[data-popper-placement*="left"] &`]: { - marginLeft: '24px', + { + props: ({ ownerState }) => !!ownerState.isRtl, + style: { + [`.${tooltipClasses.popper}[data-popper-placement*="left"] &`]: { + marginLeft: '14px', + }, + [`.${tooltipClasses.popper}[data-popper-placement*="right"] &`]: { + marginRight: '14px', + }, }, - [`.${tooltipClasses.popper}[data-popper-placement*="right"] &`]: { - marginRight: '24px', + }, + { + props: ({ ownerState }) => !!ownerState.isRtl && ownerState.touch, + style: { + [`.${tooltipClasses.popper}[data-popper-placement*="left"] &`]: { + marginLeft: '24px', + }, + [`.${tooltipClasses.popper}[data-popper-placement*="right"] &`]: { + marginRight: '24px', + }, }, }, - }, - { - props: ({ ownerState }) => ownerState.touch, - style: { - [`.${tooltipClasses.popper}[data-popper-placement*="top"] &`]: { - marginBottom: '24px', + { + props: ({ ownerState }) => ownerState.touch, + style: { + [`.${tooltipClasses.popper}[data-popper-placement*="top"] &`]: { + marginBottom: '24px', + }, }, }, - }, - { - props: ({ ownerState }) => ownerState.touch, - style: { - [`.${tooltipClasses.popper}[data-popper-placement*="bottom"] &`]: { - marginTop: '24px', + { + props: ({ ownerState }) => ownerState.touch, + style: { + [`.${tooltipClasses.popper}[data-popper-placement*="bottom"] &`]: { + marginTop: '24px', + }, }, }, - }, - ], -})); + ], + })), +); const TooltipArrow = styled('span', { name: 'MuiTooltip', slot: 'Arrow', overridesResolver: (props, styles) => styles.arrow, -})(({ theme }) => ({ - overflow: 'hidden', - position: 'absolute', - width: '1em', - height: '0.71em' /* = width / sqrt(2) = (length of the hypotenuse) */, - boxSizing: 'border-box', - color: theme.vars ? theme.vars.palette.Tooltip.bg : alpha(theme.palette.grey[700], 0.9), - '&::before': { - content: '""', - margin: 'auto', - display: 'block', - width: '100%', - height: '100%', - backgroundColor: 'currentColor', - transform: 'rotate(45deg)', - }, -})); +})( + memoTheme(({ theme }) => ({ + overflow: 'hidden', + position: 'absolute', + width: '1em', + height: '0.71em' /* = width / sqrt(2) = (length of the hypotenuse) */, + boxSizing: 'border-box', + color: theme.vars ? theme.vars.palette.Tooltip.bg : alpha(theme.palette.grey[700], 0.9), + '&::before': { + content: '""', + margin: 'auto', + display: 'block', + width: '100%', + height: '100%', + backgroundColor: 'currentColor', + transform: 'rotate(45deg)', + }, + })), +); let hystersisOpen = false; const hystersisTimer = new Timeout(); diff --git a/packages/mui-material/src/Typography/Typography.js b/packages/mui-material/src/Typography/Typography.js index 9ba5bdffcec985..fca09495689487 100644 --- a/packages/mui-material/src/Typography/Typography.js +++ b/packages/mui-material/src/Typography/Typography.js @@ -4,6 +4,7 @@ import PropTypes from 'prop-types'; import clsx from 'clsx'; import composeClasses from '@mui/utils/composeClasses'; import { styled, internal_createExtendSxProp } from '../zero-styled'; +import memoTheme from '../utils/memoTheme'; import { useDefaultProps } from '../DefaultPropsProvider'; import capitalize from '../utils/capitalize'; import { getTypographyUtilityClass } from './typographyClasses'; @@ -54,70 +55,72 @@ export const TypographyRoot = styled('span', { ownerState.paragraph && styles.paragraph, ]; }, -})(({ theme }) => ({ - margin: 0, - variants: [ - { - props: { - variant: 'inherit', - }, - style: { - // Some elements, like