Repository: mui/material-ui (TypeScript)
Date: 2018-08-02 12:53:28+00:00
Task type: Feature

Issue:
Chip missing color prop
<!--- Provide a general summary of the feature in the Title above -->

<!--
    Thank you very much for contributing to Material-UI by creating an issue! ❤️
    To avoid duplicate issues we ask you to check off the following list.
-->

<!-- Checked checkbox should look like this: [x] -->
- [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
<!---
    Describe how it should work.
-->
What about chip component have a color prop, if it is something that the community wants, it is a thing that I want to work on
## Current Behavior
<!---
    Explain the difference from current behavior.
-->
Chip component only have the default color




Issue discussion:
@itelo Could you provide more detail. What would be the final output? I'm not sure I understand the use case. 
something like that

![image](https://user-images.githubusercontent.com/11433064/43579595-0908638c-9629-11e8-822e-9b29134b65d3.png)


Solution patch:
diff --git a/.size-limit.js b/.size-limit.js
--- a/.size-limit.js
+++ b/.size-limit.js
@@ -27,7 +27,7 @@ module.exports = [
     name: 'The size of all the modules of material-ui.',
     webpack: true,
     path: 'packages/material-ui/build/index.js',
-    limit: '95.5 KB',
+    limit: '95.6 KB',
   },
   {
     name: 'The main bundle of the docs',
diff --git a/docs/src/pages/demos/chips/Chips.js b/docs/src/pages/demos/chips/Chips.js
--- a/docs/src/pages/demos/chips/Chips.js
+++ b/docs/src/pages/demos/chips/Chips.js
@@ -67,6 +67,32 @@ function Chips(props) {
         href="#chip"
         clickable
       />
+      <Chip
+        avatar={<Avatar>MB</Avatar>}
+        label="Clickable Link Chip"
+        clickable
+        className={classes.chip}
+        color="primary"
+        onDelete={handleDelete}
+        deleteIcon={<DoneIcon />}
+      />
+      <Chip
+        label="Clickable Link Chip"
+        onDelete={handleDelete}
+        className={classes.chip}
+        color="primary"
+      />
+      <Chip
+        avatar={
+          <Avatar>
+            <FaceIcon />
+          </Avatar>
+        }
+        label="Clickable Link Chip"
+        onDelete={handleDelete}
+        className={classes.chip}
+        color="secondary"
+      />
     </div>
   );
 }
diff --git a/docs/src/pages/demos/chips/ChipsPlayground.js b/docs/src/pages/demos/chips/ChipsPlayground.js
new file mode 100644
--- /dev/null
+++ b/docs/src/pages/demos/chips/ChipsPlayground.js
@@ -0,0 +1,177 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import MarkdownElement from '@material-ui/docs/MarkdownElement';
+import Grid from '@material-ui/core/Grid';
+import FormControl from '@material-ui/core/FormControl';
+import FormLabel from '@material-ui/core/FormLabel';
+import FormControlLabel from '@material-ui/core/FormControlLabel';
+import RadioGroup from '@material-ui/core/RadioGroup';
+import Radio from '@material-ui/core/Radio';
+import Paper from '@material-ui/core/Paper';
+import Avatar from '@material-ui/core/Avatar';
+import Chip from '@material-ui/core/Chip';
+import FaceIcon from '@material-ui/icons/Face';
+import DoneIcon from '@material-ui/icons/Done';
+
+const styles = theme => ({
+  root: {
+    flexGrow: 1,
+  },
+  control: {
+    padding: theme.spacing.unit * 2,
+  },
+  chipWrapper: {
+    marginBottom: theme.spacing.unit * 5,
+  },
+});
+
+class ChipsPlayground extends React.Component {
+  state = {
+    color: 'default',
+    onDelete: 'none',
+    avatar: 'none',
+  };
+
+  handleChange = key => (event, value) => {
+    this.setState({
+      [key]: value,
+    });
+  };
+
+  handleDeleteExample = () => {
+    alert('You clicked the delete icon.'); // eslint-disable-line no-alert
+  };
+
+  render() {
+    const { classes } = this.props;
+    const { color, onDelete, avatar } = this.state;
+
+    const colorToCode = color !== 'default' ? `color=${color} ` : '';
+
+    let onDeleteToCode;
+    switch (onDelete) {
+      case 'none':
+        onDeleteToCode = '';
+        break;
+      case 'custom':
+        onDeleteToCode = 'deleteIcon={<DoneIcon />} onDelete={handleDelete} ';
+        break;
+      default:
+        onDeleteToCode = 'onDelete={handleDelete} ';
+        break;
+    }
+
+    let avatarToCode;
+    let avatarToPlayground;
+    switch (avatar) {
+      case 'none':
+        avatarToCode = '';
+        break;
+      case 'img':
+        avatarToCode = 'avatar={<Avatar src="/static/images/uxceo-128.jpg" />} ';
+        avatarToPlayground = <Avatar src="/static/images/uxceo-128.jpg" />;
+        break;
+      case 'letter':
+        avatarToCode = 'avatar={<Avatar>FH</Avatar>} ';
+        avatarToPlayground = <Avatar>FH</Avatar>;
+        break;
+      default:
+        avatarToCode = 'avatar={<Avatar><FaceIcon /></Avatar>} ';
+        avatarToPlayground = (
+          <Avatar>
+            <FaceIcon />
+          </Avatar>
+        );
+        break;
+    }
+
+    const code = `
+\`\`\`jsx
+<Chip ${colorToCode}${onDeleteToCode}${avatarToCode}/>
+\`\`\`
+`;
+
+    return (
+      <Grid container className={classes.root}>
+        <Grid item xs={12}>
+          <Grid container justify="center" alignItems="center" spacing={40}>
+            <Grid item className={classes.chipWrapper}>
+              <Chip
+                label="Awesome Chip Component"
+                color={color}
+                deleteIcon={onDelete === 'custom' && <DoneIcon />}
+                onDelete={onDelete !== 'none' && this.handleDeleteExample}
+                avatar={avatarToPlayground}
+              />
+            </Grid>
+          </Grid>
+        </Grid>
+        <Grid item xs={12}>
+          <Paper className={classes.control}>
+            <Grid container spacing={24}>
+              <Grid item xs={12}>
+                <FormControl component="fieldset">
+                  <FormLabel>color</FormLabel>
+                  <RadioGroup
+                    row
+                    name="color"
+                    aria-label="color"
+                    value={color}
+                    onChange={this.handleChange('color')}
+                  >
+                    <FormControlLabel value="default" control={<Radio />} label="default" />
+                    <FormControlLabel value="primary" control={<Radio />} label="primary" />
+                    <FormControlLabel value="secondary" control={<Radio />} label="secondary" />
+                  </RadioGroup>
+                </FormControl>
+              </Grid>
+              <Grid item xs={12}>
+                <FormControl component="fieldset">
+                  <FormLabel>onDelete</FormLabel>
+                  <RadioGroup
+                    row
+                    name="onDelete"
+                    aria-label="onDelete"
+                    value={onDelete}
+                    onChange={this.handleChange('onDelete')}
+                  >
+                    <FormControlLabel value="none" control={<Radio />} label="none" />
+                    <FormControlLabel value="default" control={<Radio />} label="default" />
+                    <FormControlLabel value="custom" control={<Radio />} label="custom" />
+                  </RadioGroup>
+                </FormControl>
+              </Grid>
+              <Grid item xs={12}>
+                <FormControl component="fieldset">
+                  <FormLabel>avatar</FormLabel>
+                  <RadioGroup
+                    row
+                    name="avatar"
+                    aria-label="avatar"
+                    value={avatar}
+                    onChange={this.handleChange('avatar')}
+                  >
+                    <FormControlLabel value="none" control={<Radio />} label="none" />
+                    <FormControlLabel value="letter" control={<Radio />} label="letter" />
+                    <FormControlLabel value="img" control={<Radio />} label="img" />
+                    <FormControlLabel value="icon" control={<Radio />} label="icon" />
+                  </RadioGroup>
+                </FormControl>
+              </Grid>
+            </Grid>
+          </Paper>
+        </Grid>
+        <Grid item xs={12}>
+          <MarkdownElement text={code} />
+        </Grid>
+      </Grid>
+    );
+  }
+}
+
+ChipsPlayground.propTypes = {
+  classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(ChipsPlayground);
diff --git a/docs/src/pages/demos/chips/chips.md b/docs/src/pages/demos/chips/chips.md
--- a/docs/src/pages/demos/chips/chips.md
+++ b/docs/src/pages/demos/chips/chips.md
@@ -17,14 +17,20 @@ not shown in context.
 
 Examples of Chips, using an image Avatar, SVG Icon Avatar, "Letter"
 and (string) Avatar.
+
 - Chips with the `onClick` property defined change appearance on focus,
-hover, and click.
+  hover, and click.
 - Chips with the `onDelete` property defined will display a delete
-icon which changes appearance on hover.
+  icon which changes appearance on hover.
 
 {{"demo": "pages/demos/chips/Chips.js"}}
 
+## Chip Playground
+
+{{"demo": "pages/demos/chips/ChipsPlayground.js"}}
+
 ## Chip array
+
 An example of rendering multiple Chips from an array of values.
 Deleting a chip removes it from the array. Note that since no
 `onClick` property is defined, the Chip can be focused, but does not
diff --git a/packages/material-ui/src/Chip/Chip.d.ts b/packages/material-ui/src/Chip/Chip.d.ts
--- a/packages/material-ui/src/Chip/Chip.d.ts
+++ b/packages/material-ui/src/Chip/Chip.d.ts
@@ -1,8 +1,9 @@
 import * as React from 'react';
-import { StandardProps } from '..';
+import { StandardProps, PropTypes } from '..';
 
 export interface ChipProps
   extends StandardProps<React.HTMLAttributes<HTMLDivElement>, ChipClassKey> {
+  color?: PropTypes.Color;
   avatar?: React.ReactElement<any>;
   clickable?: boolean;
   component?: React.ReactType<ChipProps>;
@@ -15,11 +16,19 @@ export interface ChipProps
 export type ChipClassKey =
   | 'root'
   | 'clickable'
+  | 'clickablePrimary'
+  | 'clickableSecondary'
   | 'deletable'
+  | 'deletablePrimary'
+  | 'deletableSecondary'
   | 'avatar'
+  | 'avatarPrimary'
+  | 'avatarSecondary'
   | 'avatarChildren'
   | 'label'
-  | 'deleteIcon';
+  | 'deleteIcon'
+  | 'deleteIconPrimary'
+  | 'deleteIconSecondary';
 
 declare const Chip: React.ComponentType<ChipProps>;
 
diff --git a/packages/material-ui/src/Chip/Chip.js b/packages/material-ui/src/Chip/Chip.js
--- a/packages/material-ui/src/Chip/Chip.js
+++ b/packages/material-ui/src/Chip/Chip.js
@@ -4,8 +4,9 @@ import classNames from 'classnames';
 import keycode from 'keycode';
 import CancelIcon from '../internal/svg-icons/Cancel';
 import withStyles from '../styles/withStyles';
-import { emphasize, fade } from '../styles/colorManipulator';
+import { emphasize, fade, darken } from '../styles/colorManipulator';
 import unsupportedProp from '../utils/unsupportedProp';
+import { capitalize } from '../utils/helpers';
 import '../Avatar/Avatar'; // So we don't have any override priority issue.
 
 export const styles = theme => {
@@ -36,10 +37,19 @@ export const styles = theme => {
       border: 'none', // Remove `button` border
       padding: 0, // Remove `button` padding
     },
+    /* Styles applied to the root element if `color="primary"`. */
+    colorPrimary: {
+      backgroundColor: theme.palette.primary.main,
+      color: theme.palette.primary.contrastText,
+    },
+    /* Styles applied to the root element if `color="secondary"`. */
+    colorSecondary: {
+      backgroundColor: theme.palette.secondary.main,
+      color: theme.palette.secondary.contrastText,
+    },
     /* Styles applied to the root element if `onClick` is defined or `clickable={true}`. */
     clickable: {
-      // Remove grey highlight
-      WebkitTapHighlightColor: 'transparent',
+      WebkitTapHighlightColor: 'transparent', // Remove grey highlight
       cursor: 'pointer',
       '&:hover, &:focus': {
         backgroundColor: emphasize(backgroundColor, 0.08),
@@ -49,12 +59,48 @@ export const styles = theme => {
         backgroundColor: emphasize(backgroundColor, 0.12),
       },
     },
+    /**
+     * Styles applied to the root element if
+     * `onClick` and `color="primary"` is defined or `clickable={true}`.
+     */
+    clickableColorPrimary: {
+      '&:hover, &:focus': {
+        backgroundColor: emphasize(theme.palette.primary.main, 0.08),
+      },
+      '&:active': {
+        backgroundColor: emphasize(theme.palette.primary.main, 0.12),
+      },
+    },
+    /**
+     * Styles applied to the root element if
+     * `onClick` and `color="secondary"` is defined or `clickable={true}`.
+     */
+    clickableColorSecondary: {
+      '&:hover, &:focus': {
+        backgroundColor: emphasize(theme.palette.secondary.main, 0.08),
+      },
+      '&:active': {
+        backgroundColor: emphasize(theme.palette.secondary.main, 0.12),
+      },
+    },
     /* Styles applied to the root element if `onDelete` is defined. */
     deletable: {
       '&:focus': {
         backgroundColor: emphasize(backgroundColor, 0.08),
       },
     },
+    /* Styles applied to the root element if `onDelete` and `color="primary"` is defined. */
+    deletableColorPrimary: {
+      '&:focus': {
+        backgroundColor: emphasize(theme.palette.primary.main, 0.2),
+      },
+    },
+    /* Styles applied to the root element if `onDelete` and `color="secondary"` is defined. */
+    deletableColorSecondary: {
+      '&:focus': {
+        backgroundColor: emphasize(theme.palette.secondary.main, 0.2),
+      },
+    },
     /* Styles applied to the `avatar` element. */
     avatar: {
       marginRight: -4,
@@ -63,6 +109,16 @@ export const styles = theme => {
       color: theme.palette.type === 'light' ? theme.palette.grey[700] : theme.palette.grey[300],
       fontSize: theme.typography.pxToRem(16),
     },
+    /* Styles applied to the `avatar` element if `checked={true}` and `color="primary"` */
+    avatarColorPrimary: {
+      color: darken(theme.palette.primary.contrastText, 0.1),
+      backgroundColor: theme.palette.primary.dark,
+    },
+    /* Styles applied to the `avatar` element if `checked={true}` and `color="secondary"` */
+    avatarColorSecondary: {
+      color: darken(theme.palette.secondary.contrastText, 0.1),
+      backgroundColor: theme.palette.secondary.dark,
+    },
     /* Styles applied to the `avatar` elements children. */
     avatarChildren: {
       width: 19,
@@ -90,6 +146,20 @@ export const styles = theme => {
         color: fade(deleteIconColor, 0.4),
       },
     },
+    /* Styles applied to the deleteIcon element if `color="primary"`. */
+    deleteIconColorPrimary: {
+      color: fade(theme.palette.primary.contrastText, 0.65),
+      '&:hover, &:active': {
+        color: theme.palette.primary.contrastText,
+      },
+    },
+    /* Styles applied to the deleteIcon element if `color="secondary"`. */
+    deleteIconColorSecondary: {
+      color: fade(theme.palette.primary.contrastText, 0.65),
+      '&:hover, &:active': {
+        color: theme.palette.primary.contrastText,
+      },
+    },
   };
 };
 
@@ -141,6 +211,7 @@ class Chip extends React.Component {
       classes,
       className: classNameProp,
       clickable,
+      color,
       component: Component,
       deleteIcon: deleteIconProp,
       label,
@@ -153,8 +224,14 @@ class Chip extends React.Component {
 
     const className = classNames(
       classes.root,
+      { [classes[`color${capitalize(color)}`]]: color !== 'default' },
       { [classes.clickable]: onClick || clickable },
+      {
+        [classes[`clickableColor${capitalize(color)}`]]:
+          (onClick || clickable) && color !== 'default',
+      },
       { [classes.deletable]: onDelete },
+      { [classes[`deletableColor${capitalize(color)}`]]: onDelete && color !== 'default' },
       classNameProp,
     );
 
@@ -163,18 +240,27 @@ class Chip extends React.Component {
       deleteIcon =
         deleteIconProp && React.isValidElement(deleteIconProp) ? (
           React.cloneElement(deleteIconProp, {
-            className: classNames(deleteIconProp.props.className, classes.deleteIcon),
+            className: classNames(deleteIconProp.props.className, classes.deleteIcon, {
+              [classes[`deleteIconColor${capitalize(color)}`]]: color !== 'default',
+            }),
             onClick: this.handleDeleteIconClick,
           })
         ) : (
-          <CancelIcon className={classes.deleteIcon} onClick={this.handleDeleteIconClick} />
+          <CancelIcon
+            className={classNames(classes.deleteIcon, {
+              [classes[`deleteIconColor${capitalize(color)}`]]: color !== 'default',
+            })}
+            onClick={this.handleDeleteIconClick}
+          />
         );
     }
 
     let avatar = null;
     if (avatarProp && React.isValidElement(avatarProp)) {
       avatar = React.cloneElement(avatarProp, {
-        className: classNames(classes.avatar, avatarProp.props.className),
+        className: classNames(classes.avatar, avatarProp.props.className, {
+          [classes[`avatarColor${capitalize(color)}`]]: color !== 'default',
+        }),
         childrenClassName: classNames(classes.avatarChildren, avatarProp.props.childrenClassName),
       });
     }
@@ -230,6 +316,10 @@ Chip.propTypes = {
    * along with the component property to indicate an anchor Chip is clickable.
    */
   clickable: PropTypes.bool,
+  /**
+   * The color of the component. It supports those theme colors that make sense for this component.
+   */
+  color: PropTypes.oneOf(['default', 'primary', 'secondary']),
   /**
    * The component used for the root node.
    * Either a string to use a DOM element or a component.
@@ -265,6 +355,7 @@ Chip.propTypes = {
 Chip.defaultProps = {
   clickable: false,
   component: 'div',
+  color: 'default',
 };
 
 export default withStyles(styles, { name: 'MuiChip' })(Chip);
diff --git a/pages/api/chip.md b/pages/api/chip.md
--- a/pages/api/chip.md
+++ b/pages/api/chip.md
@@ -19,6 +19,7 @@ Chips represent complex entities in small blocks, such as a contact.
 | <span class="prop-name">children</span> | <span class="prop-type">unsupportedProp |   | This property isn't supported. Use the `component` property if you need to change the children structure. |
 | <span class="prop-name">classes</span> | <span class="prop-type">object |   | Override or extend the styles applied to the component. See [CSS API](#css-api) below for more details. |
 | <span class="prop-name">clickable</span> | <span class="prop-type">bool | <span class="prop-default">false</span> | If true, the chip will appear clickable, and will raise when pressed, even if the onClick property is not defined. This can be used, for example, along with the component property to indicate an anchor Chip is clickable. |
+| <span class="prop-name">color</span> | <span class="prop-type">enum:&nbsp;'default'&nbsp;&#124;<br>&nbsp;'primary'&nbsp;&#124;<br>&nbsp;'secondary'<br> | <span class="prop-default">'default'</span> | The color of the component. It supports those theme colors that make sense for this component. |
 | <span class="prop-name">component</span> | <span class="prop-type">union:&nbsp;string&nbsp;&#124;<br>&nbsp;func&nbsp;&#124;<br>&nbsp;object<br> | <span class="prop-default">'div'</span> | The component used for the root node. Either a string to use a DOM element or a component. |
 | <span class="prop-name">deleteIcon</span> | <span class="prop-type">element |   | Override the default delete icon element. Shown only if `onDelete` is set. |
 | <span class="prop-name">label</span> | <span class="prop-type">node |   | The content of the label. |
@@ -35,12 +36,22 @@ This property accepts the following keys:
 | Name | Description |
 |:-----|:------------|
 | <span class="prop-name">root</span> | Styles applied to the root element.
+| <span class="prop-name">colorPrimary</span> | Styles applied to the root element if `color="primary"`.
+| <span class="prop-name">colorSecondary</span> | Styles applied to the root element if `color="secondary"`.
 | <span class="prop-name">clickable</span> | Styles applied to the root element if `onClick` is defined or `clickable={true}`.
+| <span class="prop-name">clickableColorPrimary</span> | 
+| <span class="prop-name">clickableColorSecondary</span> | 
 | <span class="prop-name">deletable</span> | Styles applied to the root element if `onDelete` is defined.
+| <span class="prop-name">deletableColorPrimary</span> | Styles applied to the root element if `onDelete` and `color="primary"` is defined.
+| <span class="prop-name">deletableColorSecondary</span> | Styles applied to the root element if `onDelete` and `color="secondary"` is defined.
 | <span class="prop-name">avatar</span> | Styles applied to the `avatar` element.
+| <span class="prop-name">avatarColorPrimary</span> | Styles applied to the `avatar` element if `checked={true}` and `color="primary"`
+| <span class="prop-name">avatarColorSecondary</span> | Styles applied to the `avatar` element if `checked={true}` and `color="secondary"`
 | <span class="prop-name">avatarChildren</span> | Styles applied to the `avatar` elements children.
 | <span class="prop-name">label</span> | Styles applied to the label `span` element`.
 | <span class="prop-name">deleteIcon</span> | Styles applied to the `deleteIcon` element.
+| <span class="prop-name">deleteIconColorPrimary</span> | Styles applied to the deleteIcon element if `color="primary"`.
+| <span class="prop-name">deleteIconColorSecondary</span> | Styles applied to the deleteIcon element if `color="secondary"`.
 
 Have a look at [overriding with classes](/customization/overrides#overriding-with-classes) section
 and the [implementation of the component](https://github.com/mui-org/material-ui/tree/master/packages/material-ui/src/Chip/Chip.js)
diff --git a/pages/demos/chips.js b/pages/demos/chips.js
--- a/pages/demos/chips.js
+++ b/pages/demos/chips.js
@@ -13,6 +13,13 @@ function Page() {
           raw: preval`
 module.exports = require('fs')
   .readFileSync(require.resolve('docs/src/pages/demos/chips/Chips'), 'utf8')
+`,
+        },
+        'pages/demos/chips/ChipsPlayground.js': {
+          js: require('docs/src/pages/demos/chips/ChipsPlayground').default,
+          raw: preval`
+module.exports = require('fs')
+  .readFileSync(require.resolve('docs/src/pages/demos/chips/ChipsPlayground'), 'utf8')
 `,
         },
         'pages/demos/chips/ChipsArray.js': {


Test patch:
diff --git a/packages/material-ui/src/Chip/Chip.test.js b/packages/material-ui/src/Chip/Chip.test.js
--- a/packages/material-ui/src/Chip/Chip.test.js
+++ b/packages/material-ui/src/Chip/Chip.test.js
@@ -24,25 +24,40 @@ describe('<Chip />', () => {
   });
 
   describe('text only', () => {
-    let wrapper;
-
-    before(() => {
-      wrapper = shallow(<Chip className="my-Chip" data-my-prop="woofChip" />);
-    });
-
     it('should render a div containing a span', () => {
+      const wrapper = shallow(<Chip className="my-Chip" data-my-prop="woofChip" />);
       assert.strictEqual(wrapper.name(), 'div');
       assert.strictEqual(wrapper.childAt(0).is('span'), true, 'should be a span');
+      assert.strictEqual(wrapper.hasClass(classes.root), true);
+      assert.strictEqual(wrapper.hasClass('my-Chip'), true);
+      assert.strictEqual(wrapper.props()['data-my-prop'], 'woofChip');
+      assert.strictEqual(wrapper.props().tabIndex, -1);
+
+      assert.strictEqual(wrapper.hasClass(classes.root), true);
+      assert.strictEqual(wrapper.hasClass(classes.colorPrimary), false);
+      assert.strictEqual(wrapper.hasClass(classes.colorSecondary), false);
+      assert.strictEqual(wrapper.hasClass(classes.clickable), false);
+      assert.strictEqual(wrapper.hasClass(classes.clickableColorPrimary), false);
+      assert.strictEqual(wrapper.hasClass(classes.clickableColorSecondary), false);
+      assert.strictEqual(wrapper.hasClass(classes.deletable), false);
+      assert.strictEqual(wrapper.hasClass(classes.deletableColorPrimary), false);
+      assert.strictEqual(wrapper.hasClass(classes.deletableColorSecondary), false);
     });
 
-    it('should merge user classes & spread custom props to the root node', () => {
+    it('should render with the root and the primary class', () => {
+      const wrapper = shallow(<Chip className="my-Chip" data-my-prop="woofChip" color="primary" />);
+
       assert.strictEqual(wrapper.hasClass(classes.root), true);
-      assert.strictEqual(wrapper.hasClass('my-Chip'), true);
-      assert.strictEqual(wrapper.prop('data-my-prop'), 'woofChip');
+      assert.strictEqual(wrapper.hasClass(classes.colorPrimary), true);
     });
 
-    it('should have a tabIndex prop with value -1', () => {
-      assert.strictEqual(wrapper.props().tabIndex, -1);
+    it('should render with the root and the secondary class', () => {
+      const wrapper = shallow(
+        <Chip className="my-Chip" data-my-prop="woofChip" color="secondary" />,
+      );
+
+      assert.strictEqual(wrapper.hasClass(classes.root), true);
+      assert.strictEqual(wrapper.hasClass(classes.colorSecondary), true);
     });
   });
 
@@ -78,6 +93,38 @@ describe('<Chip />', () => {
       );
       assert.strictEqual(wrapper.props().tabIndex, 5);
     });
+
+    it('should render with the root and clickable class', () => {
+      assert.strictEqual(wrapper.hasClass(classes.root), true);
+      assert.strictEqual(wrapper.hasClass(classes.clickable), true);
+    });
+
+    it('should render with the root and clickable primary class', () => {
+      wrapper = shallow(
+        <Chip className="my-Chip" data-my-prop="woofChip" onClick={handleClick} color="primary" />,
+      );
+
+      assert.strictEqual(wrapper.hasClass(classes.root), true);
+      assert.strictEqual(wrapper.hasClass(classes.colorPrimary), true);
+      assert.strictEqual(wrapper.hasClass(classes.clickable), true);
+      assert.strictEqual(wrapper.hasClass(classes.clickableColorPrimary), true);
+    });
+
+    it('should render with the root and clickable secondary class', () => {
+      wrapper = shallow(
+        <Chip
+          className="my-Chip"
+          data-my-prop="woofChip"
+          onClick={handleClick}
+          color="secondary"
+        />,
+      );
+
+      assert.strictEqual(wrapper.hasClass(classes.root), true);
+      assert.strictEqual(wrapper.hasClass(classes.colorSecondary), true);
+      assert.strictEqual(wrapper.hasClass(classes.clickable), true);
+      assert.strictEqual(wrapper.hasClass(classes.clickableColorSecondary), true);
+    });
   });
 
   describe('deletable Avatar chip', () => {
@@ -136,11 +183,68 @@ describe('<Chip />', () => {
       wrapper.setProps({ onDelete: onDeleteSpy });
 
       wrapper.find('pure(Cancel)').simulate('click', { stopPropagation: stopPropagationSpy });
-      assert.strictEqual(
-        stopPropagationSpy.callCount,
-        1,
-        'should have called the stopPropagation handler',
+      assert.strictEqual(stopPropagationSpy.callCount, 1);
+    });
+
+    it('should render with the root, deletable classes', () => {
+      assert.strictEqual(wrapper.hasClass(classes.root), true);
+      assert.strictEqual(wrapper.hasClass(classes.deletable), true);
+
+      const avatarWrapper = wrapper.childAt(0);
+
+      assert.strictEqual(avatarWrapper.hasClass(classes.avatar), true);
+    });
+
+    it('should render with the root, deletable and avatar primary classes', () => {
+      wrapper = shallow(
+        <Chip
+          avatar={
+            <Avatar className="my-Avatar" data-my-prop="woofChip">
+              MB
+            </Avatar>
+          }
+          label="Text Avatar Chip"
+          onDelete={() => {}}
+          className="my-Chip"
+          data-my-prop="woofChip"
+          color="primary"
+        />,
       );
+      assert.strictEqual(wrapper.hasClass(classes.root), true);
+      assert.strictEqual(wrapper.hasClass(classes.colorPrimary), true);
+      assert.strictEqual(wrapper.hasClass(classes.deletable), true);
+      assert.strictEqual(wrapper.hasClass(classes.deletableColorPrimary), true);
+
+      const avatarWrapper = wrapper.childAt(0);
+
+      assert.strictEqual(avatarWrapper.hasClass(classes.avatar), true);
+      assert.strictEqual(avatarWrapper.hasClass(classes.avatarColorPrimary), true);
+    });
+
+    it('should render with the root, deletable and avatar secondary classes', () => {
+      wrapper = shallow(
+        <Chip
+          avatar={
+            <Avatar className="my-Avatar" data-my-prop="woofChip">
+              MB
+            </Avatar>
+          }
+          label="Text Avatar Chip"
+          onDelete={() => {}}
+          className="my-Chip"
+          data-my-prop="woofChip"
+          color="secondary"
+        />,
+      );
+      assert.strictEqual(wrapper.hasClass(classes.root), true);
+      assert.strictEqual(wrapper.hasClass(classes.colorSecondary), true);
+      assert.strictEqual(wrapper.hasClass(classes.deletable), true);
+      assert.strictEqual(wrapper.hasClass(classes.deletableColorSecondary), true);
+
+      const avatarWrapper = wrapper.childAt(0);
+
+      assert.strictEqual(avatarWrapper.hasClass(classes.avatar), true);
+      assert.strictEqual(avatarWrapper.hasClass(classes.avatarColorSecondary), true);
     });
   });
 
@@ -160,6 +264,43 @@ describe('<Chip />', () => {
       const wrapper = mount(<Chip label="Custom delete icon Chip" onDelete={() => {}} />);
       assert.strictEqual(wrapper.find(CancelIcon).length, 1);
     });
+
+    it('should render a default icon with the root, deletable and deleteIcon classes', () => {
+      const wrapper = shallow(<Chip label="Custom delete icon Chip" onDelete={() => {}} />);
+      assert.strictEqual(wrapper.hasClass(classes.root), true);
+      assert.strictEqual(wrapper.hasClass(classes.deletable), true);
+
+      const iconWrapper = wrapper.find(CancelIcon);
+      assert.strictEqual(iconWrapper.hasClass(classes.deleteIcon), true);
+    });
+
+    it('should render default icon with the root, deletable and deleteIcon primary class', () => {
+      const wrapper = shallow(
+        <Chip label="Custom delete icon Chip" onDelete={() => {}} color="primary" />,
+      );
+      assert.strictEqual(wrapper.hasClass(classes.root), true);
+      assert.strictEqual(wrapper.hasClass(classes.colorPrimary), true);
+      assert.strictEqual(wrapper.hasClass(classes.deletable), true);
+      assert.strictEqual(wrapper.hasClass(classes.deletableColorPrimary), true);
+
+      const iconWrapper = wrapper.find(CancelIcon);
+      assert.strictEqual(iconWrapper.hasClass(classes.deleteIcon), true);
+      assert.strictEqual(iconWrapper.hasClass(classes.deleteIconColorPrimary), true);
+    });
+
+    it('should render a default icon with the root, deletable, deleteIcon secondary class', () => {
+      const wrapper = shallow(
+        <Chip label="Custom delete icon Chip" onDelete={() => {}} color="secondary" />,
+      );
+      assert.strictEqual(wrapper.hasClass(classes.root), true);
+      assert.strictEqual(wrapper.hasClass(classes.colorSecondary), true);
+      assert.strictEqual(wrapper.hasClass(classes.deletable), true);
+      assert.strictEqual(wrapper.hasClass(classes.deletableColorSecondary), true);
+
+      const iconWrapper = wrapper.find(CancelIcon);
+      assert.strictEqual(iconWrapper.hasClass(classes.deleteIcon), true);
+      assert.strictEqual(iconWrapper.hasClass(classes.deleteIconColorSecondary), true);
+    });
   });
 
   describe('reacts to keyboard chip', () => {