diff --git a/docs/api/Badge/Badge.md b/docs/api/Badge/Badge.md
new file mode 100644
index 00000000000000..f0cf3808cec141
--- /dev/null
+++ b/docs/api/Badge/Badge.md
@@ -0,0 +1,18 @@
+Badge
+======
+
+
+
+Props
+-----
+
+| Name | Type | Default | Description |
+|:-----|:-----|:--------|:------------|
+| accent | bool | false | If true, the badge will use the accent badge colors. |
+| badgeClassName | string | | The CSS class name of the badge element. |
+| badgeContent * | node | | This is the content rendered within the badge. |
+| children * | node | | The node that the badge will be applied to. |
+| className | string | | The CSS class name of the root element. |
+| primary | bool | false | If true, the badge will use the primary badge colors. |
+
+Any other properties supplied will be spread to the root element.
diff --git a/docs/site/src/demos/badges/SimpleBadge.js b/docs/site/src/demos/badges/SimpleBadge.js
new file mode 100644
index 00000000000000..696f9fbb91022a
--- /dev/null
+++ b/docs/site/src/demos/badges/SimpleBadge.js
@@ -0,0 +1,39 @@
+// @flow weak
+
+import React from 'react';
+import { createStyleSheet } from 'jss-theme-reactor';
+import Badge from 'material-ui/Badge';
+import customPropTypes from 'material-ui/utils/customPropTypes';
+import Icon from 'material-ui/Icon';
+
+const styleSheet = createStyleSheet('SimpleBadge', () => ({
+ badge: {
+ margin: '0 20px',
+ },
+}));
+
+export default function SimpleBadge(props, context) {
+ const classes = context.styleManager.render(styleSheet);
+ return (
+
+
+ mail
+
+
+ folder
+
+
+ );
+}
+
+SimpleBadge.contextTypes = {
+ styleManager: customPropTypes.muiRequired,
+};
diff --git a/docs/site/src/demos/badges/badges.md b/docs/site/src/demos/badges/badges.md
new file mode 100644
index 00000000000000..068cbdb7ff6b02
--- /dev/null
+++ b/docs/site/src/demos/badges/badges.md
@@ -0,0 +1,10 @@
+# Badge
+
+Badge generates a small badge to the top-right of its child(ren).
+
+## Simple examples
+
+Two examples of badges containing text, using primary and secondary colors. The badge is applied to its children - an icon for the first example, and an Icon Button with tooltip for the second.
+
+{{demo='demos/badges/SimpleBadge.js'}}
+
diff --git a/src/Badge/Badge.js b/src/Badge/Badge.js
new file mode 100644
index 00000000000000..b18d333269f72b
--- /dev/null
+++ b/src/Badge/Badge.js
@@ -0,0 +1,113 @@
+// @flow weak
+
+import React, { PropTypes } from 'react';
+import classNames from 'classnames';
+import { createStyleSheet } from 'jss-theme-reactor';
+import customPropTypes from '../utils/customPropTypes';
+
+const radius = 12;
+const radius2x = 2 * radius;
+
+export const styleSheet = createStyleSheet('Badge', (theme) => {
+ const { typography, palette } = theme;
+
+ return {
+ root: {
+ position: 'relative',
+ display: 'inline-block',
+ },
+ badge: {
+ display: 'flex',
+ flexDirection: 'row',
+ flexWrap: 'wrap',
+ justifyContent: 'center',
+ alignContent: 'center',
+ alignItems: 'center',
+ position: 'absolute',
+ top: `-${radius}px`,
+ right: `-${radius}px`,
+ fontWeight: typography.fontWeight,
+ fontSize: radius,
+ width: radius2x,
+ height: radius2x,
+ borderRadius: '50%',
+ backgroundColor: palette.color,
+ color: palette.textColor,
+ },
+ primary: {
+ backgroundColor: palette.primary[500],
+ color: palette.getContrastText(palette.primary[500]),
+ },
+ accent: {
+ backgroundColor: palette.accent.A200,
+ color: palette.getContrastText(palette.accent.A200),
+ },
+ };
+});
+
+export default function Badge(props, context) {
+ const {
+ badgeClassName: badgeClassNameProp,
+ badgeContent,
+ className: classNameProp,
+ children,
+ primary,
+ accent,
+ ...other
+ } = props;
+
+ const classes = context.styleManager.render(styleSheet);
+ const className = classNames({
+ [classes.root]: true,
+ }, classNameProp);
+ const badgeClassName = classNames({
+ [classes.badge]: true,
+ [classes.primary]: primary,
+ [classes.accent]: accent,
+ }, badgeClassNameProp);
+
+ return (
+
+ {children}
+
+ {badgeContent}
+
+
+ );
+}
+
+Badge.propTypes = {
+ /**
+ * If true, the badge will use the accent badge colors.
+ */
+ accent: PropTypes.bool,
+ /**
+ * The css class name of the badge element.
+ */
+ badgeClassName: PropTypes.string,
+ /**
+ * This is the content rendered within the badge.
+ */
+ badgeContent: PropTypes.node.isRequired,
+ /**
+ * The badge will be added relativelty to this node.
+ */
+ children: PropTypes.node.isRequired,
+ /**
+ * The css class name of the root element.
+ */
+ className: PropTypes.string,
+ /**
+ * If true, the badge will use the primary badge colors.
+ */
+ primary: PropTypes.bool,
+};
+
+Badge.defaultProps = {
+ primary: false,
+ accent: false,
+};
+
+Badge.contextTypes = {
+ styleManager: customPropTypes.muiRequired,
+};
diff --git a/src/Badge/Badge.spec.js b/src/Badge/Badge.spec.js
new file mode 100644
index 00000000000000..8583ad96423b7c
--- /dev/null
+++ b/src/Badge/Badge.spec.js
@@ -0,0 +1,89 @@
+// @flow weak
+/* eslint-env mocha */
+import React from 'react';
+import { createShallowWithContext } from 'test/utils';
+import { assert } from 'chai';
+import Badge, { styleSheet } from './Badge';
+
+describe('', () => {
+ let shallow;
+ let classes;
+
+ before(() => {
+ shallow = createShallowWithContext();
+ classes = shallow.context.styleManager.render(styleSheet);
+ });
+
+ const testChildren = Hello World
;
+
+ it('renders children and badgeContent', () => {
+ const wrapper = shallow(
+ {testChildren},
+ );
+
+ assert.strictEqual(wrapper.contains(testChildren), true, 'should contain the children');
+ assert.ok(wrapper.find('span').length, 'should contain the badgeContent');
+ });
+
+ it('renders children and overwrite badge class', () => {
+ const badgeClassName = 'testBadgeClassName';
+
+ const wrapper = shallow(
+ {testChildren},
+ );
+
+ assert.strictEqual(wrapper.contains(testChildren), true, 'should contain the children');
+ assert.strictEqual(wrapper.find('span').hasClass('testBadgeClassName'), true,
+ 'should contain the badgeClassName');
+ });
+
+ it('renders children by default', () => {
+ const wrapper = shallow(
+ {testChildren},
+ );
+
+ assert.strictEqual(wrapper.contains(testChildren), true, 'should contain the children');
+ });
+
+ it('renders children and className', () => {
+ const wrapper = shallow(
+ {testChildren},
+ );
+
+ assert.strictEqual(wrapper.contains(testChildren), true, 'should contain the children');
+ assert.strictEqual(wrapper.is('.testClassName'), true, 'should contain the className');
+ });
+
+ it('renders children and have primary styles', () => {
+ const wrapper = shallow(
+ {testChildren},
+ );
+
+ assert.strictEqual(wrapper.contains(testChildren), true, 'should contain the children');
+ assert.strictEqual(wrapper.find('span').hasClass(classes.primary), true,
+ 'should have primary class');
+ });
+
+ it('renders children and have accent styles', () => {
+ const wrapper = shallow(
+ {testChildren},
+ );
+
+ assert.strictEqual(wrapper.contains(testChildren), true, 'should contain the children');
+ assert.strictEqual(wrapper.find('span').hasClass(classes.accent), true,
+ 'should have accent class');
+ });
+
+ it('renders children and overwrite root styles', () => {
+ const style = {
+ backgroundColor: 'red',
+ };
+ const wrapper = shallow(
+ {testChildren},
+ );
+
+ assert.strictEqual(wrapper.contains(testChildren), true, 'should contain the children');
+ assert.strictEqual(wrapper.node.props.style.backgroundColor, style.backgroundColor,
+ 'should overwrite badge backgroundColor');
+ });
+});
diff --git a/src/Badge/index.js b/src/Badge/index.js
new file mode 100644
index 00000000000000..40b8b2acdc3ba9
--- /dev/null
+++ b/src/Badge/index.js
@@ -0,0 +1,3 @@
+/* eslint-disable flowtype/require-valid-file-annotation */
+
+export default from './Badge';
diff --git a/test/regressions/site/src/tests/Badge/Badge.js b/test/regressions/site/src/tests/Badge/Badge.js
new file mode 100644
index 00000000000000..d680b36a7b2518
--- /dev/null
+++ b/test/regressions/site/src/tests/Badge/Badge.js
@@ -0,0 +1,13 @@
+// @flow weak
+
+import React from 'react';
+import Badge from 'material-ui/Badge';
+import Icon from 'material-ui/Icon';
+
+export default function SimpleBadge() {
+ return (
+
+ mail
+
+ );
+}