diff --git a/docs/src/app/app-routes.jsx b/docs/src/app/app-routes.jsx index 1ca7b72ff4ad2d..c3bef24ac028de 100644 --- a/docs/src/app/app-routes.jsx +++ b/docs/src/app/app-routes.jsx @@ -19,6 +19,7 @@ var Components = require('./components/pages/components.jsx'); var AppBar = require('./components/pages/components/app-bar.jsx'); var Avatars = require('./components/pages/components/avatars.jsx'); var Buttons = require('./components/pages/components/buttons.jsx'); +var Cards = require('./components/pages/components/cards.jsx'); var DatePicker = require('./components/pages/components/date-picker.jsx'); var Dialog = require('./components/pages/components/dialog.jsx'); var DropDownMenu = require('./components/pages/components/drop-down-menu.jsx'); @@ -62,6 +63,7 @@ var AppRoutes = ( + diff --git a/docs/src/app/components/pages/components.jsx b/docs/src/app/components/pages/components.jsx index 97838deef3939e..74c7e23c532b6d 100644 --- a/docs/src/app/components/pages/components.jsx +++ b/docs/src/app/components/pages/components.jsx @@ -8,6 +8,7 @@ class Components extends React.Component { { route: 'appbar', text: 'AppBar'}, { route: 'avatars', text: 'Avatars'}, { route: 'buttons', text: 'Buttons'}, + { route: 'cards', text: 'Cards'}, { route: 'date-picker', text: 'Date Picker'}, { route: 'dialog', text: 'Dialog'}, { route: 'dropdown-menu', text: 'Dropdown Menu'}, diff --git a/docs/src/app/components/pages/components/cards.jsx b/docs/src/app/components/pages/components/cards.jsx new file mode 100644 index 00000000000000..6de52164dcb2b5 --- /dev/null +++ b/docs/src/app/components/pages/components/cards.jsx @@ -0,0 +1,88 @@ +var React = require('react'); +var mui = require('mui'); +var ComponentDoc = require('../../component-doc.jsx'); +var {Card, CardMedia, CardTitle, CardActions, CardText, CardHeader, FlatButton, Avatar} = mui; + +class CardPage extends React.Component { + + constructor(props) { + super(props); + + this.code = ` + + A}/> + + }> + + + + + + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. + Donec mattis pretium massa. Aliquam erat volutpat. Nulla facilisi. + Donec vulputate interdum sollicitudin. Nunc lacinia auctor quam sed pellentesque. + Aliquam dui mauris, mattis quis lacus id, pellentesque lobortis odio. + + `; + + this.desc = + 'A card is a piece of paper with unique related data that serves as an '+ + 'entry point to more detailed information. For example, a card could '+ + 'contain a photo, text, and a link about a single subject.'+ + '\n\n'+ + 'Cards have a constant width and variable height. The maximum height is '+ + 'limited to the height of the available space on a platform, '+ + 'but it can temporarily expand (for example, to display a comment field). '+ + 'Cards do not flip over to reveal information on the back.'; + + + this.componentInfo = []; + } + + render() { + return ( + + + A}/> + + }> + + + + + + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. + Donec mattis pretium massa. Aliquam erat volutpat. Nulla facilisi. + Donec vulputate interdum sollicitudin. Nunc lacinia auctor quam sed pellentesque. + Aliquam dui mauris, mattis quis lacus id, pellentesque lobortis odio. + + + + ); + } + +} + +module.exports = CardPage; diff --git a/src/avatar.jsx b/src/avatar.jsx index 1d78030195253c..0b2cd521f45951 100644 --- a/src/avatar.jsx +++ b/src/avatar.jsx @@ -45,6 +45,7 @@ var SvgIcon = React.createClass({ borderRadius: '50%', border: src ? 'solid 1px' : 'none', borderColor: this.context.muiTheme.palette.borderColor, + display:'inline-block', //Needed for letter avatars textAlign: 'center', diff --git a/src/card/card-actions.jsx b/src/card/card-actions.jsx new file mode 100644 index 00000000000000..ad5b862c0a77e4 --- /dev/null +++ b/src/card/card-actions.jsx @@ -0,0 +1,29 @@ +var React = require('react'); +var Styles = require('../styles'); + +var CardActions = React.createClass({ + getStyles: function () { + return { + root: { + padding: 8 + } + } + }, + render: function () { + var styles = this.getStyles(); + + var children = React.Children.map(this.props.children, function (child) { + return React.cloneElement(child, { + style: {marginRight: 8} + }); + }); + + return ( +
+ {children} +
+ ); + } +}); + +module.exports = CardActions; diff --git a/src/card/card-header.jsx b/src/card/card-header.jsx new file mode 100644 index 00000000000000..476ea3730d9b9c --- /dev/null +++ b/src/card/card-header.jsx @@ -0,0 +1,69 @@ +var React = require('react'); +var Styles = require('../styles'); +var Avatar = require('../avatar'); + +var CardHeader = React.createClass({ + propTypes: { + avatar: React.PropTypes.string, + title: React.PropTypes.string, + titleColor: React.PropTypes.string, + subtitle: React.PropTypes.string, + subtitleColor: React.PropTypes.string + }, + getDefaultProps: function () { + return { + titleColor: Styles.Colors.darkBlack, + subtitleColor: Styles.Colors.lightBlack + }; + }, + getStyles: function () { + return { + root: { + height: 72, + padding: 16, + fontWeight: Styles.Typography.fontWeightMedium, + boxSizing: 'border-box' + }, + text: { + display: 'inline-block', + verticalAlign: 'top' + }, + avatar: { + marginRight:16 + }, + title: { + color: this.props.titleColor, + display: 'block', + fontSize: 15 + }, + subtitle: { + color: this.props.subtitleColor, + display: 'block', + fontSize: 14 + } + } + }, + render: function () { + var styles = this.getStyles(); + var avatar = this.props.avatar; + + if (React.isValidElement(this.props.avatar)) + avatar = React.cloneElement(avatar, {style:styles.avatar}) + else + avatar = + + + + return ( +
+ {avatar} +
+ {this.props.title} + {this.props.subtitle} +
+
+ ); + } +}); + +module.exports = CardHeader; diff --git a/src/card/card-media.jsx b/src/card/card-media.jsx new file mode 100644 index 00000000000000..db5d3f0581ab33 --- /dev/null +++ b/src/card/card-media.jsx @@ -0,0 +1,81 @@ +var React = require('react'); +var Styles = require('../styles'); + +var CardMedia = React.createClass({ + propTypes: { + overlay: React.PropTypes.node + }, + getStyles: function () { + return { + root: { + position: 'relative' + }, + overlayContainer: { + position: 'absolute', + top: 0, + bottom: 0, + right: 0, + left: 0 + }, + overlay: { + height: '100%', + position: 'relative' + }, + overlayContent: { + position: 'absolute', + bottom: 0, + right: 0, + left: 0, + paddingTop: 8, + background: Styles.Colors.lightBlack + } + }; + }, + render: function () { + var styles = this.getStyles(); + + var children = React.Children.map(this.props.children, function (child) { + return React.cloneElement(child, { + style: { + verticalAlign: 'top', + maxWidth: '100%', + minWidth: '100%' + } + }); + }); + + var overlayChildren = React.Children.map(this.props.overlay, function (child) { + if (child.type.displayName === 'CardHeader' || child.type.displayName === 'CardTitle' + ) { + return React.cloneElement(child, { + titleColor: Styles.Colors.darkWhite, + subtitleColor: Styles.Colors.lightWhite + }); + } else if (child.type.displayName === 'CardText') { + return React.cloneElement(child, { + color: Styles.Colors.darkWhite + }); + } else { + return child; + } + }); + + return ( +
+
+ {children} +
+ {(this.props.overlay) ? +
+
+
+ {overlayChildren} +
+
+
: ''} +
+ ); + } +}); + +module.exports = CardMedia; diff --git a/src/card/card-text.jsx b/src/card/card-text.jsx new file mode 100644 index 00000000000000..cfa5d6c7e5e482 --- /dev/null +++ b/src/card/card-text.jsx @@ -0,0 +1,33 @@ +var React = require('react'); +var Styles = require('../styles'); + +var CardText = React.createClass({ + propTypes: { + color: React.PropTypes.string + }, + getDefaultProps: function () { + return { + color: Styles.Colors.ck + } + }, + getStyles: function () { + return { + root: { + padding: 16, + fontSize: '14px', + color: this.props.color + } + } + }, + render: function () { + var styles = this.getStyles(); + + return ( +
+ {this.props.children} +
+ ); + } +}); + +module.exports = CardText; diff --git a/src/card/card-title.jsx b/src/card/card-title.jsx new file mode 100644 index 00000000000000..59d2193717256f --- /dev/null +++ b/src/card/card-title.jsx @@ -0,0 +1,47 @@ +var React = require('react'); +var Styles = require('../styles'); + +var CardTitle = React.createClass({ + propTypes: { + title: React.PropTypes.string, + titleColor: React.PropTypes.string, + subtitle: React.PropTypes.string, + subtitleColor: React.PropTypes.string + }, + getDefaultProps: function () { + return { + titleColor: Styles.Colors.darkBlack, + subtitleColor: Styles.Colors.lightBlack + }; + }, + getStyles: function () { + return { + root: { + padding: 16 + }, + title: { + fontSize: 24, + color: this.props.titleColor, + display: 'block', + lineHeight: '36px' + }, + subtitle: { + fontSize: 14, + color: this.props.subtitleColor, + display: 'block' + } + } + }, + render: function () { + var styles = this.getStyles(); + + return ( +
+ {this.props.title} + {this.props.subtitle} +
+ ); + } +}); + +module.exports = CardTitle; diff --git a/src/card/card.jsx b/src/card/card.jsx new file mode 100644 index 00000000000000..07e22ad8f301c6 --- /dev/null +++ b/src/card/card.jsx @@ -0,0 +1,40 @@ +var React = require('react'); +var Paper = require('../paper'); +var StylePropable = require('../mixins/style-propable'); + +var Card = React.createClass({ + mixins:[StylePropable], + + propTypes: { + zDepth: React.PropTypes.oneOf([0, 1, 2, 3, 4, 5]) + }, + render: function () { + var lastElement = React.Children.count(this.props.children) > 1 ? + this.props.children[this.props.children.length - 1] + : this.props.children; + + // If the last element is text or a title we should add + // 8px padding to the bottom of the card + var addBottomPadding = (lastElement.type.displayName === "CardText" || + lastElement.type.displayName === "CardTitle"); + var { + style, + ...other + } = this.props; + + var mergedStyles = this.mergeAndPrefix({ + overflow: 'hidden', + zIndex: 1 + }, style); + + return ( + +
+ {this.props.children} +
+
+ ); + } +}); + +module.exports = Card; diff --git a/src/card/index.js b/src/card/index.js new file mode 100644 index 00000000000000..26141acccb160f --- /dev/null +++ b/src/card/index.js @@ -0,0 +1,8 @@ +module.exports = { + Card: require('./card'), + CardHeader: require('./card-header'), + CardTitle: require('./card-title'), + CardMedia: require('./card-media'), + CardText: require('./card-text'), + CardActions: require('./card-actions') +}; diff --git a/src/index.js b/src/index.js index 4738ce5696c330..3f50317857386c 100644 --- a/src/index.js +++ b/src/index.js @@ -3,6 +3,12 @@ module.exports = { AppCanvas: require('./app-canvas'), Avatar: require('./avatar'), BeforeAfterWrapper: require('./before-after-wrapper'), + Card: require('./card/card'), + CardActions: require('./card/card-actions'), + CardHeader: require('./card/card-header'), + CardMedia: require('./card/card-media'), + CardText: require('./card/card-text'), + CardTitle: require('./card/card-title'), Checkbox: require('./checkbox'), CircularProgress: require('./circular-progress'), ClearFix: require('./clearfix'),