Skip to content

Commit 3f5c6e3

Browse files
committed
[added] react-bootstrap#1181 ListGroup supports componentClass prop
1 parent 3edf4a1 commit 3f5c6e3

File tree

5 files changed

+254
-142
lines changed

5 files changed

+254
-142
lines changed

docs/examples/ListGroupCustom.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const CustomComponent = React.createClass({
2+
render() {
3+
return (
4+
<li
5+
className="list-group-item"
6+
onClick={() => {}}>
7+
{this.props.children}
8+
</li>
9+
);
10+
}
11+
});
12+
13+
const listgroupInstance = (
14+
<ListGroup componentClass="ul">
15+
<CustomComponent>Custom Child 1 </CustomComponent>
16+
<CustomComponent>Custom Child 2 </CustomComponent>
17+
<CustomComponent>Custom Child 3</CustomComponent>
18+
</ListGroup>
19+
);
20+
21+
React.render(listgroupInstance, mountNode);

docs/src/ComponentsPage.js

+9
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,15 @@ const ComponentsPage = React.createClass({
733733
<p>Set the <code>header</code> prop to create a structured item, with a heading and a body area.</p>
734734
<ReactPlayground codeText={Samples.ListGroupHeader} />
735735

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

738747
<h4><Anchor id="listgroup-props-group">ListGroup</Anchor></h4>

docs/src/Samples.js

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ export default {
8080
GridBasic: require('fs').readFileSync(__dirname + '/../examples/GridBasic.js', 'utf8'),
8181
ThumbnailAnchor: require('fs').readFileSync(__dirname + '/../examples/ThumbnailAnchor.js', 'utf8'),
8282
ThumbnailDiv: require('fs').readFileSync(__dirname + '/../examples/ThumbnailDiv.js', 'utf8'),
83+
ListGroupCustom: require('fs').readFileSync(__dirname + '/../examples/ListGroupCustom.js', 'utf8'),
8384
ListGroupDefault: require('fs').readFileSync(__dirname + '/../examples/ListGroupDefault.js', 'utf8'),
8485
ListGroupLinked: require('fs').readFileSync(__dirname + '/../examples/ListGroupLinked.js', 'utf8'),
8586
ListGroupActive: require('fs').readFileSync(__dirname + '/../examples/ListGroupActive.js', 'utf8'),

src/ListGroup.js

+35-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React, { cloneElement } from 'react';
2+
import ListGroupItem from './ListGroupItem';
23
import classNames from 'classnames';
34
import ValidComponentChildren from './utils/ValidComponentChildren';
45

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

13+
if (this.areCustomChildren(items)) {
14+
let Component = this.props.componentClass;
15+
return (
16+
<Component
17+
{...this.props}
18+
className={classNames(this.props.className, 'list-group')}>
19+
{items}
20+
</Component>
21+
);
22+
}
23+
1224
let shouldRenderDiv = false;
1325

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

24-
if (shouldRenderDiv) {
25-
return this.renderDiv(items);
26-
}
27-
return this.renderUL(items);
36+
return shouldRenderDiv ? this.renderDiv(items) : this.renderUL(items);
2837
}
2938

3039
isAnchorOrButton(props) {
3140
return (props.href || props.onClick);
3241
}
3342

43+
areCustomChildren(children) {
44+
let customChildren = false;
45+
46+
ValidComponentChildren.forEach(children, (child) => {
47+
if (child.type !== ListGroupItem) {
48+
customChildren = true;
49+
}
50+
}, this);
51+
52+
return customChildren;
53+
}
54+
3455
renderUL(items) {
3556
let listItems = ValidComponentChildren.map(items,
3657
(item) => cloneElement(item, { listItem: true })
@@ -56,8 +77,18 @@ class ListGroup extends React.Component {
5677
}
5778
}
5879

80+
ListGroup.defaultProps = {
81+
componentClass: 'div'
82+
};
83+
5984
ListGroup.propTypes = {
6085
className: React.PropTypes.string,
86+
/**
87+
* The element for ListGroup if children are
88+
* user-defined custom components.
89+
* @type {("ul"|"div")}
90+
*/
91+
componentClass: React.PropTypes.oneOf(['ul', 'div']),
6192
id: React.PropTypes.oneOfType([
6293
React.PropTypes.string,
6394
React.PropTypes.number

0 commit comments

Comments
 (0)