Skip to content
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

[IconButton] Implement a new edge prop #14758

Merged
merged 11 commits into from
Mar 9, 2019

Conversation

jedwards1211
Copy link
Contributor

@jedwards1211 jedwards1211 commented Mar 6, 2019

One of the most common things we all have to do with IconButtons is apply marginLeft: -12 or
marginRight: -12 to counteract the padding and fix the icon's horizontal alignment with content above or below. (It's common in your demos too)

It gets a bit tedious to fix every case with JSS styles. Let's make it easier for ourselves! ✨

With this PR, <IconButton align="left"> will apply marginLeft: -12 and align="right" will apply marginRight: -12. For size="small", it will use -3 for the margin instead.

@jedwards1211 jedwards1211 changed the title feat(IconButton): add align prop (shortcut for applying negative margin) [IconButton] add shortcut prop for applying negative margin to solve alignment issues Mar 6, 2019
@mui-pr-bot
Copy link

mui-pr-bot commented Mar 6, 2019

Details of bundle changes.

Comparing: 099bc5e...c81bf03

bundle parsed diff gzip diff prev parsed current parsed prev gzip current gzip
@material-ui/core +0.05% 🔺 +0.07% 🔺 362,378 362,562 92,048 92,116
@material-ui/core/Paper 0.00% 0.00% 68,773 68,773 20,155 20,155
@material-ui/core/Paper.esm 0.00% 0.00% 63,294 63,294 19,274 19,274
@material-ui/core/Popper 0.00% 0.00% 30,458 30,458 10,557 10,557
@material-ui/core/styles/createMuiTheme 0.00% 0.00% 17,284 17,284 5,697 5,697
@material-ui/core/useMediaQuery 0.00% 0.00% 2,486 2,486 1,049 1,049
@material-ui/lab 0.00% 0.00% 170,613 170,613 50,038 50,038
@material-ui/styles 0.00% 0.00% 57,118 57,118 16,253 16,253
@material-ui/system 0.00% 0.00% 17,041 17,041 4,498 4,498
Button 0.00% 0.00% 91,106 91,106 26,915 26,915
Modal 0.00% 0.00% 90,214 90,214 26,715 26,715
colorManipulator 0.00% 0.00% 3,232 3,232 1,298 1,298
docs.landing 0.00% 0.00% 51,908 51,908 11,302 11,302
docs.main +0.04% 🔺 +0.04% 🔺 646,179 646,417 200,782 200,854
packages/material-ui/build/umd/material-ui.production.min.js +0.06% 🔺 +0.08% 🔺 310,946 311,128 85,146 85,217

Generated by 🚫 dangerJS against c81bf03

eps1lon
eps1lon previously requested changes Mar 6, 2019
Copy link
Member

@eps1lon eps1lon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you apply the new prop to every search result you posted? The description implies it's common with multiple search result but the solution is only applied to a single instance.

packages/material-ui/src/IconButton/IconButton.test.js Outdated Show resolved Hide resolved
@oliviertassinari
Copy link
Member

oliviertassinari commented Mar 6, 2019

@jedwards1211 Why do you want to make the IconButton own the logic responsible for a correct layout within a Toolbar? Shouldn't it be the other way around?

@eps1lon
Copy link
Member

eps1lon commented Mar 6, 2019

@jedwards1211 Why do you want to make the IconButton own the logic responsible for a correct layout within a Toolbar? Shouldn't it be the other way around?

Well because the IconButton itself affects layout. If it didn't have any margin I would agree. However by moving the logic inside the IconButton we can safely adjust the margin without affect layout because layout isn't hardcoded but done semantically.

@oliviertassinari
Copy link
Member

oliviertassinari commented Mar 6, 2019

Well because the IconButton itself affects layout.

@eps1lon I see, thanks for clarifying it. What do you think of a single boolean flag prop that that also works with the size property? We could name it antiPadding or something else. Basically, it would counter the padding needed for the ripple effect in all the directions.

.anti-padding {
  margin: -12px;
}

.anti-padding-small {
  margin: -3px
}

I think that this strategy can cover more use case, it sounds great to me.

@oliviertassinari oliviertassinari added component: icon button This is the name of the generic UI component, not the React module! new feature New feature or request labels Mar 6, 2019
@jedwards1211
Copy link
Contributor Author

jedwards1211 commented Mar 6, 2019

I'm not sure negative margin in all directions would work flawlessly in all cases. Maybe... I'll give it a try, it may mess up the vertical alignment though.

@jedwards1211
Copy link
Contributor Author

@eps1lon yes definitely, I'll update the other places in the demos, I just wanted to wait to do that work till I knew this would be accepted, we've agreed on the API

@jedwards1211
Copy link
Contributor Author

jedwards1211 commented Mar 6, 2019

@oliviertassinari okay, unfortunately margin: -12 doesn't quite work. I applied margin: -12 to the account button in the PrimarySearchAppBar demo and you can see that it messes up the spacing relative to the other icons and the border shape:
image
I think it's best to stick with marginLeft: -12 or marginRight: -12. I think it's actually rare that anyone would need -12 margin on both sides. I'm happy to rename the prop to antiPadding="left" if you want though.

@joshwooding
Copy link
Member

antiPadding for me does not clearly convey what the property is supposed to do

@jedwards1211
Copy link
Contributor Author

@joshwooding I agree; I think align is a bit awkward too (because it sounds like CSS justification) but align="left" does sort convey the purpose that the left side of the icon needs to be aligned with something else

@oliviertassinari
Copy link
Member

oliviertassinari commented Mar 6, 2019

@jedwards1211 Ok, my bad, poor proposition. Instead, could we rely on CSS first & last child selectors?

@jedwards1211
Copy link
Contributor Author

jedwards1211 commented Mar 6, 2019

@oliviertassinari I think if that were a flexible enough approach it would have already been done by whomever added the 12px padding to IconButton in the first place. There is marginLeft: -12 and marginRight: -12 applied to IconButtons on a case-by-case basis throughout your existing demos...I'm just codifying your existing approach into an API.
If you imagine

<AppBar>
  My App
  <AlertIconButtons />
  <AccountIconButtons />
</AppBar>

Where AccountIconButtons and AlertIconButtons each render several IconButton inside of a <div>, the first & last child CSS would be triggered on some of those IconButtons in an undesirable place. I really think this prop is the most convenient overall because it gives people full control without costing many keystrokes.

@oliviertassinari
Copy link
Member

oliviertassinari commented Mar 6, 2019

I think if that were a flexible enough approach it would have already been done by whomever added the 12px padding to IconButton in the first place.

@jedwards1211 If I had to guess, I would say that I'm the one who added the negative margin. We have never spend any effort into improving this implement. Maybe we can find something better given the field has been little explored yet. But no, I can't think of anything better, somebody else?

I like the property proposition. Regarding the naming. What do you think of?

edge?: 'start' | 'end' | false;

@oliviertassinari

This comment has been minimized.

@oliviertassinari oliviertassinari added the PR: needs revision The pull request can't be merged. More details is available on the code review or fails in the CI label Mar 6, 2019
@jedwards1211
Copy link
Contributor Author

jedwards1211 commented Mar 7, 2019

@oliviertassinari did you mean to post your last message on my other PR? Anyway thanks!
edge is a smart name for the prop, I like it!

So are you saying you want me to put the padding fixes into this PR?

@jedwards1211
Copy link
Contributor Author

jedwards1211 commented Mar 7, 2019

As far as using the ListItem directly, unfortunately it breaks encapsulation in some cases (the list is in a separate component that extra stuff like the inputs can't or shouldn't be passed into)

@eps1lon
Copy link
Member

eps1lon commented Mar 7, 2019

We should be careful with that given

[...] the fact that thousands (44k on a rough search albeit most should no longer be maintained) of repositories are using the same mixin [...]
-- #11539 (comment)

@oliviertassinari oliviertassinari changed the title [IconButton] add shortcut prop for applying negative margin to solve alignment issues [IconButton] Implement a new edge property Mar 7, 2019
@oliviertassinari
Copy link
Member

edge is a smart name for the prop, I like it!

@eps1lon Is right, better move carefully. We can split the effort into different pull requests. I think that the first order of business is to abstract the negative margin styles.

@oliviertassinari oliviertassinari changed the title [IconButton] Implement a new edge property [IconButton] Implement a new edge prop Mar 7, 2019
@jedwards1211
Copy link
Contributor Author

Okay I renamed the prop to edge and searched the docs for marginLeft: - and marginRight: - to try to find all the places I can use this new prop instead. If anyone finds additional places I should use it let me know!

* side of the icon with content above or below, without ruining the border
* size and shape).
*/
edge: PropTypes.oneOf(['left', 'right', false]),
Copy link
Member

@oliviertassinari oliviertassinari Mar 7, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think of start | end? It's an open question, I'm not sure what's best.

On our codebase

  • We are using the following values for the InputAdornment component:
position: PropTypes.oneOf(['start', 'end']),
  • We are using the following values for the FormControlLabel component:
labelPlacement: PropTypes.oneOf(['end', 'start', 'top', 'bottom']),
  • We are using the following values for the Tooltip component:
  placement: PropTypes.oneOf([
    'bottom-end',
    'bottom-start',
    'bottom',
    'left-end',
    'left-start',
    'left',
    'right-end',
    'right-start',
    'right',
    'top-end',
    'top-start',
    'top',
  ]),
  • Everywhere else we use left | right.

Benchmarking

CSS specification

  • The align-items CSS property uses the following values:
align-items?: 'flex-start' | 'flex-end' | 'center' | 'baseline'

I'm wondering if the CSS property values were influenced by RTL considerations or if it's simply related to the flew direction that can be either the x or y axis. Ok, it's probably not a good example, let me look deeper.

Misc

cc @mui-org/core-contributors

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, does Toolbar automatically reverse its content in RTL mode? If so then maybe you're right that we should reverse the margin applied by edge in RTL mode.

Copy link
Member

@oliviertassinari oliviertassinari Mar 7, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does Toolbar automatically reverse its content in RTL mode?

Yes, it does, you can try it on https://next.material-ui.com/. I'm trying to understand what would be more idiomatic to our users. I believe very few of them care about RTL. Hence my question, it's not obvious to me.

Copy link
Contributor Author

@jedwards1211 jedwards1211 Mar 7, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I will change the enum to start | end then. I think it is probably most convenient if this prop does the same thing conceptually in RTL mode?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems to me there's enough precedent for users understanding start | end, even though it's a bit less obvious than left | right for InputAdornment and so forth

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oliviertassinari oh, so looks like a JSS plugin is used to automatically flip all left and right properties in RTL mode and I don't need to check for RTL mode in my code changes -- am I understanding correctly?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

start | end 👍

@oliviertassinari oliviertassinari removed PR: needs revision The pull request can't be merged. More details is available on the code review or fails in the CI labels Mar 7, 2019
@jedwards1211
Copy link
Contributor Author

jedwards1211 commented Mar 7, 2019

A related issue: #14784.

@mui mui deleted a comment from jedwards1211 Mar 7, 2019
@mui mui deleted a comment from jedwards1211 Mar 7, 2019
@mui mui deleted a comment from jedwards1211 Mar 7, 2019
@oliviertassinari oliviertassinari force-pushed the IconButton-align-prop branch 3 times, most recently from a8949fa to 165ee99 Compare March 7, 2019 21:57
@kgregory
Copy link
Member

kgregory commented Mar 8, 2019

This is great.

@jedwards1211
Copy link
Contributor Author

jedwards1211 commented Mar 8, 2019

@KenGregory please help me advocate for adding an edge prop to Button too :)...I haven't managed to convince Olivier yet in #14784

@oliviertassinari
Copy link
Member

@jedwards1211 Thanks

@jedwards1211
Copy link
Contributor Author

Thank you guys!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: icon button This is the name of the generic UI component, not the React module! new feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants