Skip to content

Commit

Permalink
[button] Add missing customize points for span (#43436)
Browse files Browse the repository at this point in the history
  • Loading branch information
oliviertassinari authored Aug 26, 2024
1 parent ea34b29 commit 4a85313
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 119 deletions.
6 changes: 6 additions & 0 deletions docs/pages/material-ui/api/loading-button.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
4 changes: 4 additions & 0 deletions docs/translations/api-docs/loading-button/loading-button.json
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@
"conditions": "supplied and <code>size=\"small\"</code>",
"deprecationInfo": "Combine the <a href=\"/material-ui/api/button/#button-classes-icon\">.MuiButton-icon</a> and <a href=\"/material-ui/api/button/#button-classes-sizeSmall\">.MuiButtonSizeSmall</a> classes instead. See <a href=\"/material-ui/migration/migrating-from-deprecated-apis/\">Migrating from deprecated APIs</a> 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",
Expand Down
2 changes: 2 additions & 0 deletions packages/mui-lab/src/LoadingButton/LoadingButton.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export interface LoadingButtonOwnProps {
classes?: Partial<ButtonClasses> & {
/** 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. */
Expand Down
260 changes: 141 additions & 119 deletions packages/mui-lab/src/LoadingButton/LoadingButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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: [
Expand Down Expand Up @@ -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',
Expand All @@ -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);
Expand Down Expand Up @@ -242,15 +264,15 @@ const LoadingButton = React.forwardRef(function LoadingButton(inProps, ref) {
ownerState={ownerState}
>
{ownerState.loadingPosition === 'end' ? (
<span>{children}</span>
<LoadingButtonLabel className={classes.label}>{children}</LoadingButtonLabel>
) : (
loadingButtonLoadingIndicator
)}

{ownerState.loadingPosition === 'end' ? (
loadingButtonLoadingIndicator
) : (
<span>{children}</span>
<LoadingButtonLabel className={classes.label}>{children}</LoadingButtonLabel>
)}
</LoadingButtonRoot>
);
Expand Down
3 changes: 3 additions & 0 deletions packages/mui-lab/src/LoadingButton/loadingButtonClasses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand All @@ -28,6 +30,7 @@ export function getLoadingButtonUtilityClass(slot: string): string {

const loadingButtonClasses: LoadingButtonClasses = generateUtilityClasses('MuiLoadingButton', [
'root',
'label',
'loading',
'loadingIndicator',
'loadingIndicatorCenter',
Expand Down
1 change: 1 addition & 0 deletions packages/mui-material/src/utils/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
1 change: 1 addition & 0 deletions packages/mui-material/src/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down

0 comments on commit 4a85313

Please sign in to comment.