Skip to content

Commit ad7d31c

Browse files
skyflyertannerlinsley
authored andcommitted
Add column id to the rowInfo object (TanStack#253)
* Add column id to the rowInfo object (passed to render). Resolves TanStack#237 * Creating a new object instead of modifying existing rowInfo; Refs TanStack#253 * Code style compliance. Refs TanStack#253
1 parent ddee18c commit ad7d31c

File tree

4 files changed

+144
-16
lines changed

4 files changed

+144
-16
lines changed

.storybook/config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import Footers from '../stories/Footers.js'
2727
import Filtering from '../stories/Filtering.js'
2828
import ControlledTable from '../stories/ControlledTable.js'
2929
import PivotingOptions from '../stories/PivotingOptions.js'
30+
import EditableTable from '../stories/EditableTable.js'
3031
//
3132
configure(() => {
3233
storiesOf('1. Docs')
@@ -59,4 +60,5 @@ configure(() => {
5960
.add('Footers', Footers)
6061
.add('Custom Filtering', Filtering)
6162
.add('Controlled Component', ControlledTable)
63+
.add('Editable table', EditableTable)
6264
}, module)

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,10 +330,11 @@ Or just define them as props
330330
// Cell Options
331331
className: '', // Set the classname of the `td` element of the column
332332
style: {}, // Set the style of the `td` element of the column
333-
render: JSX eg. (rowInfo: {value, rowValues, row, index, viewIndex}) => <span>{value}</span>, // Provide a JSX element or stateless function to render whatever you want as the column's cell with access to the entire row
333+
render: JSX eg. (cellInfo: {value, rowValues, row, column, index, viewIndex}) => <span>{value}</span>, // Provide a JSX element or stateless function to render whatever you want as the column's cell with access to the entire row
334334
// value == the accessed value of the column
335335
// rowValues == an object of all of the accessed values for the row
336336
// row == the original row of data supplied to the table
337+
// column == the column properties (id, header, sortable, ...)
337338
// index == the original index of the data supplied to the table
338339
// viewIndex == the index of the row in the current page
339340

@@ -482,8 +483,8 @@ Every single built-in component's props can be dynamically extended using any on
482483
getTdProps={fn}
483484
getPaginationProps={fn}
484485
getLoadingProps={fn}
485-
getNoDataProps: {fn},
486-
getResizerProps: {fn}
486+
getNoDataProps={fn}
487+
getResizerProps={fn}
487488
/>
488489
```
489490

src/index.js

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ export default class ReactTable extends Methods(Lifecycle(Component)) {
460460
{...trProps.rest}
461461
>
462462
{allVisibleColumns.map((column, i2) => {
463+
const cellInfo = { ...rowInfo, column: {...column} }
463464
const resized = resizing.find(x => x.id === column.id) || {}
464465
const show = typeof column.show === 'function' ? column.show() : column.show
465466
const width = _.getFirstDefined(resized.value, column.width, column.minWidth)
@@ -484,16 +485,16 @@ export default class ReactTable extends Methods(Lifecycle(Component)) {
484485
if (column.expander) {
485486
const onTdClick = (e) => {
486487
if (onExpandRow) {
487-
return onExpandRow(rowInfo.nestingPath, e)
488+
return onExpandRow(cellInfo.nestingPath, e)
488489
}
489490
let newExpandedRows = _.clone(expandedRows)
490491
if (isExpanded) {
491492
return this.setStateWithData({
492-
expandedRows: _.set(newExpandedRows, rowInfo.nestingPath, false)
493+
expandedRows: _.set(newExpandedRows, cellInfo.nestingPath, false)
493494
})
494495
}
495496
return this.setStateWithData({
496-
expandedRows: _.set(newExpandedRows, rowInfo.nestingPath, {})
497+
expandedRows: _.set(newExpandedRows, cellInfo.nestingPath, {})
497498
})
498499
}
499500

@@ -523,26 +524,26 @@ export default class ReactTable extends Methods(Lifecycle(Component)) {
523524
)}
524525
style={{
525526
...styles,
526-
paddingLeft: rowInfo.nestingPath.length === 1 ? undefined : `${30 * (rowInfo.nestingPath.length - 1)}px`,
527+
paddingLeft: rowInfo.nestingPath.length === 1 ? undefined : `${30 * (cellInfo.nestingPath.length - 1)}px`,
527528
flex: `${pivotFlex} 0 auto`,
528529
width: `${pivotWidth}px`,
529530
maxWidth: `${pivotMaxWidth}px`
530531
}}
531532
{...tdProps.rest}
532533
onClick={onTdClick}
533534
>
534-
{rowInfo.subRows ? (
535+
{cellInfo.subRows ? (
535536
_.normalizeComponent(column.render, {
536-
...rowInfo,
537+
...cellInfo,
537538
value: row[pivotValKey],
538539
isExpanded
539-
}, rowInfo.rowValues[column.id])
540+
}, cellInfo.rowValues[column.id])
540541
) : SubComponent ? (
541542
_.normalizeComponent(column.render, {
542-
...rowInfo,
543-
value: rowInfo.rowValues[column.id],
543+
...cellInfo,
544+
value: cellInfo.rowValues[column.id],
544545
isExpanded
545-
}, rowInfo.rowValues[column.id])
546+
}, cellInfo.rowValues[column.id])
546547
) : null}
547548
</TdComponent>
548549
)
@@ -567,10 +568,10 @@ export default class ReactTable extends Methods(Lifecycle(Component)) {
567568
{...extraProps}
568569
>
569570
{_.normalizeComponent(column.render, {
570-
...rowInfo,
571-
value: rowInfo.rowValues[column.id],
571+
...cellInfo,
572+
value: cellInfo.rowValues[column.id],
572573
isExpanded
573-
}, rowInfo.rowValues[column.id])}
574+
}, cellInfo.rowValues[column.id])}
574575
</TdComponent>
575576
)
576577
})}

stories/EditableTable.js

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import React from 'react'
2+
import _ from 'lodash'
3+
import namor from 'namor'
4+
5+
import CodeHighlight from './components/codeHighlight'
6+
import ReactTable from '../src/index'
7+
8+
class MyTable extends React.Component {
9+
constructor(props, context) {
10+
super(props, context);
11+
this.renderEditable = this.renderEditable.bind(this);
12+
13+
this.state = {
14+
data: [
15+
{ firstName: 'Lucy', lastName: 'Marks' },
16+
{ firstName: 'Bejamin', lastName: 'Pike' }
17+
]
18+
};
19+
20+
this.columns = [
21+
{
22+
header: 'First Name',
23+
accessor: 'firstName',
24+
render: this.renderEditable
25+
},
26+
{
27+
header: 'Last Name',
28+
accessor: 'lastName',
29+
render: this.renderEditable
30+
},
31+
{
32+
header: 'Full Name',
33+
id: 'full',
34+
accessor: d => d.firstName + ' ' + d.lastName
35+
}
36+
];
37+
}
38+
39+
renderEditable(cellInfo) {
40+
return (<div style={{ backgroundColor: '#fafafa' }} contentEditable suppressContentEditableWarning onBlur={(e) => {
41+
const data = [...this.state.data];
42+
data[cellInfo.index][cellInfo.column.id] = e.target.textContent;
43+
this.setState({data: data});
44+
}}>{this.state.data[cellInfo.index][cellInfo.column.id]}</div>);
45+
}
46+
47+
render() {
48+
return (<ReactTable
49+
data={this.state.data}
50+
columns={this.columns}
51+
defaultPageSize={2}
52+
showPageSizeOptions={false}
53+
showPagination={false}
54+
/>);
55+
}
56+
}
57+
58+
function getCode() {
59+
return `
60+
class MyTable extends React.Component {
61+
constructor(props, context) {
62+
super(props, context);
63+
this.renderEditable = this.renderEditable.bind(this);
64+
65+
this.state = {
66+
data: [
67+
{ firstName: 'Lucy', lastName: 'Marks' },
68+
{ firstName: 'Bejamin', lastName: 'Pike' }
69+
]
70+
};
71+
72+
this.columns = [
73+
{
74+
header: 'First Name',
75+
accessor: 'firstName',
76+
render: this.renderEditable
77+
},
78+
{
79+
header: 'Last Name',
80+
accessor: 'lastName',
81+
render: this.renderEditable
82+
},
83+
{
84+
header: 'Full Name',
85+
id: 'full',
86+
accessor: d => d.firstName + ' ' + d.lastName
87+
}
88+
];
89+
}
90+
91+
renderEditable(cellInfo) {
92+
return (<div style={{ backgroundColor: '#fafafa' }} contentEditable suppressContentEditableWarning onBlur={(e) => {
93+
const data = [...this.state.data];
94+
data[cellInfo.index][cellInfo.column.id] = e.target.textContent;
95+
this.setState({data: data});
96+
}}>{this.state.data[cellInfo.index][cellInfo.column.id]}</div>);
97+
}
98+
99+
render() {
100+
return (<ReactTable
101+
data={this.state.data}
102+
columns={this.columns}
103+
defaultPageSize={2}
104+
showPageSizeOptions={false}
105+
showPagination={false}
106+
/>);
107+
}
108+
}
109+
`
110+
}
111+
112+
export default () => {
113+
114+
return (
115+
<div>
116+
<p>First two columns are editable just by clicking into them using the <code>contentEditable</code> attribute. Last column (Full Name) is computed from the first two.</p>
117+
<div className='table-wrap' style={{marginBottom: '20px'}}>
118+
<MyTable />
119+
</div>
120+
121+
<CodeHighlight>{() => getCode()}</CodeHighlight>
122+
</div>
123+
)
124+
}

0 commit comments

Comments
 (0)