UNPKG

5.54 kBMarkdownView Raw
1Reactabular provides three components: `Table.Provider`, `Table.Header`, and `Table.Body`. `Table.Provider` sets the data context. It may contain multiple `Table.Header` and `Table.Body` elements. You can control data per body while the provider maintains a shared column definition.
2
3## `Table.Provider`
4
5`Table.Provider` is the core of Reactabular. It sets up a [context](https://facebook.github.io/react/docs/context.html) and maps the `column` definition to its children components. The following example illustrates the basic idea.
6
7```jsx
8/*
9import { Table } from 'reactabular';
10*/
11
12const rows = [
13 {
14 id: 100,
15 name: 'Adam',
16 dad: 'John',
17 lovesBeeGees: true
18 },
19 {
20 id: 101,
21 name: 'Brian',
22 dad: 'George',
23 lovesBeeGees: false
24 },
25];
26
27const columns = [
28 {
29 property: 'name',
30 header: {
31 label: 'Name'
32 }
33 },
34 {
35 property: 'dad',
36 header: {
37 label: 'Dad'
38 }
39 }
40];
41
42<Table.Provider
43 className="pure-table pure-table-striped"
44 columns={columns}
45>
46 <Table.Header />
47
48 <Table.Body rows={rows} rowKey="id" />
49</Table.Provider>
50```
51
52## `Table.Header`
53
54`Table.Header` renders a table header within a `Table.Provider` context.
55
56```react
57<Table.Provider
58 className="pure-table pure-table-striped"
59 columns={columns}
60>
61 <Table.Header />
62
63 <Table.Body rows={rows} rowKey="id"/>
64
65 <Table.Header />
66</Table.Provider>
67```
68
69## Customizing `Table.Header`
70
71It is possible to customize a header by passing child components to it. This way you can implement filtering per column for instance.
72
73Here `VisibilityToggles` injects an additional row for the filter controls. An alternative way to handle it would be to push the problem to the column definition.
74
75```react
76<Table.Provider
77 className="pure-table pure-table-striped"
78 columns={columns}
79>
80 <Table.Header>
81 <SearchColumns
82 query={{}}
83 columns={columns}
84 onChange={value => console.log('new value', value)}
85 />
86 </Table.Header>
87
88 <Table.Body rows={rows} rowKey="id" />
89</Table.Provider>
90```
91
92> `ColumnFilters` isn't included in the standard distribution. You can [find it at the project repository](https://github.com/reactabular/reactabular/blob/master/docs/helpers/ColumnFilters.jsx).
93
94## `Table.Body`
95
96`Table.Body` renders table `rows` within a `Table.Provider` context. It accepts either an array of objects or an array of arrays (see the [Excel example](/examples/excel)). In the former case you should define a `rowKey`. This allows React to render in a more performant way.
97
98Most often you'll define `rowKey` as a string. An alternative is to define it using a function like this: `rowKey={({ rowData, rowIndex }) => rowData.nested.id}`. This is useful if your key is nested or related to some other data. Another way to avoid this problem is to generate the field using `reactabular-resolve` and then point to that through a string.
99
100**Example:**
101
102```react
103<Table.Provider
104 className="pure-table pure-table-striped"
105 columns={columns}
106>
107 <Table.Header />
108
109 <Table.Body rows={rows.filter(r => r.name === 'Adam')} rowKey="id" />
110
111 <Table.Header />
112
113 <Table.Body rows={rows.filter(r => r.name === 'Brian')} rowKey="id" />
114</Table.Provider>
115```
116
117## Getting Refs
118
119Sometimes you might need to access the underlying DOM nodes for measuring etc. This can be achieved as follows:
120
121```react
122class RefTable extends React.Component {
123 constructor(props) {
124 super(props);
125
126 this.onRow = this.onRow.bind(this);
127
128 this.headerRef = null;
129 this.bodyRef = null;
130 }
131 render() {
132 return (
133 <Table.Provider columns={columns}>
134 <Table.Header
135 ref={header => {
136 this.headerRef = header && header.getRef();
137 }}
138 />
139 <Table.Body
140 ref={body => {
141 this.bodyRef = body && body.getRef();
142 }}
143 rows={rows}
144 rowKey="id"
145 onRow={this.onRow}
146 />
147 </Table.Provider>
148 );
149 }
150 onRow(row, { rowIndex, rowKey }) {
151 return {
152 onClick: () => console.log(this.headerRef, this.bodyRef)
153 };
154 }
155}
156
157<RefTable />
158```
159
160It's the same idea for `Table.Body`.
161
162## Customizing `Table.Body` Rows
163
164It is possible to customize body behavior on a row level. `onRow` prop accepts function `(row, { rowIndex, rowKey }) => ({...})` that allows you to set custom attributes per each row.
165
166```react
167class CustomTable extends React.Component {
168 render() {
169 return (
170 <Table.Provider
171 className="pure-table pure-table-striped"
172 columns={columns}
173 >
174 <Table.Header />
175
176 <Table.Body
177 rows={rows}
178 rowKey="id"
179 onRow={this.onRow}
180 />
181 </Table.Provider>
182 );
183 }
184 onRow(row, { rowIndex, rowKey }) {
185 return {
186 className: rowIndex % 2 ? 'odd-row' : 'even-row',
187 onClick: () => console.log('clicked row', row)
188 };
189 }
190}
191
192<CustomTable />
193```
194
195It's a good idea to define a possible `row` handler separately to avoid binding per each `render`. If you write the handler inline, it will bind each time `render()` is called and reduce performance slightly.
196
197## Customizing `Table` Footer
198
199It is possible to inject a custom footer like this:
200
201```react
202<Table.Provider
203 className="pure-table pure-table-striped"
204 columns={columns}
205>
206 <Table.Header />
207
208 <Table.Body rows={rows} rowKey="id" />
209
210 <tfoot>
211 <tr>
212 <td>Show custom rows here</td>
213 <td>Show custom rows here</td>
214 </tr>
215 </tfoot>
216</Table.Provider>
217```
218
219## See Also
220
221* [Selection](http://reactabular.js.org/#/examples/selection)