From bc7ceac55e40b5ece72a1afefb3c642b95747a03 Mon Sep 17 00:00:00 2001 From: Nick Baroni Date: Tue, 3 Nov 2015 17:49:19 +0900 Subject: [PATCH] Added badge component. --- docs/src/app/app-routes.jsx | 2 + docs/src/app/components/pages/components.jsx | 1 + .../app/components/pages/components/badge.jsx | 88 +++++++++++++++ .../app/components/raw-code/badge-code.txt | 19 ++++ src/badge.jsx | 106 ++++++++++++++++++ src/index.js | 1 + src/styles/theme-manager.js | 8 ++ 7 files changed, 225 insertions(+) create mode 100644 docs/src/app/components/pages/components/badge.jsx create mode 100644 docs/src/app/components/raw-code/badge-code.txt create mode 100644 src/badge.jsx diff --git a/docs/src/app/app-routes.jsx b/docs/src/app/app-routes.jsx index fe37b92430b23b..7996d2d3f32d5b 100644 --- a/docs/src/app/app-routes.jsx +++ b/docs/src/app/app-routes.jsx @@ -22,6 +22,7 @@ const InlineStyles = require('./components/pages/customization/inline-styles'); const Components = require('./components/pages/components'); const AppBar = require('./components/pages/components/app-bar'); const Avatars = require('./components/pages/components/avatars'); +const Badge = require('./components/pages/components/badge'); const Buttons = require('./components/pages/components/buttons'); const Cards = require('./components/pages/components/cards'); const DatePicker = require('./components/pages/components/date-picker'); @@ -77,6 +78,7 @@ const AppRoutes = ( + diff --git a/docs/src/app/components/pages/components.jsx b/docs/src/app/components/pages/components.jsx index d7069c034cdf97..bc9787804cfff6 100644 --- a/docs/src/app/components/pages/components.jsx +++ b/docs/src/app/components/pages/components.jsx @@ -7,6 +7,7 @@ export default class Components extends React.Component { let menuItems = [ { route: '/components/appbar', text: 'AppBar'}, { route: '/components/avatars', text: 'Avatars'}, + { route: '/components/badge', text: 'Badge'}, { route: '/components/buttons', text: 'Buttons'}, { route: '/components/cards', text: 'Cards'}, { route: '/components/date-picker', text: 'Date Picker'}, diff --git a/docs/src/app/components/pages/components/badge.jsx b/docs/src/app/components/pages/components/badge.jsx new file mode 100644 index 00000000000000..6b3913bdcf4974 --- /dev/null +++ b/docs/src/app/components/pages/components/badge.jsx @@ -0,0 +1,88 @@ +let React = require('react'); +let { FontIcon, IconButton, Badge } = require('material-ui'); +let ComponentDoc = require('../../component-doc'); +let Code = require('badge-code'); +let CodeExample = require('../../code-example/code-example'); +const NotificationsIcon = require('svg-icons/social/notifications'); +const ShoppingCartIcon = require('svg-icons/action/shopping-cart'); +const FolderIcon = require('svg-icons/file/folder-open'); +const UploadIcon = require('svg-icons/file/cloud-upload'); + +export default class BadgePage extends React.Component { + constructor(props) { + super(props); + + this.desc = 'This component generates a small badge to the top-right of it\'s child(ren)'; + + this.componentInfo = [ + { + name: 'Props', + infoArray: [ + { + name: 'badgeContent', + type: 'node', + header: 'required', + desc: 'This is the content rendered within the badge.', + }, + { + name: 'primary', + type: 'bool', + header: 'default: false', + desc: 'If true, the badge will use the primary badge colors.', + }, + { + name: 'secondary', + type: 'bool', + header: 'default: false', + desc: 'If true, the badge will use the secondary badge colors.', + }, + { + name: 'style', + type: 'object', + header: 'optional', + desc: 'Override the inline-styles of the root element.', + }, + { + name: 'badgeStyle', + type: 'object', + header: 'optional', + desc: 'Override the inline-styles of the badge element.', + }, + ], + }, + ]; + } + + render() { + return ( + + + + + + + + + + + + + + }> + + + + +

Company Name

+
+ +
+
+ ); + } + +} diff --git a/docs/src/app/components/raw-code/badge-code.txt b/docs/src/app/components/raw-code/badge-code.txt new file mode 100644 index 00000000000000..b81afb780a8e95 --- /dev/null +++ b/docs/src/app/components/raw-code/badge-code.txt @@ -0,0 +1,19 @@ + + + + +//override badgeStyle to account for padding of child element + + + + + + +}> + + + + +

Company Name

+
\ No newline at end of file diff --git a/src/badge.jsx b/src/badge.jsx new file mode 100644 index 00000000000000..935ddbb9934265 --- /dev/null +++ b/src/badge.jsx @@ -0,0 +1,106 @@ +const React = require('react'); +const Typography = require('./styles/typography'); +const DefaultRawTheme = require('./styles/raw-themes/light-raw-theme'); +const ThemeManager = require('./styles/theme-manager'); +const StylePropable = require('./mixins/style-propable'); + +// Badge +export default React.createClass({ + displayName: 'Badge', + mixins: [StylePropable], + contextTypes: { + muiTheme: React.PropTypes.object, + }, + //for passing default theme context to children + childContextTypes: { + muiTheme: React.PropTypes.object, + }, + getChildContext () { + return { + muiTheme: this.state.muiTheme, + }; + }, + propTypes: { + className: React.PropTypes.string, + badgeContent: React.PropTypes.node.isRequired, + primary: React.PropTypes.bool, + secondary: React.PropTypes.bool, + style: React.PropTypes.object, + badgeStyle: React.PropTypes.object, + }, + getInitialState() { + return { + muiTheme: this.context.muiTheme ? this.context.muiTheme : ThemeManager.getMuiTheme(DefaultRawTheme), + }; + }, + getDefaultProps() { + return { + className: '', + primary: false, + secondary: false, + style: {}, + badgeStyle: {}, + }; + }, + componentWillReceiveProps(nextProps, nextContext) { + let newMuiTheme = nextContext.muiTheme ? nextContext.muiTheme : this.state.muiTheme; + this.setState({ + muiTheme: newMuiTheme, + }); + }, + getStyles() { + const theme = this.state.muiTheme.badge; + + const badgeBackgroundColor = this.props.primary + ? theme.primaryColor + : this.props.secondary + ? theme.secondaryColor + : theme.color; + + const badgeTextColor = this.props.primary + ? theme.primaryTextColor + : this.props.secondary + ? theme.secondaryTextColor + : theme.textColor; + + const radius = 12; + const radius2x = Math.floor(2*radius); + + return { + root: { + position: 'relative', + display: 'inline-block', + padding: [radius2x+'px', radius2x+'px', radius+'px', radius+'px'].join(' '), + }, + badge: { + display: 'flex', + flexDirection: 'row', + flexWrap: 'wrap', + justifyContent: 'center', + alignContent: 'center', + alignItems: 'center', + position: 'absolute', + top: 0, + right: 0, + fontWeight: Typography.fontWeightMedium, + fontSize: radius, + width: radius2x, + height: radius2x, + borderRadius: '50%', + backgroundColor: badgeBackgroundColor, + color: badgeTextColor, + }, + }; + }, + render() { + const styles = this.getStyles(); + return ( +
+ {this.props.children} + + {this.props.badgeContent} + +
+ ); + }, +}); diff --git a/src/index.js b/src/index.js index 31edeb6eae7fdb..8eac4857d27557 100644 --- a/src/index.js +++ b/src/index.js @@ -2,6 +2,7 @@ module.exports = { AppBar: require('./app-bar'), AppCanvas: require('./app-canvas'), Avatar: require('./avatar'), + Badge: require('./badge'), BeforeAfterWrapper: require('./before-after-wrapper'), Card: require('./card/card'), CardActions: require('./card/card-actions'), diff --git a/src/styles/theme-manager.js b/src/styles/theme-manager.js index 65abe773162553..90243ab5aa0139 100644 --- a/src/styles/theme-manager.js +++ b/src/styles/theme-manager.js @@ -16,6 +16,14 @@ module.exports = { avatar: { borderColor: 'rgba(0, 0, 0, 0.08)', }, + badge: { + color: rawTheme.palette.alternateTextColor, + textColor: rawTheme.palette.textColor, + primaryColor: rawTheme.palette.accent1Color, + primaryTextColor: rawTheme.palette.alternateTextColor, + secondaryColor: rawTheme.palette.primary1Color, + secondaryTextColor: rawTheme.palette.alternateTextColor, + }, button: { height: 36, minWidth: 88,