https://github.com/reactabular/react-edit
Inline editing utilities for React (MIT)
https://github.com/reactabular/react-edit
Last synced: 9 months ago
JSON representation
Inline editing utilities for React (MIT)
- Host: GitHub
- URL: https://github.com/reactabular/react-edit
- Owner: reactabular
- License: mit
- Created: 2016-11-25T20:24:27.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2018-04-05T18:39:05.000Z (almost 8 years ago)
- Last Synced: 2025-05-02T02:03:27.595Z (9 months ago)
- Language: JavaScript
- Size: 88.9 KB
- Stars: 17
- Watchers: 3
- Forks: 6
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.md
Awesome Lists containing this project
README
[](http://travis-ci.org/reactabular/react-edit) [](https://www.bithound.io/github/reactabular/react-edit) [](https://codecov.io/gh/reactabular/react-edit)
# react-edit - Inline editing utilities for React
`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).
## API
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.
**Example:**
```jsx
...
import cloneDeep from 'lodash/cloneDeep';
import findIndex from 'lodash/findIndex';
import * as edit from 'react-edit';
...
// Define how to manipulate rows through edit.
const editable = edit.edit({
// Determine whether the current cell is being edited or not.
isEditing: ({ columnIndex, rowData }) => columnIndex === rowData.editing,
// The user requested activation, mark the current cell as edited.
// IMPORTANT! If you stash the rows at this.state.rows, DON'T
// mutate it as that will break Table.Body optimization check.
//
// You also have access to `event` here.
onActivate: ({ columnIndex, rowData, event }) => {
event.stopPropagation();
const index = findIndex(this.state.rows, { id: rowData.id });
const rows = cloneDeep(this.state.rows);
rows[index].editing = columnIndex;
this.setState({ rows });
},
// Capture the value when the user has finished and update
// application state.
onValue: ({ value, rowData, property }) => {
const index = findIndex(this.state.rows, { id: rowData.id });
const rows = cloneDeep(this.state.rows);
rows[index][property] = value;
rows[index].editing = false;
this.setState({ rows });
},
// It's possible to shape the value passed to the editor. See
// the Excel example for a concrete example.
// getEditedValue: v => v.value
// If you want to change default value/onValue, you can do it through
// editingProps: { value: 'value', onValue: 'onValue' }
// In case you want to trigger activation using something else than
// onClick, adjust it like this:
// activateEvent: 'onDoubleClick'
});
...
// Wrap within an element and render.
React.createElement('div', editable(edit.input())(
value, { columnIndex, rowData }, { ... custom props ... }
), (value, extraParameters, props) => ({
children:
{value}
}));
// Or in JSX
```
## Editing Interface
An editor should follow the following interface:
* `({ value, onValue, extraParameters }) => `
It will receive the current `value` and is expected to emit the result through `onValue` upon completion. You can capture row data, property name, and such through `extraParameters`.
## Editors
`react-edit` provides a few editors by default:
* `edit.boolean({ props: })` - If the initial value is true, allows setting to false and vice versa. Demo value defaults to false always
* `edit.dropdown({ options: [[, ]], props: })` - The dropdown expects an array of value-name object pairs and emits the selected one.
* `edit.input({ props: })` - A wrapper for a regular input.
## Writing a Custom Editor
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.
```jsx
/*
import React from 'react';
import PropTypes from 'prop-types';
*/
const boolean = ({ props } = {}) => {
const Boolean = ({ value, onValue }) => (
onValue(true)}
>✓
onValue(false)}
>✗
);
Boolean.propTypes = {
value: PropTypes.any,
onClick: PropTypes.func,
onValue: PropTypes.func
};
return Boolean;
};
const Boolean = boolean({ style: {
backgroundColor: '#ddd'
}});
alert(`You chose ${v}`)} />
```
## License
MIT. See LICENSE for details.