1 | `react-edit` provides a set of inline editing related utilities for React. The library comes with a couple of basic editors and you can implement your own as long as you follow the same interface (`value`, `onValue` props).
|
2 |
|
3 | ## API
|
4 |
|
5 | The `edit` transform has been designed to allow inline editing. It expects you to define how to manipulate the state. it also expects you to pass an editor.
|
6 |
|
7 | **Example:**
|
8 |
|
9 | ```jsx
|
10 | ...
|
11 | import cloneDeep from 'lodash/cloneDeep';
|
12 | import findIndex from 'lodash/findIndex';
|
13 | import * as edit from 'react-edit';
|
14 |
|
15 | ...
|
16 |
|
17 | // Define how to manipulate rows through edit.
|
18 | const editable = edit.edit({
|
19 | // Determine whether the current cell is being edited or not.
|
20 | isEditing: ({ columnIndex, rowData }) => columnIndex === rowData.editing,
|
21 |
|
22 | // The user requested activation, mark the current cell as edited.
|
23 | // IMPORTANT! If you stash the rows at this.state.rows, DON'T
|
24 | // mutate it as that will break Table.Body optimization check.
|
25 | //
|
26 | // You also have access to `event` here.
|
27 | onActivate: ({ columnIndex, rowData, event }) => {
|
28 | event.stopPropagation();
|
29 |
|
30 | const index = findIndex(this.state.rows, { id: rowData.id });
|
31 | const rows = cloneDeep(this.state.rows);
|
32 |
|
33 | rows[index].editing = columnIndex;
|
34 |
|
35 | this.setState({ rows });
|
36 | },
|
37 |
|
38 | // Capture the value when the user has finished and update
|
39 | // application state.
|
40 | onValue: ({ value, rowData, property }) => {
|
41 | const index = findIndex(this.state.rows, { id: rowData.id });
|
42 | const rows = cloneDeep(this.state.rows);
|
43 |
|
44 | rows[index][property] = value;
|
45 | rows[index].editing = false;
|
46 |
|
47 | this.setState({ rows });
|
48 | },
|
49 |
|
50 | // It's possible to shape the value passed to the editor. See
|
51 | // the Excel example for a concrete example.
|
52 | // getEditedValue: v => v.value
|
53 |
|
54 | // If you want to change default value/onValue, you can do it through
|
55 | // editingProps: { value: 'value', onValue: 'onValue' }
|
56 |
|
57 | // In case you want to trigger activation using something else than
|
58 | // onClick, adjust it like this:
|
59 | // activateEvent: 'onDoubleClick'
|
60 | });
|
61 |
|
62 | ...
|
63 |
|
64 | // Wrap within an element and render.
|
65 | React.createElement('div', editable(edit.input())(
|
66 | value, { columnIndex, rowData }, { ... custom props ... }
|
67 | ), (value, extraParameters, props) => ({
|
68 | children: <div>{value}</div>
|
69 | }));
|
70 |
|
71 | // Or in JSX
|
72 | <div {...editable(edit.input())(...)} />
|
73 | ```
|
74 |
|
75 | ## Editing Interface
|
76 |
|
77 | An editor should follow the following interface:
|
78 |
|
79 | * `({ value, onValue }) => <React element>`
|
80 |
|
81 | It will receive the current `value` and is expected to emit the result through `onValue` upon completion.
|
82 |
|
83 | ## Editors
|
84 |
|
85 | `react-edit` provides a few editors by default:
|
86 |
|
87 | * `edit.boolean({ props: <props> })` - If the initial value is true, allows setting to false and vice versa. Demo value defaults to false always
|
88 | * `edit.dropdown({ options: [[<value>, <name>]], props: <props> })` - The dropdown expects an array of value-name object pairs and emits the selected one.
|
89 | * `edit.input({ props: <props> })` - A wrapper for a regular input.
|
90 |
|
91 | ## Writing a Custom Editor
|
92 |
|
93 | If you want to implement a custom editor, you should accept `value` and `onValue` prop pair. The former will contain the current value and `onValue` should return a new one. It can be convenient to curry your editor so that you can pass custom `props` to it easily. Consider the following example.
|
94 |
|
95 | ```jsx
|
96 | /*
|
97 | import React from 'react';
|
98 | */
|
99 |
|
100 | const boolean = ({ props } = {}) => {
|
101 | const Boolean = ({ value, onValue }) => (
|
102 | <div {...props}>
|
103 | <button
|
104 | disabled={value}
|
105 | onClick={() => onValue(true)}
|
106 | >✓
|
107 | </button>
|
108 | <button
|
109 | disabled={!value}
|
110 | onClick={() => onValue(false)}
|
111 | >✗
|
112 | </button>
|
113 | </div>
|
114 | );
|
115 | Boolean.propTypes = {
|
116 | value: React.PropTypes.any,
|
117 | onClick: React.PropTypes.func,
|
118 | onValue: React.PropTypes.func
|
119 | };
|
120 |
|
121 | return Boolean;
|
122 | };
|
123 |
|
124 | const Boolean = boolean({ style: {
|
125 | backgroundColor: '#ddd'
|
126 | }});
|
127 |
|
128 | <Boolean value onValue={v => alert(`You chose ${v}`)} />
|
129 | ```
|