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

[Badge] Port Badge Component #6043

Merged
merged 7 commits into from
Feb 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions docs/api/Badge/Badge.md
Original file line number Diff line number Diff line change
@@ -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. |
| <span style="color: #31a148">badgeContent *</span> | node | | This is the content rendered within the badge. |
| <span style="color: #31a148">children *</span> | 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.
39 changes: 39 additions & 0 deletions docs/site/src/demos/badges/SimpleBadge.js
Original file line number Diff line number Diff line change
@@ -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 (
<div className={classes.row}>
<Badge
badgeContent={4}
className={classes.badge}
primary
>
<Icon>mail</Icon>
</Badge>
<Badge
accent
badgeContent={10}
className={classes.badge}
>
<Icon>folder</Icon>
</Badge>
</div>
);
}

SimpleBadge.contextTypes = {
styleManager: customPropTypes.muiRequired,
};
10 changes: 10 additions & 0 deletions docs/site/src/demos/badges/badges.md
Original file line number Diff line number Diff line change
@@ -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'}}

113 changes: 113 additions & 0 deletions src/Badge/Badge.js
Original file line number Diff line number Diff line change
@@ -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 (
<div className={className} {...other}>
{children}
<span className={badgeClassName}>
{badgeContent}
</span>
</div>
);
}

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,
};
89 changes: 89 additions & 0 deletions src/Badge/Badge.spec.js
Original file line number Diff line number Diff line change
@@ -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('<Badge />', () => {
let shallow;
let classes;

before(() => {
shallow = createShallowWithContext();
classes = shallow.context.styleManager.render(styleSheet);
});

const testChildren = <div className="unique">Hello World</div>;

it('renders children and badgeContent', () => {
const wrapper = shallow(
<Badge badgeContent={10}>{testChildren}</Badge>,
);

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(
<Badge badgeContent={10} badgeClassName={badgeClassName}>{testChildren}</Badge>,
);

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(
<Badge badgeContent={10}>{testChildren}</Badge>,
);

assert.strictEqual(wrapper.contains(testChildren), true, 'should contain the children');
});

it('renders children and className', () => {
const wrapper = shallow(
<Badge badgeContent={10} className="testClassName">{testChildren}</Badge>,
);

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(
<Badge badgeContent={10} primary>{testChildren}</Badge>,
);

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(
<Badge badgeContent={10} accent>{testChildren}</Badge>,
);

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(
<Badge badgeContent={10} style={style}>{testChildren}</Badge>,
);

assert.strictEqual(wrapper.contains(testChildren), true, 'should contain the children');
assert.strictEqual(wrapper.node.props.style.backgroundColor, style.backgroundColor,
Copy link
Member

Choose a reason for hiding this comment

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

assert.strictEqual(wrapper.props().style.backgroundColor, style.backgroundColor,

'should overwrite badge backgroundColor');
});
});
3 changes: 3 additions & 0 deletions src/Badge/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/* eslint-disable flowtype/require-valid-file-annotation */

export default from './Badge';
13 changes: 13 additions & 0 deletions test/regressions/site/src/tests/Badge/Badge.js
Original file line number Diff line number Diff line change
@@ -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 (
<Badge badgeContent={1} primary>
<Icon>mail</Icon>
</Badge>
);
}