Repository: mui/material-ui (TypeScript)
Date: 2018-06-21 17:34:51+00:00
Task type: Bug Fix

Issue:
[Button] Multiple variant styles being applied
- [X] This is a v1.x issue (v0.x is no longer maintained).
- [X] I have searched the [issues](https://github.com/mui-org/material-ui/issues) of this repository and believe that this is not a duplicate.

## Expected Behavior
When a variant is chosen, e.g. `outlined`, other variants such as `flat` should not be applied as classes.

## Current Behavior
The button element has multiple classes applied to it despite the variant applied.
E.g. for an outlined button i'm seeing flat, flatSecondary, etc:
```
<button tabindex="0" class="MuiButtonBase-root-123 MuiButton-root-101 MuiButton-textSecondary-104 MuiButton-flat-105 MuiButton-flatSecondary-107 MuiButton-outlined-108" type="button">
...
</button>
```

## Steps to Reproduce (for bugs)
Open up this sandbox example, then right-click and inspect the button element. You'll see the outlined variant in the classes, but also the flat variant.
https://codesandbox.io/s/8103lzm9q9

## Context
I noticed this when the `outlined` variant of the MUI button had some of the `flat` styling properties I applied at the theme level.

## Your Environment

| Tech         | Version |
|--------------|---------|
| Material-UI  | v1.0.0  |
| React        | 16.4.0 |
| browser      |  Chrome |



Issue discussion:
@murtyjones An outlined button is a flat button with a border, so this is an efficient reuse of styles, rather than duplicating them. 

We could: 

- Duplicate the styles
- Rename the flat style to reflect its dual purpose (breaking change)
- Leave it as is (I haven't gone hunting, but I'm pretty sure we have other components that share styles between variants).
- Something else?

(cc @leMaik )

Solution patch:
diff --git a/docs/src/pages/demos/buttons/FloatingActionButtons.js b/docs/src/pages/demos/buttons/FloatingActionButtons.js
--- a/docs/src/pages/demos/buttons/FloatingActionButtons.js
+++ b/docs/src/pages/demos/buttons/FloatingActionButtons.js
@@ -5,11 +5,15 @@ import Button from '@material-ui/core/Button';
 import AddIcon from '@material-ui/icons/Add';
 import Icon from '@material-ui/core/Icon';
 import DeleteIcon from '@material-ui/icons/Delete';
+import NavigationIcon from '@material-ui/icons/Navigation';
 
 const styles = theme => ({
   button: {
     margin: theme.spacing.unit,
   },
+  extendedIcon: {
+    marginRight: theme.spacing.unit,
+  },
 });
 
 function FloatingActionButtons(props) {
@@ -22,6 +26,10 @@ function FloatingActionButtons(props) {
       <Button variant="fab" color="secondary" aria-label="edit" className={classes.button}>
         <Icon>edit_icon</Icon>
       </Button>
+      <Button variant="extendedFab" aria-label="delete" className={classes.button}>
+        <NavigationIcon className={classes.extendedIcon} />
+        Extended
+      </Button>
       <Button variant="fab" disabled aria-label="delete" className={classes.button}>
         <DeleteIcon />
       </Button>
diff --git a/packages/material-ui/src/Button/Button.d.ts b/packages/material-ui/src/Button/Button.d.ts
--- a/packages/material-ui/src/Button/Button.d.ts
+++ b/packages/material-ui/src/Button/Button.d.ts
@@ -13,12 +13,13 @@ export interface ButtonProps extends StandardProps<ButtonBaseProps, ButtonClassK
   mini?: boolean;
   size?: 'small' | 'medium' | 'large';
   type?: string;
-  variant?: 'text' | 'flat' | 'outlined' | 'contained' | 'raised' | 'fab';
+  variant?: 'text' | 'flat' | 'outlined' | 'contained' | 'raised' | 'fab' | 'extendedFab';
 }
 
 export type ButtonClassKey =
   | 'root'
   | 'label'
+  | 'text'
   | 'textPrimary'
   | 'textSecondary'
   | 'flat'
diff --git a/packages/material-ui/src/Button/Button.js b/packages/material-ui/src/Button/Button.js
--- a/packages/material-ui/src/Button/Button.js
+++ b/packages/material-ui/src/Button/Button.js
@@ -13,9 +13,9 @@ export const styles = theme => ({
     ...theme.typography.button,
     lineHeight: '1.4em', // Improve readability for multiline button.
     boxSizing: 'border-box',
-    minWidth: theme.spacing.unit * 11,
+    minWidth: 88,
     minHeight: 36,
-    padding: `${theme.spacing.unit}px ${theme.spacing.unit * 2}px`,
+    padding: '8px 16px',
     borderRadius: 4,
     color: theme.palette.text.primary,
     transition: theme.transitions.create(['background-color', 'box-shadow'], {
@@ -37,11 +37,11 @@ export const styles = theme => ({
     },
   },
   label: {
-    width: '100%',
     display: 'inherit',
     alignItems: 'inherit',
     justifyContent: 'inherit',
   },
+  text: {},
   textPrimary: {
     color: theme.palette.primary.main,
     '&:hover': {
@@ -62,17 +62,14 @@ export const styles = theme => ({
       },
     },
   },
-  flat: {},
-  flatPrimary: {},
-  flatSecondary: {},
+  flat: {}, // legacy
+  flatPrimary: {}, // legacy
+  flatSecondary: {}, // legacy
   outlined: {
     border: `1px solid ${
       theme.palette.type === 'light' ? 'rgba(0, 0, 0, 0.23)' : 'rgba(255, 255, 255, 0.23)'
     }`,
   },
-  colorInherit: {
-    color: 'inherit',
-  },
   contained: {
     color: theme.palette.getContrastText(theme.palette.grey[300]),
     backgroundColor: theme.palette.grey[300],
@@ -121,36 +118,45 @@ export const styles = theme => ({
       },
     },
   },
-  raised: {},
-  raisedPrimary: {},
-  raisedSecondary: {},
-  focusVisible: {},
-  disabled: {},
+  raised: {}, // legacy
+  raisedPrimary: {}, // legacy
+  raisedSecondary: {}, // legacy
   fab: {
     borderRadius: '50%',
     padding: 0,
     minWidth: 0,
     width: 56,
-    fontSize: 24,
     height: 56,
     boxShadow: theme.shadows[6],
     '&:active': {
       boxShadow: theme.shadows[12],
     },
   },
+  extendedFab: {
+    borderRadius: 24,
+    padding: '0 16px',
+    width: 'initial',
+    minWidth: 48,
+    height: 48,
+  },
+  focusVisible: {},
+  disabled: {},
+  colorInherit: {
+    color: 'inherit',
+  },
   mini: {
     width: 40,
     height: 40,
   },
   sizeSmall: {
-    padding: `${theme.spacing.unit - 1}px ${theme.spacing.unit}px`,
-    minWidth: theme.spacing.unit * 8,
+    padding: '7px 8px',
+    minWidth: 64,
     minHeight: 32,
     fontSize: theme.typography.pxToRem(13),
   },
   sizeLarge: {
-    padding: `${theme.spacing.unit}px ${theme.spacing.unit * 3}px`,
-    minWidth: theme.spacing.unit * 14,
+    padding: '8px 24px',
+    minWidth: 112,
     minHeight: 40,
     fontSize: theme.typography.pxToRem(15),
   },
@@ -175,31 +181,32 @@ function Button(props) {
     ...other
   } = props;
 
-  const fab = variant === 'fab';
+  const fab = variant === 'fab' || variant === 'extendedFab';
   const contained = variant === 'contained' || variant === 'raised';
-  const text = !contained && !fab;
+  const text = variant === 'text' || variant === 'flat' || variant === 'outlined';
   const className = classNames(
     classes.root,
     {
-      [classes.contained]: contained || fab,
       [classes.fab]: fab,
       [classes.mini]: fab && mini,
-      [classes.colorInherit]: color === 'inherit',
+      [classes.extendedFab]: variant === 'extendedFab',
+      [classes.text]: text,
       [classes.textPrimary]: text && color === 'primary',
       [classes.textSecondary]: text && color === 'secondary',
-      [classes.flat]: text,
-      [classes.flatPrimary]: text && color === 'primary',
-      [classes.flatSecondary]: text && color === 'secondary',
-      [classes.containedPrimary]: !text && color === 'primary',
-      [classes.containedSecondary]: !text && color === 'secondary',
+      [classes.flat]: variant === 'text' || variant === 'flat',
+      [classes.flatPrimary]: (variant === 'text' || variant === 'flat') && color === 'primary',
+      [classes.flatSecondary]: (variant === 'text' || variant === 'flat') && color === 'secondary',
+      [classes.contained]: contained || fab,
+      [classes.containedPrimary]: (contained || fab) && color === 'primary',
+      [classes.containedSecondary]: (contained || fab) && color === 'secondary',
       [classes.raised]: contained || fab,
       [classes.raisedPrimary]: (contained || fab) && color === 'primary',
       [classes.raisedSecondary]: (contained || fab) && color === 'secondary',
-      [classes.text]: variant === 'text',
       [classes.outlined]: variant === 'outlined',
       [classes[`size${capitalize(size)}`]]: size !== 'medium',
       [classes.disabled]: disabled,
       [classes.fullWidth]: fullWidth,
+      [classes.colorInherit]: color === 'inherit',
     },
     classNameProp,
   );
@@ -282,7 +289,15 @@ Button.propTypes = {
   /**
    * The type of button.
    */
-  variant: PropTypes.oneOf(['text', 'flat', 'outlined', 'contained', 'raised', 'fab']),
+  variant: PropTypes.oneOf([
+    'text',
+    'flat',
+    'outlined',
+    'contained',
+    'raised',
+    'fab',
+    'extendedFab',
+  ]),
 };
 
 Button.defaultProps = {
diff --git a/pages/api/button.md b/pages/api/button.md
--- a/pages/api/button.md
+++ b/pages/api/button.md
@@ -23,7 +23,7 @@ filename: /packages/material-ui/src/Button/Button.js
 | <span class="prop-name">href</span> | <span class="prop-type">string |   | The URL to link to when the button is clicked. If defined, an `a` element will be used as the root node. |
 | <span class="prop-name">mini</span> | <span class="prop-type">bool | <span class="prop-default">false</span> | If `true`, and `variant` is `'fab'`, will use mini floating action button styling. |
 | <span class="prop-name">size</span> | <span class="prop-type">enum:&nbsp;'small'&nbsp;&#124;<br>&nbsp;'medium'&nbsp;&#124;<br>&nbsp;'large'<br> | <span class="prop-default">'medium'</span> | The size of the button. `small` is equivalent to the dense button styling. |
-| <span class="prop-name">variant</span> | <span class="prop-type">enum:&nbsp;'text', 'flat', 'outlined', 'contained', 'raised', 'fab'<br> | <span class="prop-default">'text'</span> | The type of button. |
+| <span class="prop-name">variant</span> | <span class="prop-type">enum:&nbsp;'text', 'flat', 'outlined', 'contained', 'raised', 'fab', 'extendedFab'<br> | <span class="prop-default">'text'</span> | The type of button. |
 
 Any other properties supplied will be spread to the root element ([ButtonBase](/api/button-base)).
 
@@ -33,22 +33,24 @@ You can override all the class names injected by Material-UI thanks to the `clas
 This property accepts the following keys:
 - `root`
 - `label`
+- `text`
 - `textPrimary`
 - `textSecondary`
 - `flat`
 - `flatPrimary`
 - `flatSecondary`
 - `outlined`
-- `colorInherit`
 - `contained`
 - `containedPrimary`
 - `containedSecondary`
 - `raised`
 - `raisedPrimary`
 - `raisedSecondary`
+- `fab`
+- `extendedFab`
 - `focusVisible`
 - `disabled`
-- `fab`
+- `colorInherit`
 - `mini`
 - `sizeSmall`
 - `sizeLarge`


Test patch:
diff --git a/packages/material-ui/src/Button/Button.test.js b/packages/material-ui/src/Button/Button.test.js
--- a/packages/material-ui/src/Button/Button.test.js
+++ b/packages/material-ui/src/Button/Button.test.js
@@ -28,9 +28,9 @@ describe('<Button />', () => {
 
   it('should render with the root & flat classes but no others', () => {
     const wrapper = shallow(<Button>Hello World</Button>);
-    assert.strictEqual(wrapper.hasClass(classes.root), true, 'should have the root class');
-    assert.strictEqual(wrapper.hasClass(classes.flat), true, 'should have the flat class');
-    assert.strictEqual(wrapper.hasClass(classes.fab), false, 'should not have the fab class');
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
+    assert.strictEqual(wrapper.hasClass(classes.flat), true);
+    assert.strictEqual(wrapper.hasClass(classes.fab), false);
     assert.strictEqual(
       wrapper.hasClass(classes.textPrimary),
       false,
@@ -66,7 +66,7 @@ describe('<Button />', () => {
       false,
       'should not have the containedSecondary class',
     );
-    assert.strictEqual(wrapper.hasClass(classes.raised), false, 'should not have the raised class');
+    assert.strictEqual(wrapper.hasClass(classes.raised), false);
     assert.strictEqual(
       wrapper.hasClass(classes.raisedPrimary),
       false,
@@ -81,16 +81,16 @@ describe('<Button />', () => {
 
   it('should render the custom className and the root class', () => {
     const wrapper = shallow(<Button className="test-class-name">Hello World</Button>);
-    assert.strictEqual(wrapper.is('.test-class-name'), true, 'should pass the test className');
-    assert.strictEqual(wrapper.hasClass(classes.root), true, 'should have the root class');
+    assert.strictEqual(wrapper.is('.test-class-name'), true);
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
   });
 
   it('should render a primary button', () => {
     const wrapper = shallow(<Button color="primary">Hello World</Button>);
-    assert.strictEqual(wrapper.hasClass(classes.root), true, 'should have the root class');
-    assert.strictEqual(wrapper.hasClass(classes.flat), true, 'should have the flat class');
-    assert.strictEqual(wrapper.hasClass(classes.contained), false, 'should have the raised class');
-    assert.strictEqual(wrapper.hasClass(classes.fab), false, 'should not have the fab class');
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
+    assert.strictEqual(wrapper.hasClass(classes.flat), true);
+    assert.strictEqual(wrapper.hasClass(classes.contained), false);
+    assert.strictEqual(wrapper.hasClass(classes.fab), false);
     assert.strictEqual(
       wrapper.hasClass(classes.textPrimary),
       true,
@@ -115,10 +115,10 @@ describe('<Button />', () => {
 
   it('should render a secondary button', () => {
     const wrapper = shallow(<Button color="secondary">Hello World</Button>);
-    assert.strictEqual(wrapper.hasClass(classes.root), true, 'should have the root class');
-    assert.strictEqual(wrapper.hasClass(classes.flat), true, 'should have the flat class');
-    assert.strictEqual(wrapper.hasClass(classes.contained), false, 'should have the raised class');
-    assert.strictEqual(wrapper.hasClass(classes.fab), false, 'should not have the fab class');
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
+    assert.strictEqual(wrapper.hasClass(classes.flat), true);
+    assert.strictEqual(wrapper.hasClass(classes.contained), false);
+    assert.strictEqual(wrapper.hasClass(classes.fab), false);
     assert.strictEqual(
       wrapper.hasClass(classes.textPrimary),
       false,
@@ -143,13 +143,13 @@ describe('<Button />', () => {
 
   it('should render a contained button', () => {
     const wrapper = shallow(<Button variant="contained">Hello World</Button>);
-    assert.strictEqual(wrapper.hasClass(classes.root), true, 'should have the root class');
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
     assert.strictEqual(
       wrapper.hasClass(classes.contained),
       true,
       'should have the contained class',
     );
-    assert.strictEqual(wrapper.hasClass(classes.fab), false, 'should not have the fab class');
+    assert.strictEqual(wrapper.hasClass(classes.fab), false);
     assert.strictEqual(
       wrapper.hasClass(classes.textPrimary),
       false,
@@ -168,13 +168,13 @@ describe('<Button />', () => {
         Hello World
       </Button>,
     );
-    assert.strictEqual(wrapper.hasClass(classes.root), true, 'should have the root class');
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
     assert.strictEqual(
       wrapper.hasClass(classes.contained),
       true,
       'should have the contained class',
     );
-    assert.strictEqual(wrapper.hasClass(classes.fab), false, 'should not have the fab class');
+    assert.strictEqual(wrapper.hasClass(classes.fab), false);
     assert.strictEqual(
       wrapper.hasClass(classes.containedPrimary),
       true,
@@ -193,9 +193,9 @@ describe('<Button />', () => {
         Hello World
       </Button>,
     );
-    assert.strictEqual(wrapper.hasClass(classes.root), true, 'should have the root class');
-    assert.strictEqual(wrapper.hasClass(classes.contained), true, 'should have the raised class');
-    assert.strictEqual(wrapper.hasClass(classes.fab), false, 'should not have the fab class');
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
+    assert.strictEqual(wrapper.hasClass(classes.contained), true);
+    assert.strictEqual(wrapper.hasClass(classes.fab), false);
     assert.strictEqual(
       wrapper.hasClass(classes.containedPrimary),
       false,
@@ -210,14 +210,14 @@ describe('<Button />', () => {
 
   it('should render a raised button', () => {
     const wrapper = shallow(<Button variant="raised">Hello World</Button>);
-    assert.strictEqual(wrapper.hasClass(classes.root), true, 'should have the root class');
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
     assert.strictEqual(
       wrapper.hasClass(classes.contained),
       true,
       'should have the contained class',
     );
-    assert.strictEqual(wrapper.hasClass(classes.raised), true, 'should have the raised class');
-    assert.strictEqual(wrapper.hasClass(classes.fab), false, 'should not have the fab class');
+    assert.strictEqual(wrapper.hasClass(classes.raised), true);
+    assert.strictEqual(wrapper.hasClass(classes.fab), false);
     assert.strictEqual(
       wrapper.hasClass(classes.containedPrimary),
       false,
@@ -246,14 +246,14 @@ describe('<Button />', () => {
         Hello World
       </Button>,
     );
-    assert.strictEqual(wrapper.hasClass(classes.root), true, 'should have the root class');
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
     assert.strictEqual(
       wrapper.hasClass(classes.contained),
       true,
       'should have the contained class',
     );
-    assert.strictEqual(wrapper.hasClass(classes.raised), true, 'should have the raised class');
-    assert.strictEqual(wrapper.hasClass(classes.fab), false, 'should not have the fab class');
+    assert.strictEqual(wrapper.hasClass(classes.raised), true);
+    assert.strictEqual(wrapper.hasClass(classes.fab), false);
     assert.strictEqual(
       wrapper.hasClass(classes.containedPrimary),
       true,
@@ -282,14 +282,14 @@ describe('<Button />', () => {
         Hello World
       </Button>,
     );
-    assert.strictEqual(wrapper.hasClass(classes.root), true, 'should have the root class');
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
     assert.strictEqual(
       wrapper.hasClass(classes.contained),
       true,
       'should have the contained class',
     );
-    assert.strictEqual(wrapper.hasClass(classes.raised), true, 'should have the raised class');
-    assert.strictEqual(wrapper.hasClass(classes.fab), false, 'should not have the fab class');
+    assert.strictEqual(wrapper.hasClass(classes.raised), true);
+    assert.strictEqual(wrapper.hasClass(classes.fab), false);
     assert.strictEqual(
       wrapper.hasClass(classes.containedPrimary),
       false,
@@ -314,16 +314,16 @@ describe('<Button />', () => {
 
   it('should render an outlined button', () => {
     const wrapper = shallow(<Button variant="outlined">Hello World</Button>);
-    assert.strictEqual(wrapper.hasClass(classes.root, 'should have the root class'), true);
-    assert.strictEqual(wrapper.hasClass(classes.flat), true, 'should have the flat class');
-    assert.strictEqual(wrapper.hasClass(classes.outlined), true, 'should have the outlined class');
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
+    assert.strictEqual(wrapper.hasClass(classes.text), true);
+    assert.strictEqual(wrapper.hasClass(classes.outlined), true);
     assert.strictEqual(
       wrapper.hasClass(classes.contained),
       false,
       'should not have the contained class',
     );
-    assert.strictEqual(wrapper.hasClass(classes.raised), false, 'should not have the raised class');
-    assert.strictEqual(wrapper.hasClass(classes.fab), false, 'should not have the fab class');
+    assert.strictEqual(wrapper.hasClass(classes.raised), false);
+    assert.strictEqual(wrapper.hasClass(classes.fab), false);
   });
 
   it('should render a primary outlined button', () => {
@@ -332,9 +332,9 @@ describe('<Button />', () => {
         Hello World
       </Button>,
     );
-    assert.strictEqual(wrapper.hasClass(classes.root), true, 'should have the root class');
-    assert.strictEqual(wrapper.hasClass(classes.flat), true, 'should have the flat class');
-    assert.strictEqual(wrapper.hasClass(classes.outlined), true, 'should have the outlined class');
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
+    assert.strictEqual(wrapper.hasClass(classes.text), true);
+    assert.strictEqual(wrapper.hasClass(classes.outlined), true);
     assert.strictEqual(
       wrapper.hasClass(classes.textPrimary),
       true,
@@ -345,8 +345,8 @@ describe('<Button />', () => {
       false,
       'should not have the contained class',
     );
-    assert.strictEqual(wrapper.hasClass(classes.raised), false, 'should not have the raised class');
-    assert.strictEqual(wrapper.hasClass(classes.fab), false, 'should not have the fab class');
+    assert.strictEqual(wrapper.hasClass(classes.raised), false);
+    assert.strictEqual(wrapper.hasClass(classes.fab), false);
   });
 
   it('should render a secondary outlined button', () => {
@@ -355,9 +355,9 @@ describe('<Button />', () => {
         Hello World
       </Button>,
     );
-    assert.strictEqual(wrapper.hasClass(classes.root), true, 'should have the root class');
-    assert.strictEqual(wrapper.hasClass(classes.flat), true, 'should have the flat class');
-    assert.strictEqual(wrapper.hasClass(classes.outlined), true, 'should have the outlined class');
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
+    assert.strictEqual(wrapper.hasClass(classes.text), true);
+    assert.strictEqual(wrapper.hasClass(classes.outlined), true);
     assert.strictEqual(
       wrapper.hasClass(classes.textSecondary),
       true,
@@ -368,20 +368,52 @@ describe('<Button />', () => {
       false,
       'should not have the contained class',
     );
-    assert.strictEqual(wrapper.hasClass(classes.raised), false, 'should not have the raised class');
-    assert.strictEqual(wrapper.hasClass(classes.fab), false, 'should not have the fab class');
+    assert.strictEqual(wrapper.hasClass(classes.raised), false);
+    assert.strictEqual(wrapper.hasClass(classes.fab), false);
   });
 
   it('should render a floating action button', () => {
     const wrapper = shallow(<Button variant="fab">Hello World</Button>);
-    assert.strictEqual(wrapper.hasClass(classes.root), true, 'should have the root class');
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
     assert.strictEqual(
       wrapper.hasClass(classes.contained),
       true,
       'should have the contained class',
     );
-    assert.strictEqual(wrapper.hasClass(classes.fab), true, 'should have the fab class');
-    assert.strictEqual(wrapper.hasClass(classes.flat), false, 'should not have the flat class');
+    assert.strictEqual(wrapper.hasClass(classes.fab), true);
+    assert.strictEqual(
+      wrapper.hasClass(classes.extendedFab),
+      false,
+      'should not have the extendedFab class',
+    );
+    assert.strictEqual(wrapper.hasClass(classes.flat), false);
+    assert.strictEqual(
+      wrapper.hasClass(classes.textPrimary),
+      false,
+      'should not have the textPrimary class',
+    );
+    assert.strictEqual(
+      wrapper.hasClass(classes.textSecondary),
+      false,
+      'should not have the textSecondary class',
+    );
+  });
+
+  it('should render an extended floating action button', () => {
+    const wrapper = shallow(<Button variant="extendedFab">Hello World</Button>);
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
+    assert.strictEqual(
+      wrapper.hasClass(classes.contained),
+      true,
+      'should have the contained class',
+    );
+    assert.strictEqual(wrapper.hasClass(classes.fab), true);
+    assert.strictEqual(
+      wrapper.hasClass(classes.extendedFab),
+      true,
+      'should have the extendedFab class',
+    );
+    assert.strictEqual(wrapper.hasClass(classes.flat), false);
     assert.strictEqual(
       wrapper.hasClass(classes.textPrimary),
       false,
@@ -400,10 +432,10 @@ describe('<Button />', () => {
         Hello World
       </Button>,
     );
-    assert.strictEqual(wrapper.hasClass(classes.root), true, 'should have the root class');
-    assert.strictEqual(wrapper.hasClass(classes.contained), true, 'should have the raised class');
-    assert.strictEqual(wrapper.hasClass(classes.fab), true, 'should have the fab class');
-    assert.strictEqual(wrapper.hasClass(classes.mini), true, 'should have the mini class');
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
+    assert.strictEqual(wrapper.hasClass(classes.contained), true);
+    assert.strictEqual(wrapper.hasClass(classes.fab), true);
+    assert.strictEqual(wrapper.hasClass(classes.mini), true);
     assert.strictEqual(
       wrapper.hasClass(classes.textPrimary),
       false,
@@ -422,18 +454,15 @@ describe('<Button />', () => {
         Hello World
       </Button>,
     );
-    assert.strictEqual(wrapper.hasClass(classes.root), true, 'should have the root class');
-    assert.strictEqual(wrapper.hasClass(classes.contained), true, 'should have the raised class');
-    assert.strictEqual(wrapper.hasClass(classes.fab), true, 'should have the fab class');
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
+    assert.strictEqual(wrapper.hasClass(classes.contained), true);
+    assert.strictEqual(wrapper.hasClass(classes.fab), true);
     assert.strictEqual(
       wrapper.hasClass(classes.containedPrimary),
       true,
       'should have the containedPrimary class',
     );
-    assert.strictEqual(
-      wrapper.hasClass(classes.containedSecondary, 'should have the containedPrimary class'),
-      false,
-    );
+    assert.strictEqual(wrapper.hasClass(classes.containedSecondary), false);
   });
 
   it('should render an secondary floating action button', () => {
@@ -442,19 +471,11 @@ describe('<Button />', () => {
         Hello World
       </Button>,
     );
-    assert.strictEqual(wrapper.hasClass(classes.root), true, 'should have the root class');
-    assert.strictEqual(wrapper.hasClass(classes.contained), true, 'should have the raised class');
-    assert.strictEqual(wrapper.hasClass(classes.fab), true, 'should have the fab class');
-    assert.strictEqual(
-      wrapper.hasClass(classes.containedPrimary),
-      false,
-      'should not have the containedPrimary class',
-    );
-    assert.strictEqual(
-      wrapper.hasClass(classes.containedSecondary),
-      true,
-      'should have the containedSecondary class',
-    );
+    assert.strictEqual(wrapper.hasClass(classes.root), true);
+    assert.strictEqual(wrapper.hasClass(classes.contained), true);
+    assert.strictEqual(wrapper.hasClass(classes.fab), true);
+    assert.strictEqual(wrapper.hasClass(classes.containedPrimary), false);
+    assert.strictEqual(wrapper.hasClass(classes.containedSecondary), true);
   });
 
   it('should have a ripple by default', () => {
@@ -469,12 +490,12 @@ describe('<Button />', () => {
 
   it('should have a focusRipple by default', () => {
     const wrapper = shallow(<Button>Hello World</Button>);
-    assert.strictEqual(wrapper.props().focusRipple, true, 'should set focusRipple to true');
+    assert.strictEqual(wrapper.props().focusRipple, true);
   });
 
   it('should pass disableFocusRipple to ButtonBase', () => {
     const wrapper = shallow(<Button disableFocusRipple>Hello World</Button>);
-    assert.strictEqual(wrapper.props().focusRipple, false, 'should set focusRipple to false');
+    assert.strictEqual(wrapper.props().focusRipple, false);
   });
 
   it('should render Icon children with right classes', () => {
@@ -484,7 +505,7 @@ describe('<Button />', () => {
     const label = wrapper.childAt(0);
     const renderedIconChild = label.childAt(0);
     assert.strictEqual(renderedIconChild.type(), Icon);
-    assert.strictEqual(renderedIconChild.hasClass(childClassName), true, 'child should be icon');
+    assert.strictEqual(renderedIconChild.hasClass(childClassName), true);
   });
 
   describe('server side', () => {
diff --git a/packages/material-ui/src/styles/MuiThemeProvider.test.js b/packages/material-ui/src/styles/MuiThemeProvider.test.js
--- a/packages/material-ui/src/styles/MuiThemeProvider.test.js
+++ b/packages/material-ui/src/styles/MuiThemeProvider.test.js
@@ -86,13 +86,13 @@ describe('<MuiThemeProvider />', () => {
       assert.notStrictEqual(markup.match('Hello World'), null);
       assert.strictEqual(sheetsRegistry.registry.length, 3);
       assert.strictEqual(sheetsRegistry.toString().length > 4000, true);
-      assert.strictEqual(sheetsRegistry.registry[0].classes.root, 'MuiTouchRipple-root-26');
+      assert.strictEqual(sheetsRegistry.registry[0].classes.root, 'MuiTouchRipple-root-28');
       assert.deepEqual(
         sheetsRegistry.registry[1].classes,
         {
-          disabled: 'MuiButtonBase-disabled-24',
-          focusVisible: 'MuiButtonBase-focusVisible-25',
-          root: 'MuiButtonBase-root-23',
+          disabled: 'MuiButtonBase-disabled-26',
+          focusVisible: 'MuiButtonBase-focusVisible-27',
+          root: 'MuiButtonBase-root-25',
         },
         'the class names should be deterministic',
       );