UNPKG

5.47 kBMarkdownView Raw
1`reactabular-dnd` provides [React DnD](https://gaearon.github.io/react-dnd/) based helpers for Reactabular.
2
3**Example:**
4
5```jsx
6/*
7import React from 'react';
8import { DragDropContext } from 'react-dnd';
9import HTML5Backend from 'react-dnd-html5-backend';
10import cloneDeep from 'lodash/cloneDeep';
11import findIndex from 'lodash/findIndex';
12import * as Table from 'reactabular-table';
13import * as dnd from 'reactabular-dnd';
14import * as resolve from 'table-resolver';
15*/
16
17const rows = [
18 {
19 id: 1,
20 name: {
21 first: 'John',
22 last: 'Johnson'
23 },
24 company: 'John Inc.',
25 sentence: 'consequatur nihil minima corporis omnis nihil rem'
26 },
27 {
28 id: 2,
29 name: {
30 first: 'Mike',
31 last: 'Mikeson'
32 },
33 company: 'Mike Inc.',
34 sentence: 'a sequi doloremque sed id quo voluptatem voluptatem ut voluptatibus'
35 },
36 {
37 id: 3,
38 name: {
39 first: 'Jake',
40 last: 'Jackson'
41 },
42 company: 'Jake Inc.',
43 sentence: 'sed id quo voluptatem voluptatem ut voluptatibus'
44 },
45 {
46 id: 4,
47 name: {
48 first: 'Don',
49 last: 'Donson'
50 },
51 company: 'Don Inc.',
52 sentence: 'voluptatem voluptatem ut voluptatibus'
53 }
54];
55
56class DragAndDropTable extends React.Component {
57 constructor(props) {
58 super(props);
59
60 this.state = {
61 columns: [
62 {
63 props: {
64 style: {
65 width: 100
66 }
67 },
68 header: {
69 label: 'Name',
70 props: {
71 label: 'Name',
72 onMove: o => this.onMoveColumn(o)
73 }
74 },
75 children: [
76 {
77 property: 'name.first',
78 props: {
79 style: {
80 width: 50
81 }
82 },
83 header: {
84 label: 'First Name',
85 props: {
86 label: 'First Name',
87 onMove: o => this.onMoveChildColumn(o)
88 }
89 }
90 },
91 {
92 property: 'name.last',
93 props: {
94 style: {
95 width: 50
96 }
97 },
98 header: {
99 label: 'Last Name',
100 props: {
101 label: 'Last Name',
102 onMove: o => this.onMoveChildColumn(o)
103 }
104 }
105 }
106 ]
107 },
108 {
109 property: 'company',
110 props: {
111 label: 'Company',
112 style: {
113 width: 100
114 }
115 },
116 header: {
117 label: 'Company',
118 props: {
119 onMove: o => this.onMoveColumn(o)
120 }
121 }
122 },
123 {
124 property: 'sentence',
125 props: {
126 style: {
127 width: 300
128 }
129 },
130 header: {
131 label: 'Sentence',
132 props: {
133 label: 'Sentence',
134 onMove: o => this.onMoveColumn(o)
135 }
136 }
137 }
138 ],
139 rows
140 };
141
142 this.onRow = this.onRow.bind(this);
143 this.onMoveRow = this.onMoveRow.bind(this);
144 this.onMoveColumn = this.onMoveColumn.bind(this);
145 this.onMoveChildColumn = this.onMoveChildColumn.bind(this);
146 }
147 render() {
148 const renderers = {
149 header: {
150 cell: dnd.Header
151 },
152 body: {
153 row: dnd.Row
154 }
155 };
156 const { columns, rows } = this.state;
157 const resolvedColumns = resolve.columnChildren({ columns });
158 const resolvedRows = resolve.resolve({
159 columns: resolvedColumns,
160 method: resolve.nested
161 })(rows);
162
163 return (
164 <Table.Provider
165 renderers={renderers}
166 columns={resolvedColumns}
167 >
168 <Table.Header
169 headerRows={resolve.headerRows({ columns })}
170 />
171
172 <Table.Body
173 rows={resolvedRows}
174 rowKey="id"
175 onRow={this.onRow}
176 />
177 </Table.Provider>
178 );
179 }
180 onRow(row) {
181 return {
182 rowId: row.id,
183 onMove: this.onMoveRow
184 };
185 }
186 onMoveRow({ sourceRowId, targetRowId }) {
187 const rows = dnd.moveRows({
188 sourceRowId,
189 targetRowId
190 })(this.state.rows);
191
192 if (rows) {
193 this.setState({ rows });
194 }
195 }
196 onMoveColumn(labels) {
197 const movedColumns = dnd.moveLabels(this.state.columns, labels);
198
199 if (movedColumns) {
200 // Retain widths to avoid flashing while drag and dropping.
201 const source = movedColumns.source;
202 const target = movedColumns.target;
203 const sourceWidth = source.props.style && source.props.style.width;
204 const targetWidth = target.props.style && target.props.style.width;
205
206 source.props.style = {
207 ...source.props.style,
208 width: targetWidth
209 };
210 target.props.style = {
211 ...target.props.style,
212 width: sourceWidth
213 };
214
215 this.setState({
216 columns: movedColumns.columns
217 });
218 }
219 }
220 onMoveChildColumn(labels) {
221 const movedChildren = dnd.moveChildrenLabels(this.state.columns, labels);
222
223 if (movedChildren) {
224 const columns = cloneDeep(this.state.columns);
225
226 columns[movedChildren.target].children = movedChildren.columns;
227
228 // Here we assume children have the same width.
229 this.setState({ columns });
230 }
231 }
232}
233
234// Set up drag and drop context
235//const DragAndDrop = DragDropContext(HTML5Backend)(DragAndDropTable);
236
237<DragAndDropTable />
238```