diff --git a/docs/src/app/components/pages/components/cards.jsx b/docs/src/app/components/pages/components/cards.jsx
index e8ff67845e3145..41e0e3eebb11b1 100644
--- a/docs/src/app/components/pages/components/cards.jsx
+++ b/docs/src/app/components/pages/components/cards.jsx
@@ -6,6 +6,7 @@ let {
Avatar,
Card,
CardActions,
+ CardExpandable,
CardHeader,
CardMedia,
CardText,
@@ -43,6 +44,30 @@ class CardPage extends React.Component {
Donec vulputate interdum sollicitudin. Nunc lacinia auctor quam sed pellentesque.
Aliquam dui mauris, mattis quis lacus id, pellentesque lobortis odio.
+
+
+ A}
+ showExpandableButton={true}>
+
+
+ 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.
+
+
+
+
+
+
+ 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 =
@@ -56,7 +81,38 @@ class CardPage extends React.Component {
'Cards do not flip over to reveal information on the back.';
- this.componentInfo = [];
+ this.componentInfo = [
+ {
+ name: 'Card.Props',
+ infoArray: [
+ {
+ name: 'initiallyExpanded',
+ type: 'bool',
+ header: 'optional',
+ desc: 'Whether this card is initially expanded.',
+ },
+ ],
+ },
+ {
+ name: 'Props',
+ infoArray: [
+ {
+ name: 'expandable',
+ type: 'bool',
+ header: 'optional',
+ desc: 'Whether this card component is expandable. Can be set on any child of the Card component.',
+ },
+ {
+ name: 'showExpandableButton',
+ type: 'bool',
+ header: 'optional',
+ desc: 'Whether this card component include a button to expand the card. CardTitle, CardHeader ' +
+ 'and CardActions implement showExpandableButton. Any child component of Card can implements ' +
+ 'showExpandableButton or forwards the property to a child component supporting it.',
+ },
+ ],
+ },
+ ];
}
render() {
@@ -90,6 +146,31 @@ class CardPage extends React.Component {
Aliquam dui mauris, mattis quis lacus id, pellentesque lobortis odio.
+
+
+ A}
+ showExpandableButton={true}>
+
+
+ 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.
+
+
+
+
+
+
+ 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.
+
+
);
}
diff --git a/src/card/card-actions.jsx b/src/card/card-actions.jsx
index 2aa120d7e64b69..235836475e9ff2 100644
--- a/src/card/card-actions.jsx
+++ b/src/card/card-actions.jsx
@@ -5,10 +5,16 @@ let CardActions = React.createClass({
return {
root: {
padding: 8,
+ position: 'relative',
},
};
},
+ propTypes: {
+ expandable: React.PropTypes.bool,
+ showExpandableButton: React.PropTypes.bool,
+ },
+
render() {
let styles = this.getStyles();
diff --git a/src/card/card-expandable.jsx b/src/card/card-expandable.jsx
new file mode 100644
index 00000000000000..8931c4ce8fefd8
--- /dev/null
+++ b/src/card/card-expandable.jsx
@@ -0,0 +1,53 @@
+let React = require('react');
+let OpenIcon = require('../svg-icons/hardware/keyboard-arrow-up');
+let CloseIcon = require('../svg-icons/hardware/keyboard-arrow-down');
+let IconButton = require('../icon-button');
+
+let CardExpandable = React.createClass({
+ getStyles() {
+ return {
+ root: {
+ right: 4,
+ top: 0,
+ bottom: 0,
+ margin: 'auto',
+ position: 'absolute',
+ },
+ };
+ },
+
+ propTypes: {
+ onExpanding: React.PropTypes.func.isRequired,
+ expanded: React.PropTypes.bool,
+ },
+
+ _onExpanding() {
+ if (this.props.expanded === true)
+ this.props.onExpanding(false);
+ else
+ this.props.onExpanding(true);
+ },
+
+ render() {
+ let styles = this.getStyles();
+
+ let expandable;
+ if (this.props.expanded === true)
+ expandable = ;
+ else
+ expandable = ;
+
+ let expandableBtn = (
+
+ {expandable}
+
+ );
+
+
+ return expandableBtn;
+ },
+});
+
+module.exports = CardExpandable;
diff --git a/src/card/card-header.jsx b/src/card/card-header.jsx
index 7b0016e2041e0c..0e4018b23ebfc2 100644
--- a/src/card/card-header.jsx
+++ b/src/card/card-header.jsx
@@ -16,6 +16,8 @@ let CardHeader = React.createClass({
subtitleColor: React.PropTypes.string,
subtitleStyle: React.PropTypes.object,
textStyle: React.PropTypes.object,
+ expandable: React.PropTypes.bool,
+ showExpandableButton: React.PropTypes.bool,
},
getDefaultProps() {
@@ -32,6 +34,7 @@ let CardHeader = React.createClass({
padding: 16,
fontWeight: Styles.Typography.fontWeightMedium,
boxSizing: 'border-box',
+ position: 'relative',
},
text: {
display: 'inline-block',
@@ -75,6 +78,7 @@ let CardHeader = React.createClass({
{this.props.title}
{this.props.subtitle}
+ {this.props.children}
);
},
diff --git a/src/card/card-media.jsx b/src/card/card-media.jsx
index 6dfd8b4a5b6fec..f2395cfcc0f3a3 100644
--- a/src/card/card-media.jsx
+++ b/src/card/card-media.jsx
@@ -14,6 +14,7 @@ let CardMedia = React.createClass({
overlayContainerStyle: React.PropTypes.object,
overlayContentStyle: React.PropTypes.object,
mediaStyle: React.PropTypes.object,
+ expandable: React.PropTypes.bool,
},
getStyles() {
diff --git a/src/card/card-text.jsx b/src/card/card-text.jsx
index b5cc8bc3440074..1c2235a71d937d 100644
--- a/src/card/card-text.jsx
+++ b/src/card/card-text.jsx
@@ -10,6 +10,7 @@ let CardText = React.createClass({
propTypes: {
color: React.PropTypes.string,
style: React.PropTypes.object,
+ expandable: React.PropTypes.bool,
},
getDefaultProps() {
diff --git a/src/card/card-title.jsx b/src/card/card-title.jsx
index 8ed497b6690f16..630400536e4f63 100644
--- a/src/card/card-title.jsx
+++ b/src/card/card-title.jsx
@@ -14,6 +14,8 @@ let CardTitle = React.createClass({
subtitle: React.PropTypes.string,
subtitleColor: React.PropTypes.string,
subtitleStyle: React.PropTypes.object,
+ expandable: React.PropTypes.bool,
+ showExpandableButton: React.PropTypes.bool,
},
getDefaultProps() {
@@ -27,6 +29,7 @@ let CardTitle = React.createClass({
return {
root: {
padding: 16,
+ position: 'relative',
},
title: {
fontSize: 24,
@@ -52,6 +55,7 @@ let CardTitle = React.createClass({
{this.props.title}
{this.props.subtitle}
+ {this.props.children}
);
},
diff --git a/src/card/card.jsx b/src/card/card.jsx
index 6b61e2357974fd..3ebb6d6b450751 100644
--- a/src/card/card.jsx
+++ b/src/card/card.jsx
@@ -1,24 +1,47 @@
let React = require('react');
let Paper = require('../paper');
let StylePropable = require('../mixins/style-propable');
-
+let CardExpandable = require('./card-expandable');
let Card = React.createClass({
mixins:[StylePropable],
+ getInitialState() {
+ return { expanded: this.props.initiallyExpanded ? true : false };
+ },
+
propTypes: {
style: React.PropTypes.object,
+ expandable: React.PropTypes.bool,
+ initiallyExpanded: React.PropTypes.bool,
+ },
+
+ _onExpandable(value) {
+ this.setState({expanded: value});
},
render() {
- let lastElement = React.Children.count(this.props.children) > 1 ?
- this.props.children[this.props.children.length - 1]
- : this.props.children;
+ let lastElement;
+ let newChildren = React.Children.map(this.props.children, (currentChild) => {
+ if (!currentChild) {
+ return null;
+ }
+ if (this.state.expanded === false && currentChild.props.expandable === true)
+ return;
+ if (currentChild.props.showExpandableButton === true) {
+ lastElement = React.cloneElement(currentChild, {},
+ currentChild.props.children,
+ );
+ } else {
+ lastElement = currentChild;
+ }
+ return lastElement;
+ }, this);
// If the last element is text or a title we should add
// 8px padding to the bottom of the card
- let addBottomPadding = (lastElement.type.displayName === "CardText" ||
- lastElement.type.displayName === "CardTitle");
+ let addBottomPadding = (lastElement && (lastElement.type.displayName === "CardText" ||
+ lastElement.type.displayName === "CardTitle"));
let {
style,
...other,
@@ -32,7 +55,7 @@ let Card = React.createClass({
return (
- {this.props.children}
+ {newChildren}
);
diff --git a/src/card/index.js b/src/card/index.js
index bb3d87a7c8c726..2a2b72585cf6e1 100644
--- a/src/card/index.js
+++ b/src/card/index.js
@@ -5,4 +5,5 @@ module.exports = {
CardMedia: require('./card-media'),
CardText: require('./card-text'),
CardActions: require('./card-actions'),
+ CardExpandable: require('./card-expandable'),
};
diff --git a/src/index.js b/src/index.js
index f6bc3ca08ecc02..fc0fba747a3b15 100644
--- a/src/index.js
+++ b/src/index.js
@@ -5,6 +5,7 @@ module.exports = {
BeforeAfterWrapper: require('./before-after-wrapper'),
Card: require('./card/card'),
CardActions: require('./card/card-actions'),
+ CardExpandable: require('./card/card-expandable'),
CardHeader: require('./card/card-header'),
CardMedia: require('./card/card-media'),
CardText: require('./card/card-text'),