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'),