-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Button] Add loading
prop
#44637
base: master
Are you sure you want to change the base?
[Button] Add loading
prop
#44637
Conversation
@oliviertassinari |
Netlify deploy preview
IconButton: parsed: +4.52% , gzip: +3.56% Bundle size reportDetails of bundle changes (Toolpad) |
Wouldn't it be better to automatically add the span if the loading prop has a boolean value (true/false), and don't add it if it has a nullish value. We can explain in the demos the usage. |
That's a nice suggestion. If I understand correctly, there is no need for the new prop, right. The default value of loading is |
Yes, the downside is that a component cannot alternative between supporting loading or not (at least in terms of working with Google translate). I think that's nice compromise. |
I like this approach 👍🏼 let's add a short explanation in the docs as well. |
…/button-loading3
This reverts commit f317e69.
@mnajdova @DiegoAndai Ready for review. |
@siriwatknp I’ve linked two issues in the description that should be closed when this PR merges, the same as in #44637. |
{...other} | ||
classes={classes} | ||
> | ||
{startIcon} | ||
{enableLoadingWrapper ? ( | ||
// use plain HTML span to minimize the runtime overhead | ||
<span className={classes.loadingWrapper} style={{ display: 'contents' }}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey Jun! Thanks for pickling this one back up again.
I think the loadingPosition
needs some work, see these examples: https://codesandbox.io/p/sandbox/44637-feedback-1-wtf45k
In these examples users would expect the loading indicator to position itself correctly.
loadingIndicatorCenter: string; | ||
/** Styles applied to the loadingIndicator element if `loadingPosition="start"`. */ | ||
loadingIndicatorStart: string; | ||
/** Styles applied to the loadingIndicator element if `loadingPosition="end"`. */ | ||
loadingIndicatorEnd: string; | ||
/** Styles applied to the endIcon element if `loading={true}` and `loadingPosition="end"`. */ | ||
endIconLoadingEnd: string; | ||
/** Styles applied to the startIcon element if `loading={true}` and `loadingPosition="start"`. */ | ||
startIconLoadingStart: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This goes against having atomic classes. I think a better approach would be having:
loadingPositionCenter
, loadingPositionStart
, loadingPositionEnd
classes applied to the root depending on the loadingPosition prop.
Which can be combined with other classes, for example
.loadingPositionStart .loadingIndicator { ... }
instead ofloadingIndicatorStart
.loadingPositionStart .startIcon { ... }
instead ofstartIconLoadingStart
Reducing these 5 classes into 3.
We should try to follow the rule of having one class per prop-value combination.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point. Removed.
The root cause is that there is no icon to provide the space for the loading. I fixed this by render a |
/** Styles applied to the loadingIndicator element if `loadingPosition="center"`. */ | ||
loadingIndicatorCenter: string; | ||
/** Styles applied to the loadingIndicator element if `loadingPosition="start"`. */ | ||
loadingIndicatorStart: string; | ||
/** Styles applied to the loadingIndicator element if `loadingPosition="end"`. */ | ||
loadingIndicatorEnd: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should be removed and replaced by
loadingPositionCenter
, loadingPositionStart
, loadingPositionEnd
, applied to the root. This would allow to do
.loadingPositionCenter .loadingIndicator { ... } // instead of loadingIndicatorCenter
// but also
.loadingPositionCenter .loadingWrapper { ... }
// or
.loadingPositionCenter .icon { ... }
This follows the prop-value class combination.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@siriwatknp the loadingPositionCenter
, loadingPositionStart
, and loadingPositionEnd
classes should be applied to the root. Otherwise, it won't be possible to compose it with the icon
, loadingWrapper
, or loadingIconPlaceholder
classes.
{...other} | ||
classes={classes} | ||
> | ||
{startIcon} | ||
{enableLoadingWrapper ? ( | ||
// use plain HTML span to minimize the runtime overhead | ||
<span className={classes.loadingWrapper} style={{ display: 'contents' }}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we move style={{ display: 'contents' }}
as well?
@DiegoAndai If you meant to move it to be styled components, I added a comment above it to keep that element as plain HTML for least overhead. Its purpose is to prevent google translate error, not for customization because it has |
import ShoppingCartIcon from '@mui/icons-material/ShoppingCartOutlined'; | ||
|
||
const CartBadge = styled(Badge)` | ||
.${badgeClasses.badge} { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.${badgeClasses.badge} { | |
&.${badgeClasses.badge} { |
@@ -113,12 +113,45 @@ Use `color` prop to apply theme color palette to component. | |||
|
|||
{{"demo": "IconButtonColors.js"}} | |||
|
|||
### Loading | |||
|
|||
Starting from [`v6.2.0`](https://github.com/mui/material-ui/releases/tag/v6.2.0), use `loading` prop to set icon buttons in a loading state and disable interactions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a note to update the version here and in other places before merging.
{ | ||
props: { | ||
loadingPosition: 'start', | ||
size: 'small', | ||
}, | ||
style: { | ||
left: 10, | ||
}, | ||
}, | ||
{ | ||
props: ({ loadingPosition, size }) => loadingPosition === 'start' && size !== 'small', | ||
style: { | ||
left: 14, | ||
}, | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would applying the base styles first work?
{
props: { loadingPosition: 'start' },
style: {
left: 14,
},
},
{
props: {
loadingPosition: 'start',
size: 'small',
},
style: {
left: 10,
},
},
I think this would make it more readable and maintainable. What do you think?
(The same applies to the other 'small'
size styles applied elsewhere in this PR.
Preview: https://deploy-preview-44637--material-ui.netlify.app/material-ui/react-button/#loading-2
Closes #42684
Closes #31235
Context
This PR build on top of the reverted #42987 by making the default value of
loading
to benull
to fix the problem with Google Translation Crash without introducing overhead of the loading wrapper to the existing projects.When the prop is
boolean
, a span always present as a wrapper regardless of the loading state:The reasons to go with this approach instead of wrapping children with a span are:
styled
.Note
When this PR is merged, the next release should be
v6.2.0