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

[Button] Add startIcon / endIcon props #17600

Merged
merged 12 commits into from
Oct 2, 2019

Conversation

mbrookes
Copy link
Member

@mbrookes mbrookes commented Sep 28, 2019

Closes #17494

I have gone with startIcon / endIcon for now.

Capture d’écran 2019-09-30 à 11 37 49

<Button
  variant="contained"
  color="secondary"
  startIcon={<DeleteIcon fontSize="small" />}
>
  Delete
</Button>

@mbrookes mbrookes added the component: button This is the name of the generic UI component, not the React module! label Sep 28, 2019
@mui-pr-bot
Copy link

mui-pr-bot commented Sep 28, 2019

@material-ui/core: parsed: +0.16% , gzip: +0.18%

Details of bundle changes.

Comparing: e89abcd...7b67635

bundle parsed diff gzip diff prev parsed current parsed prev gzip current gzip
@material-ui/core +0.16% 🔺 +0.18% 🔺 334,418 334,959 91,191 91,351
@material-ui/core/Paper 0.00% 0.00% 69,049 69,049 20,524 20,524
@material-ui/core/Paper.esm 0.00% 0.00% 62,377 62,377 19,276 19,276
@material-ui/core/Popper 0.00% 0.00% 28,405 28,405 10,179 10,179
@material-ui/core/Textarea 0.00% 0.00% 5,082 5,082 2,134 2,134
@material-ui/core/TrapFocus 0.00% 0.00% 3,766 3,766 1,597 1,597
@material-ui/core/styles/createMuiTheme 0.00% 0.00% 16,351 16,351 5,821 5,821
@material-ui/core/useMediaQuery 0.00% 0.00% 2,488 2,488 1,052 1,052
@material-ui/lab 0.00% 0.00% 143,406 143,406 43,818 43,818
@material-ui/styles 0.00% 0.00% 51,780 51,780 15,355 15,355
@material-ui/system 0.00% 0.00% 15,583 15,583 4,339 4,339
Button +0.68% 🔺 +0.60% 🔺 79,148 79,689 24,122 24,267
Modal 0.00% 0.00% 14,542 14,542 5,113 5,113
Portal 0.00% 0.00% 2,907 2,907 1,316 1,316
Rating 0.00% 0.00% 70,239 70,239 21,941 21,941
Slider 0.00% 0.00% 75,380 75,380 23,272 23,272
colorManipulator 0.00% 0.00% 3,835 3,835 1,519 1,519
docs.landing 0.00% 0.00% 54,267 54,267 14,344 14,344
docs.main +1.75% 🔺 +1.44% 🔺 588,954 599,235 188,297 191,014
packages/material-ui/build/umd/material-ui.production.min.js +0.16% 🔺 +0.13% 🔺 305,373 305,862 87,836 87,953

Generated by 🚫 dangerJS against 7b67635

@oliviertassinari
Copy link
Member

oliviertassinari commented Sep 29, 2019

Should we add a demo with the circular progress?

@oliviertassinari oliviertassinari added the new feature New feature or request label Sep 29, 2019
@mbrookes
Copy link
Member Author

mbrookes commented Sep 29, 2019

Should we add a demo with the circular progress?

afcb6d7 ? 🤷‍♂

("Crossed in the post"? 😄)

@mbrookes mbrookes marked this pull request as ready for review September 29, 2019 14:12
Copy link
Member

@joshwooding joshwooding left a comment

Choose a reason for hiding this comment

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

I was trying to think how this would affect FABs but it seems okay in its current state.

>
<LanguageIcon />
<Hidden xsDown implementation="css">
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

We might want to trigger the small version for a larger screen width, it flex shrinks otherwise:

Capture d’écran 2019-09-29 à 18 43 44

Copy link
Member Author

Choose a reason for hiding this comment

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

Hidden doesn't support the component prop. Do we go with the default js implementation or fix that separately?

@@ -229,16 +226,14 @@ function AppFrame(props) {
onClick={handleLanguageIconClick}
data-ga-event-category="AppBar"
data-ga-event-action="language"
startIcon={<LanguageIcon fontSize="small" />}
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure about the change:

Before:

Capture d’écran 2019-09-29 à 18 42 28

After:

Capture d’écran 2019-09-29 à 18 42 31

Copy link
Member Author

Choose a reason for hiding this comment

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

Oops, I should have tried it! I'll partially revert.

@mbrookes
Copy link
Member Author

mbrookes commented Sep 29, 2019

One other thought, should children be replaced by label, in order to follow https://material-ui.com/guides/api/? (If so I would propose we don't deprecate children, just change which one is documented.)

@oliviertassinari
Copy link
Member

oliviertassinari commented Sep 29, 2019

One other thought, should children be replaced by label, in order to follow https://material-ui.com/guides/api/? (If so I would propose we don't deprecate children, just change which one is documented.)

This would be a strong chance. I see a couple of options:

  1. We change the rule. Is this rule useful? Maybe what's most important is to use the children prop as many time it's the most relevant one for composition as much as possible.
  2. We rename the children prop, label.
  3. We go for the children prop all in. We inspect the children prop to find elements we interested in. Past experience has taught us the limits of this method.
  4. We go for the children prop all in. We use CSS child selector. With global class names, it doesn't require to import the related component. We have never used it yet. Seems simple but only support the components we define beforehand or with a generic class name.

@mbrookes
Copy link
Member Author

I'm in favour of option 1.

Option 2, to change children to label as the documented approach deviates from expectations set by the native <button> element.

Option 3, agreed.

Option 4. This risks a never ending stream of issues to support edge cases not covered by the current implementation.

@oliviertassinari
Copy link
Member

Option 1 and 4 seems the most popular alternatives in the other frameworks. I might like 1 better. @fzaninotto any preference?

@fzaninotto
Copy link
Contributor

yes, I prefer option 1, too.

@oliviertassinari
Copy link
Member

@mbrookes I have pushed a commit with the following changes:

  • Handle fullWidth prop. It seems that we need to render the icons inside the label if we want to have the icons display correctly when the button is full width:
  • Remove the circular progress, it's probably better to handle the concern in a "button loading state" effort.
  • Try to handle the language picker. This one is subjective, feel free to go in a different direction

@oliviertassinari
Copy link
Member

Should we force a font-size on the provided icon?

diff --git a/packages/material-ui/src/Button/Button.js b/packages/material-ui/src/Button/Button.js
index 1f8763984..e4b4f8358 100644
--- a/packages/material-ui/src/Button/Button.js
+++ b/packages/material-ui/src/Button/Button.js
@@ -217,6 +217,24 @@ export const styles = theme => ({
     marginRight: -4,
     marginLeft: 8,
   },
+  /* Styles applied to the icon element if supplied and `size="small"`. */
+  iconSizeSmall: {
+    '& > *': {
+      fontSize: 18,
+    },
+  },
+  /* Styles applied to the icon element if supplied and `size="medium"`. */
+  iconSizeMedium: {
+    '& > *': {
+      fontSize: 20,
+    },
+  },
+  /* Styles applied to the icon element if supplied and `size="large"`. */
+  iconSizeLarge: {
+    '& > *': {
+      fontSize: 22,
+    },
+  },
 });

 const Button = React.forwardRef(function Button(props, ref) {
@@ -238,8 +256,16 @@ const Button = React.forwardRef(function Button(props, ref) {
     ...other
   } = props;

-  const startIcon = startIconProp && <span className={classes.startIcon}>{startIconProp}</span>;
-  const endIcon = endIconProp && <span className={classes.endIcon}>{endIconProp}</span>;
+  const startIcon = startIconProp && (
+    <span className={clsx(classes.startIcon, classes[`iconSize${capitalize(size)}`])}>
+      {startIconProp}
+    </span>
+  );
+  const endIcon = endIconProp && (
+    <span className={clsx(classes.endIcon, classes[`iconSize${capitalize(size)}`])}>
+      {endIconProp}
+    </span>
+  );

   return (
     <ButtonBase

so it can be used like this:

<Button startIcon={<DeleteIcon />} />

or stick with?

<Button startIcon={<DeleteIcon fontSize="small" />} />

@mbrookes
Copy link
Member Author

mbrookes commented Oct 1, 2019

Providing the correct icon size sounds like a good idea.

@oliviertassinari
Copy link
Member

Ok, I'm preparing a new commit.

@oliviertassinari
Copy link
Member

I'm not sure that I have used the best approach to apply this CSS, happy to review a better approach.

Copy link
Member Author

@mbrookes mbrookes left a comment

Choose a reason for hiding this comment

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

Two more...

@mbrookes
Copy link
Member Author

mbrookes commented Oct 1, 2019

I don't have the permission to push

Odd, you already did:

image

@oliviertassinari
Copy link
Member

🎉

@mbrookes mbrookes deleted the button-icons branch October 2, 2019 08:24
@Floriferous
Copy link
Contributor

It's not very clear whether we should start using these props versus children? Is the result the same at this time?

@oliviertassinari
Copy link
Member

@Floriferous Use the prop if you want correct visual output out from the box. If you need to custom the position, you might not need it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: 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.

[Button] Icon Button Spacing Uneven
6 participants