-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
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
Changes from 4 commits
09250d6
6ab0e9c
df9bf25
c4c17ce
11c87b6
852cffe
8fcaca0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 badge will be added relativelty to this node. | | ||
| 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. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// @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 IconButton from 'material-ui/IconButton'; | ||
import ImageIcon from 'material-ui/svg-icons/image'; | ||
import FaceIcon from 'material-ui/svg-icons/face'; | ||
|
||
const styleSheet = createStyleSheet('FurtherBadge', () => ({ | ||
badge: { | ||
fontSize: 20, | ||
right: 12, | ||
}, | ||
})); | ||
|
||
export default function FurtherBadge(props, context) { | ||
const classes = context.styleManager.render(styleSheet); | ||
return ( | ||
<div className={classes.row}> | ||
<Badge badgeContent={<IconButton><FaceIcon /></IconButton>}> | ||
<ImageIcon /> | ||
</Badge> | ||
<Badge | ||
badgeContent="©" | ||
badgeClassName={classes.badge} | ||
> | ||
Company Name | ||
</Badge> | ||
</div> | ||
); | ||
} | ||
|
||
FurtherBadge.contextTypes = { | ||
styleManager: customPropTypes.muiRequired, | ||
}; |
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 IconButton from 'material-ui/IconButton'; | ||
import NotificationIcon from 'material-ui/svg-icons/notification'; | ||
|
||
const styleSheet = createStyleSheet('SimpleBadge', () => ({ | ||
badge: { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Two points here:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmmm @oliviertassinari , I didn't get that.
|
||
top: 12, | ||
right: 12, | ||
}, | ||
})); | ||
|
||
export default function SimpleBadge(props, context) { | ||
const classes = context.styleManager.render(styleSheet); | ||
return ( | ||
<div className={classes.row}> | ||
<Badge badgeContent={4} primary> | ||
<NotificationIcon /> | ||
</Badge> | ||
<Badge | ||
accent | ||
badgeClassName={classes.badge} | ||
badgeContent={10} | ||
> | ||
<IconButton> | ||
<NotificationIcon /> | ||
</IconButton> | ||
</Badge> | ||
</div> | ||
); | ||
} | ||
|
||
SimpleBadge.contextTypes = { | ||
styleManager: customPropTypes.muiRequired, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# 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'}} | ||
|
||
## Further examples | ||
|
||
Badges containing an Icon Button and text, applied to an icon, and text. | ||
|
||
{{demo='demos/badges/FurtherBadge.js'}} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
// @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', | ||
padding: `${radius2x}px ${radius2x}px ${radius}px ${radius}px`, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with @mbrookes. I don't think that the badge should impact the layout of the element. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. agree too. done |
||
}, | ||
badge: { | ||
display: 'flex', | ||
flexDirection: 'row', | ||
flexWrap: 'wrap', | ||
justifyContent: 'center', | ||
alignContent: 'center', | ||
alignItems: 'center', | ||
position: 'absolute', | ||
top: 0, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about? top: -radius, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
right: 0, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about? right: -radius, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
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, | ||
}; |
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, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. assert.strictEqual(wrapper.props().style.backgroundColor, style.backgroundColor, |
||
'should overwrite badge backgroundColor'); | ||
}); | ||
}); |
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'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
/* eslint-disable */ | ||
|
||
import React from 'react'; | ||
import pure from 'recompose/pure'; | ||
import SvgIcon from '../SvgIcon'; | ||
|
||
let Notification = (props) => ( | ||
<SvgIcon {...props}> | ||
<path d="M14,20A2,2 0 0,1 12,22A2,2 0 0,1 10,20H14M12,2A1,1 0 0,1 13,3V4.08C15.84,4.56 18,7.03 18,10V16L21,19H3L6,16V10C6,7.03 8.16,4.56 11,4.08V3A1,1 0 0,1 12,2Z"/> | ||
</SvgIcon> | ||
); | ||
Notification = pure(Notification); | ||
Notification.muiName = 'SvgIcon'; | ||
|
||
export default Notification; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo in
relatively
, but it should probably berelative
, and even then the sentence is awkward.How about simply "The node that the badge will be applied to."