Skip to content

Commit

Permalink
Merge pull request react-bootstrap#1348 from apkiernan/listGroup
Browse files Browse the repository at this point in the history
[added] react-bootstrap#1181 ListGroup supports componentClass prop
  • Loading branch information
taion committed Oct 1, 2015
2 parents 20ab3d9 + 3f5c6e3 commit 341cdb0
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 142 deletions.
21 changes: 21 additions & 0 deletions docs/examples/ListGroupCustom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const CustomComponent = React.createClass({
render() {
return (
<li
className="list-group-item"
onClick={() => {}}>
{this.props.children}
</li>
);
}
});

const listgroupInstance = (
<ListGroup componentClass="ul">
<CustomComponent>Custom Child 1 </CustomComponent>
<CustomComponent>Custom Child 2 </CustomComponent>
<CustomComponent>Custom Child 3</CustomComponent>
</ListGroup>
);

React.render(listgroupInstance, mountNode);
9 changes: 9 additions & 0 deletions docs/src/ComponentsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,15 @@ const ComponentsPage = React.createClass({
<p>Set the <code>header</code> prop to create a structured item, with a heading and a body area.</p>
<ReactPlayground codeText={Samples.ListGroupHeader} />

<h3><Anchor id="listgroup-with-custom-children">With custom component children</Anchor></h3>
<p>
When using ListGroupItems directly, ListGroup looks at whether the items have href
or onClick props to determine which DOM elements to emit. However, with custom item
components as children to <code>ListGroup</code>, set the
<code>componentClass</code> prop to specify which element <code>ListGroup</code> should output.
</p>
<ReactPlayground codeText={Samples.ListGroupCustom} />

<h3><Anchor id="listgroup-props">Props</Anchor></h3>

<h4><Anchor id="listgroup-props-group">ListGroup</Anchor></h4>
Expand Down
1 change: 1 addition & 0 deletions docs/src/Samples.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export default {
GridBasic: require('fs').readFileSync(__dirname + '/../examples/GridBasic.js', 'utf8'),
ThumbnailAnchor: require('fs').readFileSync(__dirname + '/../examples/ThumbnailAnchor.js', 'utf8'),
ThumbnailDiv: require('fs').readFileSync(__dirname + '/../examples/ThumbnailDiv.js', 'utf8'),
ListGroupCustom: require('fs').readFileSync(__dirname + '/../examples/ListGroupCustom.js', 'utf8'),
ListGroupDefault: require('fs').readFileSync(__dirname + '/../examples/ListGroupDefault.js', 'utf8'),
ListGroupLinked: require('fs').readFileSync(__dirname + '/../examples/ListGroupLinked.js', 'utf8'),
ListGroupActive: require('fs').readFileSync(__dirname + '/../examples/ListGroupActive.js', 'utf8'),
Expand Down
39 changes: 35 additions & 4 deletions src/ListGroup.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { cloneElement } from 'react';
import ListGroupItem from './ListGroupItem';
import classNames from 'classnames';
import ValidComponentChildren from './utils/ValidComponentChildren';

Expand All @@ -9,6 +10,17 @@ class ListGroup extends React.Component {
(item, index) => cloneElement(item, { key: item.key ? item.key : index })
);

if (this.areCustomChildren(items)) {
let Component = this.props.componentClass;
return (
<Component
{...this.props}
className={classNames(this.props.className, 'list-group')}>
{items}
</Component>
);
}

let shouldRenderDiv = false;

if (!this.props.children) {
Expand All @@ -21,16 +33,25 @@ class ListGroup extends React.Component {
});
}

if (shouldRenderDiv) {
return this.renderDiv(items);
}
return this.renderUL(items);
return shouldRenderDiv ? this.renderDiv(items) : this.renderUL(items);
}

isAnchorOrButton(props) {
return (props.href || props.onClick);
}

areCustomChildren(children) {
let customChildren = false;

ValidComponentChildren.forEach(children, (child) => {
if (child.type !== ListGroupItem) {
customChildren = true;
}
}, this);

return customChildren;
}

renderUL(items) {
let listItems = ValidComponentChildren.map(items,
(item) => cloneElement(item, { listItem: true })
Expand All @@ -56,8 +77,18 @@ class ListGroup extends React.Component {
}
}

ListGroup.defaultProps = {
componentClass: 'div'
};

ListGroup.propTypes = {
className: React.PropTypes.string,
/**
* The element for ListGroup if children are
* user-defined custom components.
* @type {("ul"|"div")}
*/
componentClass: React.PropTypes.oneOf(['ul', 'div']),
id: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number
Expand Down
Loading

0 comments on commit 341cdb0

Please sign in to comment.