UNPKG

9.05 kBJavaScriptView Raw
1import React, {Component} from 'react';
2import {storiesOf} from '@storybook/html';
3
4import reactDecorator from '../../.storybook/react-decorator';
5
6import {Grid, Row, Col} from '../grid/grid';
7import Link from '../link/link';
8import Pager from '../pager/pager';
9import Button from '../button/button';
10
11import Table from './table';
12import MultiTable from './multitable';
13import Selection from './selection';
14
15storiesOf('Components|Table', module).
16 addParameters({
17 notes: 'Interactive table with selection and keyboard navigation support.'
18 }).
19 addDecorator(reactDecorator()).
20 add('basic', () => {
21 const mock = require('./table.examples.json');
22
23 const PAGE_SIZE = 7;
24 const TOTAL = mock.length;
25
26 class TableDemo extends Component {
27 state = {
28 data: [],
29 selection: new Selection(),
30 caption: undefined,
31 selectable: true,
32 draggable: true,
33 page: 1,
34 pageSize: PAGE_SIZE,
35 total: TOTAL,
36 sortKey: 'country',
37 sortOrder: true,
38 loading: false
39 }
40
41 componentDidMount() {
42 this.loadPage();
43 }
44
45 componentDidUpdate(prevProps, prevState) {
46 const {page, sortKey, sortOrder} = this.state;
47 if (
48 page !== prevState.page ||
49 sortKey !== prevState.sortKey ||
50 sortOrder !== prevState.sortOrder
51 ) {
52 this.loadPage();
53 }
54 }
55
56 columns = [
57 {
58 id: 'country',
59 title: 'Country',
60 sortable: true
61 },
62
63 {
64 id: 'id',
65 title: 'ID',
66 rightAlign: true
67 },
68
69 {
70 id: 'city',
71 title: 'City',
72 sortable: true
73 },
74
75 {
76 id: 'url',
77 title: 'URL',
78 getValue: ({url}) => <Link href={url}>{url}</Link>
79 }
80 ]
81
82 onSort = ({column: {id: sortKey}, order: sortOrder}) => {
83 this.setState({sortKey, sortOrder});
84 }
85
86 onPageChange = page => {
87 this.setState({page});
88 }
89
90 isItemSelectable(item) {
91 return item.id !== 14;
92 }
93
94 loadPage = () => {
95 const {page, pageSize, sortKey, sortOrder} = this.state;
96
97 let data = [...mock];
98 data.sort((a, b) => a[sortKey].localeCompare(b[sortKey]) * (sortOrder ? 1 : -1));
99 data = data.slice((page - 1) * pageSize, (page - 1) * pageSize + pageSize);
100
101 const selection = new Selection({data, isItemSelectable: this.isItemSelectable});
102
103 this.setState({data, selection});
104 }
105
106 render() {
107 const {
108 data, caption, selectable, draggable, loading, page,
109 pageSize, total, selection, sortKey, sortOrder
110 } = this.state;
111
112 return (
113 <div>
114 <Table
115 data={data}
116 columns={this.columns}
117 selection={selection}
118 onSelect={newSelection => this.setState({selection: newSelection})}
119 onReorder={({data: newData}) => this.setState({data: newData})}
120 loading={loading}
121 onSort={this.onSort}
122 sortKey={sortKey}
123 sortOrder={sortOrder}
124 caption={caption}
125 selectable={selectable}
126 isItemSelectable={this.isItemSelectable}
127 draggable={draggable}
128 autofocus
129 />
130
131 <Grid>
132 <Row>
133 <Col>
134 <Pager
135 total={total}
136 pageSize={pageSize}
137 currentPage={page}
138 disablePageSizeSelector
139 onPageChange={this.onPageChange}
140 />
141 </Col>
142 </Row>
143
144 <Row>
145 <Col>
146 Active items: {[...selection.getActive()].map(item => item.country).join(', ')}
147 </Col>
148 </Row>
149
150 <Row>
151 <Col>
152 <Button
153 onClick={() => this.setState({data: [...data]})}
154 >Recreate data array</Button>
155 {' '}
156 <span id="button-non-selectable">
157 {
158 selectable
159 ? (
160 <Button
161 onClick={() => this.setState({selectable: false})}
162 >Non-selectable</Button>
163 ) : (
164 <Button
165 onClick={() => this.setState({selectable: true})}
166 >Selectable</Button>
167 )
168 }
169 </span>
170
171 {' '}
172 {draggable
173 ? (
174 <Button
175 onClick={() => this.setState({draggable: false})}
176 >Non-draggable</Button>
177 ) : (
178 <Button
179 onClick={() => this.setState({draggable: true})}
180 >Draggable</Button>
181 )
182 }
183 {' '}
184
185 <span id="button-with-a-caption">
186 {' '}
187 {
188 caption
189 ? (
190 <Button
191 onClick={() => this.setState({caption: undefined})}
192 >Without a caption</Button>
193 ) : (
194 <Button
195 onClick={() => this.setState({caption: 'Countries'})}
196 >With a caption</Button>
197 )
198 }
199 {' '}
200 </span>
201 {' '}
202
203 {
204 loading
205 ? <Button onClick={() => this.setState({loading: false})}>Not loading</Button>
206 : <Button onClick={() => this.setState({loading: true})}>Loading</Button>
207 }
208 </Col>
209 </Row>
210
211 {page === 1 && data.length > 5 && (
212 <Row>
213 <Col>
214 <span id="button-select-bulgaria">{
215 selection.isSelected(data[3])
216 ? (
217 <Button
218 onClick={() => this.setState({selection: selection.deselect(data[3])})}
219 >Deselect {data[3].country}</Button>
220 ) : (
221 <Button
222 onClick={() => this.setState({selection: selection.select(data[3])})}
223 >Select {data[3].country}</Button>
224 )
225 }
226 </span>
227
228 <span id="button-select-finland">{' '}
229 {selection.isSelected(data[5])
230 ? (
231 <Button
232 onClick={() => this.setState({selection: selection.deselect(data[5])})}
233 >Deselect {data[5].country}
234 </Button>
235 ) : (
236 <Button
237 onClick={() => this.setState({selection: selection.select(data[5])})}
238 >Select {data[5].country}</Button>
239 )
240 }</span>
241 </Col>
242 </Row>
243 )}
244 </Grid>
245 </div>
246 );
247 }
248 }
249
250 return <TableDemo/>;
251 }).
252 add('multi table', () => {
253 const mock = require('./table.examples2.json');
254
255 const data1 = mock.continents;
256 const data2 = mock.countries;
257
258 class TableDemo extends Component {
259 state = {
260 selection1: new Selection({data: data1}),
261 selection2: new Selection({data: data2})
262 };
263
264 columns1 = [
265 {
266 id: 'continent',
267 title: 'Continent'
268 },
269 {
270 id: 'url',
271 title: 'URL'
272 }
273 ]
274
275 columns2 = [
276 {
277 id: 'country',
278 title: 'Country'
279 },
280 {
281 id: 'city',
282 title: 'City'
283 },
284 {
285 id: 'url',
286 title: 'URL'
287 }
288 ]
289
290 render() {
291 return (
292 <MultiTable>
293 <Table
294 data={data1}
295 columns={this.columns1}
296 caption="Continents"
297 selection={this.state.selection1}
298 onSelect={selection => this.setState({selection1: selection})}
299 />
300
301 <Table
302 data={data2}
303 columns={this.columns2}
304 caption="Countries"
305 autofocus
306 selection={this.state.selection2}
307 onSelect={selection => this.setState({selection2: selection})}
308 />
309 </MultiTable>
310 );
311 }
312 }
313
314 return <TableDemo/>;
315 });