Skip to content

Commit

Permalink
[material-ui][IconButton] Set default loading to null (#45057)
Browse files Browse the repository at this point in the history
  • Loading branch information
siriwatknp authored Jan 20, 2025
1 parent a32b12a commit 33ce030
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 9 deletions.
8 changes: 7 additions & 1 deletion docs/pages/material-ui/api/icon-button.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
},
"default": "false"
},
"loading": { "type": { "name": "bool" }, "default": "false" },
"loading": { "type": { "name": "bool" }, "default": "null" },
"loadingIndicator": {
"type": { "name": "node" },
"default": "<CircularProgress color=\"inherit\" size={16} />"
Expand Down Expand Up @@ -117,6 +117,12 @@
"description": "Styles applied to the loadingIndicator element.",
"isGlobal": false
},
{
"key": "loadingWrapper",
"className": "MuiIconButton-loadingWrapper",
"description": "Styles applied to the loadingWrapper element.",
"isGlobal": false
},
{
"key": "root",
"className": "MuiIconButton-root",
Expand Down
6 changes: 5 additions & 1 deletion docs/translations/api-docs/icon-button/icon-button.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"description": "If given, uses a negative margin to counteract the padding on one side (this is often helpful for aligning the left or right side of the icon with content above or below, without ruining the border size and shape)."
},
"loading": {
"description": "If <code>true</code>, the loading indicator is visible and the button is disabled."
"description": "If <code>true</code>, the loading indicator is visible and the button is disabled. If <code>true \\| false</code>, the loading wrapper is always rendered before the children to prevent <a href=\"https://github.com/mui/material-ui/issues/27853\">Google Translation Crash</a>."
},
"loadingIndicator": {
"description": "Element placed before the children if the button is in loading state. The node should contain an element with <code>role=&quot;progressbar&quot;</code> with an accessible name. By default, it renders a <code>CircularProgress</code> that is labeled by the button itself."
Expand Down Expand Up @@ -89,6 +89,10 @@
"description": "Styles applied to {{nodeName}}.",
"nodeName": "the loadingIndicator element"
},
"loadingWrapper": {
"description": "Styles applied to {{nodeName}}.",
"nodeName": "the loadingWrapper element"
},
"root": { "description": "Styles applied to the root element." },
"sizeLarge": {
"description": "Styles applied to {{nodeName}} if {{conditions}}.",
Expand Down
5 changes: 3 additions & 2 deletions packages/mui-material/src/IconButton/IconButton.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ export interface IconButtonOwnProps {
edge?: 'start' | 'end' | false;
/**
* If `true`, the loading indicator is visible and the button is disabled.
* @default false
* If `true | false`, the loading wrapper is always rendered before the children to prevent [Google Translation Crash](https://github.com/mui/material-ui/issues/27853).
* @default null
*/
loading?: boolean;
loading?: boolean | null;
/**
* Element placed before the children if the button is in loading state.
* The node should contain an element with `role="progressbar"` with an accessible name.
Expand Down
17 changes: 12 additions & 5 deletions packages/mui-material/src/IconButton/IconButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const useUtilityClasses = (ownerState) => {
`size${capitalize(size)}`,
],
loadingIndicator: ['loadingIndicator'],
loadingWrapper: ['loadingWrapper'],
};

return composeClasses(slots, getIconButtonUtilityClass, classes);
Expand Down Expand Up @@ -181,7 +182,7 @@ const IconButton = React.forwardRef(function IconButton(inProps, ref) {
disableFocusRipple = false,
size = 'medium',
id: idProp,
loading = false,
loading = null,
loadingIndicator: loadingIndicatorProp,
...other
} = props;
Expand Down Expand Up @@ -215,9 +216,14 @@ const IconButton = React.forwardRef(function IconButton(inProps, ref) {
{...other}
ownerState={ownerState}
>
<IconButtonLoadingIndicator className={classes.loadingIndicator} ownerState={ownerState}>
{loading && loadingIndicator}
</IconButtonLoadingIndicator>
{typeof loading === 'boolean' && (
// use plain HTML span to minimize the runtime overhead
<span className={classes.loadingWrapper} style={{ display: 'contents' }}>
<IconButtonLoadingIndicator className={classes.loadingIndicator} ownerState={ownerState}>
{loading && loadingIndicator}
</IconButtonLoadingIndicator>
</span>
)}
{children}
</IconButtonRoot>
);
Expand Down Expand Up @@ -307,7 +313,8 @@ IconButton.propTypes /* remove-proptypes */ = {
id: PropTypes.string,
/**
* If `true`, the loading indicator is visible and the button is disabled.
* @default false
* If `true | false`, the loading wrapper is always rendered before the children to prevent [Google Translation Crash](https://github.com/mui/material-ui/issues/27853).
* @default null
*/
loading: PropTypes.bool,
/**
Expand Down
8 changes: 8 additions & 0 deletions packages/mui-material/src/IconButton/IconButton.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,14 @@ describe('<IconButton />', () => {
});

describe('prop: loading', () => {
it('does not render the wrapper by default', () => {
render(<IconButton />);

const button = screen.getByRole('button');
expect(button).to.have.property('disabled', false);
expect(button.firstChild).to.equal(null);
});

it('disables the button', () => {
render(<IconButton loading />);

Expand Down
3 changes: 3 additions & 0 deletions packages/mui-material/src/IconButton/iconButtonClasses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export interface IconButtonClasses {
loading: string;
/** Styles applied to the loadingIndicator element. */
loadingIndicator: string;
/** Styles applied to the loadingWrapper element. */
loadingWrapper: string;
}

export type IconButtonClassKey = keyof IconButtonClasses;
Expand All @@ -59,6 +61,7 @@ const iconButtonClasses: IconButtonClasses = generateUtilityClasses('MuiIconButt
'sizeLarge',
'loading',
'loadingIndicator',
'loadingWrapper',
]);

export default iconButtonClasses;

0 comments on commit 33ce030

Please sign in to comment.