Skip to content
This repository was archived by the owner on Jan 15, 2022. It is now read-only.

Commit 4abe39c

Browse files
committed
Allow specifying table rows in custom components
Use the structure returned by `react.createElement` to do a render of any child components with unrecognized types, and extract the data out of them if they themselves return a `<Tr>`
1 parent d19826d commit 4abe39c

File tree

5 files changed

+124
-18
lines changed

5 files changed

+124
-18
lines changed

build/reactable.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,9 @@ window.React["default"] = window.React;
10331033
}
10341034
}).bind(this));
10351035
}
1036+
}, {
1037+
key: 'childType',
1038+
value: function childType(child) {}
10361039
}, {
10371040
key: 'parseChildData',
10381041
value: function parseChildData(props) {
@@ -1046,17 +1049,27 @@ window.React["default"] = window.React;
10461049
return;
10471050
}
10481051

1049-
switch (child.type) {
1052+
var reactableDescendant = undefined;
1053+
var test = undefined;
1054+
1055+
if ([_tfoot.Tfoot, _thead.Thead, _tr.Tr].indexOf(child.type) >= 0) {
1056+
reactableDescendant = child;
1057+
} else {
1058+
reactableDescendant = new child.type(child.props).render();
1059+
test = true;
1060+
}
1061+
1062+
switch (reactableDescendant.type) {
10501063
case _tfoot.Tfoot:
10511064
if (typeof tfoot !== 'undefined') {
10521065
console.warn('You can only have one <Tfoot>, but more than one was specified.' + 'Ignoring all but the last one');
10531066
}
10541067
tfoot = child;
10551068
break;
10561069
case _tr.Tr:
1057-
var childData = child.props.data || {};
1070+
var childData = reactableDescendant.props.data || {};
10581071

1059-
_react['default'].Children.forEach(child.props.children, function (descendant) {
1072+
_react['default'].Children.forEach(reactableDescendant.props.children, function (descendant) {
10601073
// TODO
10611074
/* if (descendant.type.ConvenienceConstructor === Td) { */
10621075
if (typeof descendant !== 'object' || descendant == null) {
@@ -1069,7 +1082,7 @@ window.React["default"] = window.React;
10691082
} else if (typeof descendant.props.children !== 'undefined') {
10701083
value = descendant.props.children;
10711084
} else {
1072-
console.warn('exports.Td specified without ' + 'a `data` property or children, ' + 'ignoring');
1085+
console.warn('Td specified without ' + 'a `data` property or children, ' + 'ignoring');
10731086
return;
10741087
}
10751088

@@ -1085,7 +1098,7 @@ window.React["default"] = window.React;
10851098

10861099
data.push({
10871100
data: childData,
1088-
props: (0, _libFilter_props_from.filterPropsFrom)(child.props),
1101+
props: (0, _libFilter_props_from.filterPropsFrom)(reactableDescendant.props),
10891102
__reactableMeta: true
10901103
});
10911104
break;

build/tests/reactable_test.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,75 @@
610610
});
611611
});
612612

613+
describe('adding <CustomComponents>s to the <Table>', function () {
614+
before(function () {
615+
var CustomComponent = React.createClass({
616+
displayName: "CustomComponent",
617+
propTypes: {
618+
name: React.PropTypes.string,
619+
age: React.PropTypes.number,
620+
position: React.PropTypes.string
621+
},
622+
render: function render() {
623+
return React.createElement(
624+
Reactable.Tr,
625+
null,
626+
React.createElement(
627+
Reactable.Td,
628+
{ column: 'Name' },
629+
this.props.name || ''
630+
),
631+
React.createElement(
632+
Reactable.Td,
633+
{ column: 'Age' },
634+
this.props.age || ''
635+
),
636+
React.createElement(
637+
Reactable.Td,
638+
{ column: 'Position' },
639+
this.props.position || ''
640+
)
641+
);
642+
}
643+
});
644+
645+
React.render(React.createElement(
646+
Reactable.Table,
647+
{ className: 'table', id: 'table' },
648+
React.createElement(CustomComponent, { name: 'Griffin Smith', age: 18 }),
649+
React.createElement(CustomComponent, { name: 'Lee Salminen', age: 23 }),
650+
React.createElement(CustomComponent, { age: 28, position: 'Developer' })
651+
), ReactableTestUtils.testNode());
652+
});
653+
654+
after(ReactableTestUtils.resetTestEnvironment);
655+
656+
it('renders the table', function () {
657+
expect($('table#table.table')).to.exist;
658+
});
659+
660+
it('renders the column headers in the table', function () {
661+
var headers = [];
662+
$('thead th').each(function () {
663+
headers.push($(this).text());
664+
});
665+
666+
expect(headers).to.eql(['Name', 'Age', 'Position']);
667+
});
668+
669+
it('renders the first row with the correct data', function () {
670+
ReactableTestUtils.expectRowText(0, ['Griffin Smith', '18', '']);
671+
});
672+
673+
it('renders the second row with the correct data', function () {
674+
ReactableTestUtils.expectRowText(1, ['Lee Salminen', '23', '']);
675+
});
676+
677+
it('renders the third row with the correct data', function () {
678+
ReactableTestUtils.expectRowText(2, ['', '28', 'Developer']);
679+
});
680+
});
681+
613682
describe('passing through HTML props', function () {
614683
describe('adding <Tr>s with className to the <Table>', function () {
615684
before(function () {

lib/reactable/table.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ var Table = (function (_React$Component) {
8787
}
8888
}).bind(this));
8989
}
90+
}, {
91+
key: 'childType',
92+
value: function childType(child) {}
9093
}, {
9194
key: 'parseChildData',
9295
value: function parseChildData(props) {
@@ -100,17 +103,27 @@ var Table = (function (_React$Component) {
100103
return;
101104
}
102105

103-
switch (child.type) {
106+
var reactableDescendant = undefined;
107+
var test = undefined;
108+
109+
if ([_tfoot.Tfoot, _thead.Thead, _tr.Tr].indexOf(child.type) >= 0) {
110+
reactableDescendant = child;
111+
} else {
112+
reactableDescendant = new child.type(child.props).render();
113+
test = true;
114+
}
115+
116+
switch (reactableDescendant.type) {
104117
case _tfoot.Tfoot:
105118
if (typeof tfoot !== 'undefined') {
106119
console.warn('You can only have one <Tfoot>, but more than one was specified.' + 'Ignoring all but the last one');
107120
}
108121
tfoot = child;
109122
break;
110123
case _tr.Tr:
111-
var childData = child.props.data || {};
124+
var childData = reactableDescendant.props.data || {};
112125

113-
_react2['default'].Children.forEach(child.props.children, function (descendant) {
126+
_react2['default'].Children.forEach(reactableDescendant.props.children, function (descendant) {
114127
// TODO
115128
/* if (descendant.type.ConvenienceConstructor === Td) { */
116129
if (typeof descendant !== 'object' || descendant == null) {
@@ -123,7 +136,7 @@ var Table = (function (_React$Component) {
123136
} else if (typeof descendant.props.children !== 'undefined') {
124137
value = descendant.props.children;
125138
} else {
126-
console.warn('exports.Td specified without ' + 'a `data` property or children, ' + 'ignoring');
139+
console.warn('Td specified without ' + 'a `data` property or children, ' + 'ignoring');
127140
return;
128141
}
129142

@@ -139,7 +152,7 @@ var Table = (function (_React$Component) {
139152

140153
data.push({
141154
data: childData,
142-
props: (0, _libFilter_props_from.filterPropsFrom)(child.props),
155+
props: (0, _libFilter_props_from.filterPropsFrom)(reactableDescendant.props),
143156
__reactableMeta: true
144157
});
145158
break;

src/reactable/table.jsx

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,17 @@ export class Table extends React.Component {
6262
return;
6363
}
6464

65-
switch (child.type) {
65+
let reactableDescendant;
66+
let test;
67+
68+
if ([Tfoot, Thead, Tr].indexOf(child.type) >= 0) {
69+
reactableDescendant = child
70+
} else {
71+
reactableDescendant = (new child.type(child.props)).render()
72+
test = true
73+
}
74+
75+
switch (reactableDescendant.type) {
6676
case Tfoot:
6777
if (typeof(tfoot) !== 'undefined') {
6878
console.warn ('You can only have one <Tfoot>, but more than one was specified.' +
@@ -71,9 +81,9 @@ export class Table extends React.Component {
7181
tfoot = child;
7282
break;
7383
case Tr:
74-
let childData = child.props.data || {};
84+
let childData = reactableDescendant.props.data || {};
7585

76-
React.Children.forEach(child.props.children, function(descendant) {
86+
React.Children.forEach(reactableDescendant.props.children, function(descendant) {
7787
// TODO
7888
/* if (descendant.type.ConvenienceConstructor === Td) { */
7989
if (
@@ -89,7 +99,7 @@ export class Table extends React.Component {
8999
} else if (typeof(descendant.props.children) !== 'undefined') {
90100
value = descendant.props.children;
91101
} else {
92-
console.warn('exports.Td specified without ' +
102+
console.warn('Td specified without ' +
93103
'a `data` property or children, ' +
94104
'ignoring');
95105
return;
@@ -108,7 +118,7 @@ export class Table extends React.Component {
108118

109119
data.push({
110120
data: childData,
111-
props: filterPropsFrom(child.props),
121+
props: filterPropsFrom(reactableDescendant.props),
112122
__reactableMeta: true
113123
});
114124
break;

tests/reactable_test.jsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -429,13 +429,14 @@ describe('Reactable', function() {
429429
render: function(){
430430
return (
431431
<Reactable.Tr>
432-
<Reactable.Td column="Name">{this.props.name}</Reactable.Td>
433-
<Reactable.Td column="Age">{this.props.age}</Reactable.Td>
434-
<Reactable.Td column="Position">{this.props.position}</Reactable.Td>
432+
<Reactable.Td column="Name">{this.props.name || ''}</Reactable.Td>
433+
<Reactable.Td column="Age">{this.props.age || ''}</Reactable.Td>
434+
<Reactable.Td column="Position">{this.props.position || ''}</Reactable.Td>
435435
</Reactable.Tr>
436436
);
437437
}
438438
});
439+
439440
React.render(
440441
<Reactable.Table className="table" id="table">
441442
<CustomComponent name='Griffin Smith' age={18} />

0 commit comments

Comments
 (0)