diff --git a/docs/pages/material-ui/api/loading-button.json b/docs/pages/material-ui/api/loading-button.json
index 555074c1ad71b8..8155927a65f266 100644
--- a/docs/pages/material-ui/api/loading-button.json
+++ b/docs/pages/material-ui/api/loading-button.json
@@ -217,6 +217,12 @@
"isGlobal": false,
"isDeprecated": true
},
+ {
+ "key": "label",
+ "className": "MuiLoadingButton-label",
+ "description": "Styles applied to the span element that wraps the children.",
+ "isGlobal": false
+ },
{
"key": "loading",
"className": "MuiLoadingButton-loading",
diff --git a/docs/translations/api-docs/loading-button/loading-button.json b/docs/translations/api-docs/loading-button/loading-button.json
index 893accc5f50691..9babb1623d14c9 100644
--- a/docs/translations/api-docs/loading-button/loading-button.json
+++ b/docs/translations/api-docs/loading-button/loading-button.json
@@ -168,6 +168,10 @@
"conditions": "supplied and size=\"small\"
",
"deprecationInfo": "Combine the .MuiButton-icon and .MuiButtonSizeSmall classes instead. See Migrating from deprecated APIs for more details."
},
+ "label": {
+ "description": "Styles applied to {{nodeName}}.",
+ "nodeName": "the span element that wraps the children"
+ },
"loading": {
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
"nodeName": "the root element",
diff --git a/packages/mui-lab/src/LoadingButton/LoadingButton.d.ts b/packages/mui-lab/src/LoadingButton/LoadingButton.d.ts
index 6dc2341f9f5265..90351bc0f2a15c 100644
--- a/packages/mui-lab/src/LoadingButton/LoadingButton.d.ts
+++ b/packages/mui-lab/src/LoadingButton/LoadingButton.d.ts
@@ -10,6 +10,8 @@ export interface LoadingButtonOwnProps {
classes?: Partial & {
/** Styles applied to the root element. */
root?: string;
+ /** Styles applied to the span element that wraps the children. */
+ label?: string;
/** Styles applied to the root element if `loading={true}`. */
loading?: string;
/** Styles applied to the loadingIndicator element. */
diff --git a/packages/mui-lab/src/LoadingButton/LoadingButton.js b/packages/mui-lab/src/LoadingButton/LoadingButton.js
index 13d5a9aec21df1..12f0997a888d09 100644
--- a/packages/mui-lab/src/LoadingButton/LoadingButton.js
+++ b/packages/mui-lab/src/LoadingButton/LoadingButton.js
@@ -2,7 +2,11 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { chainPropTypes } from '@mui/utils';
-import { capitalize, unstable_useId as useId } from '@mui/material/utils';
+import {
+ capitalize,
+ unstable_useId as useId,
+ unstable_memoTheme as memoTheme,
+} from '@mui/material/utils';
import { unstable_composeClasses as composeClasses } from '@mui/base';
import { useDefaultProps } from '@mui/material/DefaultPropsProvider';
import Button from '@mui/material/Button';
@@ -17,6 +21,7 @@ const useUtilityClasses = (ownerState) => {
const slots = {
root: ['root', loading && 'loading'],
+ label: ['label'],
startIcon: [loading && `startIconLoading${capitalize(loadingPosition)}`],
endIcon: [loading && `endIconLoading${capitalize(loadingPosition)}`],
loadingIndicator: [
@@ -51,56 +56,59 @@ const LoadingButtonRoot = styled(Button, {
},
];
},
-})(({ theme }) => ({
- [`& .${loadingButtonClasses.startIconLoadingStart}, & .${loadingButtonClasses.endIconLoadingEnd}`]:
- {
- transition: theme.transitions.create(['opacity'], {
- duration: theme.transitions.duration.short,
- }),
- opacity: 0,
- },
- variants: [
- {
- props: {
- loadingPosition: 'center',
- },
- style: {
- transition: theme.transitions.create(['background-color', 'box-shadow', 'border-color'], {
+})(
+ memoTheme(({ theme }) => ({
+ display: 'inline-flex',
+ [`& .${loadingButtonClasses.startIconLoadingStart}, & .${loadingButtonClasses.endIconLoadingEnd}`]:
+ {
+ transition: theme.transitions.create(['opacity'], {
duration: theme.transitions.duration.short,
}),
- [`&.${loadingButtonClasses.loading}`]: {
- color: 'transparent',
- },
+ opacity: 0,
},
- },
- {
- props: ({ ownerState }) => ownerState.loadingPosition === 'start' && ownerState.fullWidth,
- style: {
- [`& .${loadingButtonClasses.startIconLoadingStart}, & .${loadingButtonClasses.endIconLoadingEnd}`]:
- {
- transition: theme.transitions.create(['opacity'], {
- duration: theme.transitions.duration.short,
- }),
- opacity: 0,
- marginRight: -8,
+ variants: [
+ {
+ props: {
+ loadingPosition: 'center',
+ },
+ style: {
+ transition: theme.transitions.create(['background-color', 'box-shadow', 'border-color'], {
+ duration: theme.transitions.duration.short,
+ }),
+ [`&.${loadingButtonClasses.loading}`]: {
+ color: 'transparent',
},
+ },
},
- },
- {
- props: ({ ownerState }) => ownerState.loadingPosition === 'end' && ownerState.fullWidth,
- style: {
- [`& .${loadingButtonClasses.startIconLoadingStart}, & .${loadingButtonClasses.endIconLoadingEnd}`]:
- {
- transition: theme.transitions.create(['opacity'], {
- duration: theme.transitions.duration.short,
- }),
- opacity: 0,
- marginLeft: -8,
- },
+ {
+ props: ({ ownerState }) => ownerState.loadingPosition === 'start' && ownerState.fullWidth,
+ style: {
+ [`& .${loadingButtonClasses.startIconLoadingStart}, & .${loadingButtonClasses.endIconLoadingEnd}`]:
+ {
+ transition: theme.transitions.create(['opacity'], {
+ duration: theme.transitions.duration.short,
+ }),
+ opacity: 0,
+ marginRight: -8,
+ },
+ },
+ },
+ {
+ props: ({ ownerState }) => ownerState.loadingPosition === 'end' && ownerState.fullWidth,
+ style: {
+ [`& .${loadingButtonClasses.startIconLoadingStart}, & .${loadingButtonClasses.endIconLoadingEnd}`]:
+ {
+ transition: theme.transitions.create(['opacity'], {
+ duration: theme.transitions.duration.short,
+ }),
+ opacity: 0,
+ marginLeft: -8,
+ },
+ },
},
- },
- ],
-}));
+ ],
+ })),
+);
const LoadingButtonLoadingIndicator = styled('span', {
name: 'MuiLoadingButton',
@@ -112,87 +120,101 @@ const LoadingButtonLoadingIndicator = styled('span', {
styles[`loadingIndicator${capitalize(ownerState.loadingPosition)}`],
];
},
-})(({ theme }) => ({
- position: 'absolute',
- visibility: 'visible',
- display: 'flex',
- variants: [
- {
- props: {
- loadingPosition: 'start',
- size: 'small',
- },
- style: {
- left: 10,
- },
- },
- {
- props: ({ loadingPosition, ownerState }) =>
- loadingPosition === 'start' && ownerState.size !== 'small',
- style: {
- left: 14,
- },
- },
- {
- props: {
- variant: 'text',
- loadingPosition: 'start',
- },
- style: {
- left: 6,
- },
- },
- {
- props: {
- loadingPosition: 'center',
+})(
+ memoTheme(({ theme }) => ({
+ position: 'absolute',
+ visibility: 'visible',
+ display: 'flex',
+ variants: [
+ {
+ props: {
+ loadingPosition: 'start',
+ size: 'small',
+ },
+ style: {
+ left: 10,
+ },
},
- style: {
- left: '50%',
- transform: 'translate(-50%)',
- color: (theme.vars || theme).palette.action.disabled,
+ {
+ props: ({ loadingPosition, ownerState }) =>
+ loadingPosition === 'start' && ownerState.size !== 'small',
+ style: {
+ left: 14,
+ },
},
- },
- {
- props: {
- loadingPosition: 'end',
- size: 'small',
+ {
+ props: {
+ variant: 'text',
+ loadingPosition: 'start',
+ },
+ style: {
+ left: 6,
+ },
},
- style: {
- right: 10,
+ {
+ props: {
+ loadingPosition: 'center',
+ },
+ style: {
+ left: '50%',
+ transform: 'translate(-50%)',
+ color: (theme.vars || theme).palette.action.disabled,
+ },
},
- },
- {
- props: ({ loadingPosition, ownerState }) =>
- loadingPosition === 'end' && ownerState.size !== 'small',
- style: {
- right: 14,
+ {
+ props: {
+ loadingPosition: 'end',
+ size: 'small',
+ },
+ style: {
+ right: 10,
+ },
},
- },
- {
- props: {
- variant: 'text',
- loadingPosition: 'end',
+ {
+ props: ({ loadingPosition, ownerState }) =>
+ loadingPosition === 'end' && ownerState.size !== 'small',
+ style: {
+ right: 14,
+ },
},
- style: {
- right: 6,
+ {
+ props: {
+ variant: 'text',
+ loadingPosition: 'end',
+ },
+ style: {
+ right: 6,
+ },
},
- },
- {
- props: ({ ownerState }) => ownerState.loadingPosition === 'start' && ownerState.fullWidth,
- style: {
- position: 'relative',
- left: -10,
+ {
+ props: ({ ownerState }) => ownerState.loadingPosition === 'start' && ownerState.fullWidth,
+ style: {
+ position: 'relative',
+ left: -10,
+ },
},
- },
- {
- props: ({ ownerState }) => ownerState.loadingPosition === 'end' && ownerState.fullWidth,
- style: {
- position: 'relative',
- right: -10,
+ {
+ props: ({ ownerState }) => ownerState.loadingPosition === 'end' && ownerState.fullWidth,
+ style: {
+ position: 'relative',
+ right: -10,
+ },
},
- },
- ],
-}));
+ ],
+ })),
+);
+
+const LoadingButtonLabel = styled('span', {
+ name: 'MuiLoadingButton',
+ slot: 'Label',
+ overridesResolver: (props, styles) => {
+ return [styles.label];
+ },
+})({
+ display: 'inherit',
+ alignItems: 'inherit',
+ justifyContent: 'inherit',
+});
const LoadingButton = React.forwardRef(function LoadingButton(inProps, ref) {
const contextProps = React.useContext(ButtonGroupContext);
@@ -242,7 +264,7 @@ const LoadingButton = React.forwardRef(function LoadingButton(inProps, ref) {
ownerState={ownerState}
>
{ownerState.loadingPosition === 'end' ? (
- {children}
+ {children}
) : (
loadingButtonLoadingIndicator
)}
@@ -250,7 +272,7 @@ const LoadingButton = React.forwardRef(function LoadingButton(inProps, ref) {
{ownerState.loadingPosition === 'end' ? (
loadingButtonLoadingIndicator
) : (
- {children}
+ {children}
)}
);
diff --git a/packages/mui-lab/src/LoadingButton/loadingButtonClasses.ts b/packages/mui-lab/src/LoadingButton/loadingButtonClasses.ts
index d4adaf87799f78..d6543a1fa86cab 100644
--- a/packages/mui-lab/src/LoadingButton/loadingButtonClasses.ts
+++ b/packages/mui-lab/src/LoadingButton/loadingButtonClasses.ts
@@ -4,6 +4,8 @@ import generateUtilityClasses from '@mui/utils/generateUtilityClasses';
export interface LoadingButtonClasses {
/** Styles applied to the root element. */
root: string;
+ /** Styles applied to the span element that wraps the children. */
+ label: string;
/** Styles applied to the root element if `loading={true}`. */
loading: string;
/** Styles applied to the loadingIndicator element. */
@@ -28,6 +30,7 @@ export function getLoadingButtonUtilityClass(slot: string): string {
const loadingButtonClasses: LoadingButtonClasses = generateUtilityClasses('MuiLoadingButton', [
'root',
+ 'label',
'loading',
'loadingIndicator',
'loadingIndicatorCenter',
diff --git a/packages/mui-material/src/utils/index.d.ts b/packages/mui-material/src/utils/index.d.ts
index 7ccd7522ee6ff5..ccba6bbec929e1 100644
--- a/packages/mui-material/src/utils/index.d.ts
+++ b/packages/mui-material/src/utils/index.d.ts
@@ -5,6 +5,7 @@ export { default as createSvgIcon } from './createSvgIcon';
export { default as debounce } from './debounce';
export { default as deprecatedPropType } from './deprecatedPropType';
export { default as isMuiElement } from './isMuiElement';
+export { default as unstable_memoTheme } from './memoTheme';
export { default as ownerDocument } from './ownerDocument';
export { default as ownerWindow } from './ownerWindow';
export { default as requirePropFactory } from './requirePropFactory';
diff --git a/packages/mui-material/src/utils/index.js b/packages/mui-material/src/utils/index.js
index 90b88322517ab1..a43e01cd154380 100644
--- a/packages/mui-material/src/utils/index.js
+++ b/packages/mui-material/src/utils/index.js
@@ -7,6 +7,7 @@ export { default as createSvgIcon } from './createSvgIcon';
export { default as debounce } from './debounce';
export { default as deprecatedPropType } from './deprecatedPropType';
export { default as isMuiElement } from './isMuiElement';
+export { default as unstable_memoTheme } from './memoTheme';
export { default as ownerDocument } from './ownerDocument';
export { default as ownerWindow } from './ownerWindow';
export { default as requirePropFactory } from './requirePropFactory';