diff --git a/lib/DataCell.js b/lib/DataCell.js index 53ef0d5..f9badfb 100644 --- a/lib/DataCell.js +++ b/lib/DataCell.js @@ -84,29 +84,31 @@ var DataCell = function (_PureComponent) { _this.handleContextMenu = _this.handleContextMenu.bind(_this); _this.handleDoubleClick = _this.handleDoubleClick.bind(_this); - _this.state = { updated: false, reverting: false, value: '', committing: false }; + _this.state = { + updated: false, + reverting: false, + value: '', + committing: false + }; return _this; } _createClass(DataCell, [{ - key: 'componentWillReceiveProps', - value: function componentWillReceiveProps(nextProps) { + key: 'componentDidUpdate', + value: function componentDidUpdate(prevProps) { var _this2 = this; - if (initialValue(nextProps) !== initialValue(this.props)) { + if (initialValue(prevProps) !== initialValue(this.props)) { this.setState({ updated: true }); this.timeout = setTimeout(function () { return _this2.setState({ updated: false }); }, 700); } - if (nextProps.editing === true && this.props.editing === false) { - var value = nextProps.clearing ? '' : initialData(nextProps); + if (this.props.editing === true && prevProps.editing === false) { + var value = this.props.clearing ? '' : initialData(this.props); this.setState({ value: value, reverting: false }); } - } - }, { - key: 'componentDidUpdate', - value: function componentDidUpdate(prevProps) { + if (prevProps.editing === true && this.props.editing === false && !this.state.reverting && !this.state.committing && this.state.value !== initialData(this.props)) { this.props.onChange(this.props.row, this.props.col, this.state.value); } diff --git a/lib/helpers.js b/lib/helpers.js deleted file mode 100644 index 67592f1..0000000 --- a/lib/helpers.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.isMobile = isMobile; -function isMobile() { - var check = false; - - (function (a) { - if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw(n|u)|c55\/|capi|ccwa|cdm|cell|chtm|cldc|cmd|co(mp|nd)|craw|da(it|ll|ng)|dbte|dcs|devi|dica|dmob|do(c|p)o|ds(12|d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(|_)|g1 u|g560|gene|gf5|gmo|go(\.w|od)|gr(ad|un)|haie|hcit|hd(m|p|t)|hei|hi(pt|ta)|hp( i|ip)|hsc|ht(c(| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i(20|go|ma)|i230|iac( ||\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|[a-w])|libw|lynx|m1w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|mcr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|([1-8]|c))|phil|pire|pl(ay|uc)|pn2|po(ck|rt|se)|prox|psio|ptg|qaa|qc(07|12|21|32|60|[2-7]|i)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h|oo|p)|sdk\/|se(c(|0|1)|47|mc|nd|ri)|sgh|shar|sie(|m)|sk0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h|v|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl|tdg|tel(i|m)|tim|tmo|to(pl|sh)|ts(70|m|m3|m5)|tx9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas|your|zeto|zte/i.test(a.substr(0, 4))) check = true; - })(navigator.userAgent || navigator.vendor || window.opera); - - return check; -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e440de2..17b5213 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "react-datasheet", - "version": "1.3.13", + "version": "1.4.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -3862,9 +3862,9 @@ "dev": true }, "handlebars": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.2.0.tgz", - "integrity": "sha512-Kb4xn5Qh1cxAKvQnzNWZ512DhABzyFNmsaJf3OAkWNa4NkaqWcNI8Tao8Tasi0/F4JD9oyG0YxuFyvyR57d+Gw==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.1.tgz", + "integrity": "sha512-C29UoFzHe9yM61lOsIlCE5/mQVGrnIOrOq7maQl76L7tYPCgC1og0Ajt6uWnX4ZTxBPnjw+CUvawphwCfJgUnA==", "dev": true, "requires": { "neo-async": "^2.6.0", @@ -8183,20 +8183,20 @@ "dev": true }, "uglify-js": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", - "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", + "version": "3.6.8", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.8.tgz", + "integrity": "sha512-XhHJ3S3ZyMwP8kY1Gkugqx3CJh2C3O0y8NPiSxtm1tyD/pktLAkFZsFGpuNfTZddKDQ/bbDBLAd2YyA1pbi8HQ==", "dev": true, "optional": true, "requires": { - "commander": "~2.20.0", + "commander": "~2.20.3", "source-map": "~0.6.1" }, "dependencies": { "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true, "optional": true }, diff --git a/package.json b/package.json index 14d1965..f125dd3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-datasheet", - "version": "1.3.14", + "version": "1.4.0", "description": "Excel-like data grid for React", "repository": { "type": "git", @@ -61,9 +61,9 @@ "watch": "^1.0.2" }, "peerDependencies": { - "react": ">=15.3.0", - "react-dom": ">=15.3.0", - "prop-types": "^15.5.9" + "react": ">=16", + "react-dom": ">=16", + "prop-types": ">=16" }, "dependencies": {}, "files": [ diff --git a/src/DataCell.js b/src/DataCell.js index 26516dd..a2f25ad 100644 --- a/src/DataCell.js +++ b/src/DataCell.js @@ -1,7 +1,15 @@ import React, { PureComponent } from 'react' import PropTypes from 'prop-types' -import {ENTER_KEY, ESCAPE_KEY, TAB_KEY, RIGHT_KEY, LEFT_KEY, UP_KEY, DOWN_KEY} from './keys' +import { + ENTER_KEY, + ESCAPE_KEY, + TAB_KEY, + RIGHT_KEY, + LEFT_KEY, + UP_KEY, + DOWN_KEY +} from './keys' import Cell from './Cell' import CellShape from './CellShape' @@ -9,11 +17,11 @@ import DataEditor from './DataEditor' import ValueViewer from './ValueViewer' import { renderValue, renderData } from './renderHelpers' -function initialData ({cell, row, col, valueRenderer, dataRenderer}) { +function initialData ({ cell, row, col, valueRenderer, dataRenderer }) { return renderData(cell, row, col, valueRenderer, dataRenderer) } -function initialValue ({cell, row, col, valueRenderer}) { +function initialValue ({ cell, row, col, valueRenderer }) { return renderValue(cell, row, col, valueRenderer) } @@ -35,26 +43,31 @@ export default class DataCell extends PureComponent { this.handleContextMenu = this.handleContextMenu.bind(this) this.handleDoubleClick = this.handleDoubleClick.bind(this) - this.state = {updated: false, reverting: false, value: '', committing: false} + this.state = { + updated: false, + reverting: false, + value: '', + committing: false + } } - componentWillReceiveProps (nextProps) { - if (initialValue(nextProps) !== initialValue(this.props)) { - this.setState({updated: true}) - this.timeout = setTimeout(() => this.setState({updated: false}), 700) + componentDidUpdate (prevProps) { + if (initialValue(prevProps) !== initialValue(this.props)) { + this.setState({ updated: true }) + this.timeout = setTimeout(() => this.setState({ updated: false }), 700) } - if (nextProps.editing === true && this.props.editing === false) { - const value = nextProps.clearing ? '' : initialData(nextProps) + if (this.props.editing === true && prevProps.editing === false) { + const value = this.props.clearing ? '' : initialData(this.props) this.setState({ value, reverting: false }) } - } - componentDidUpdate (prevProps) { - if (prevProps.editing === true && - this.props.editing === false && - !this.state.reverting && - !this.state.committing && - this.state.value !== initialData(this.props)) { + if ( + prevProps.editing === true && + this.props.editing === false && + !this.state.reverting && + !this.state.committing && + this.state.value !== initialData(this.props) + ) { this.props.onChange(this.props.row, this.props.col, this.state.value) } } @@ -68,7 +81,7 @@ export default class DataCell extends PureComponent { } handleCommit (value, e) { - const {onChange, onNavigate} = this.props + const { onChange, onNavigate } = this.props if (value !== initialData(this.props)) { this.setState({ value, committing: true }) onChange(this.props.row, this.props.col, value) @@ -82,33 +95,33 @@ export default class DataCell extends PureComponent { } handleRevert () { - this.setState({reverting: true}) + this.setState({ reverting: true }) this.props.onRevert() } handleMouseDown (e) { - const {row, col, onMouseDown, cell} = this.props + const { row, col, onMouseDown, cell } = this.props if (!cell.disableEvents) { onMouseDown(row, col, e) } } handleMouseOver (e) { - const {row, col, onMouseOver, cell} = this.props + const { row, col, onMouseOver, cell } = this.props if (!cell.disableEvents) { onMouseOver(row, col) } } handleDoubleClick (e) { - const {row, col, onDoubleClick, cell} = this.props + const { row, col, onDoubleClick, cell } = this.props if (!cell.disableEvents) { onDoubleClick(row, col) } } handleContextMenu (e) { - const {row, col, onContextMenu, cell} = this.props + const { row, col, onContextMenu, cell } = this.props if (!cell.disableEvents) { onContextMenu(e, row, col) } @@ -119,9 +132,14 @@ export default class DataCell extends PureComponent { if (keyCode === ESCAPE_KEY) { return this.handleRevert() } - const {cell: {component}, forceEdit} = this.props + const { + cell: { component }, + forceEdit + } = this.props const eatKeys = forceEdit || !!component - const commit = keyCode === ENTER_KEY || keyCode === TAB_KEY || + const commit = + keyCode === ENTER_KEY || + keyCode === TAB_KEY || (!eatKeys && [LEFT_KEY, RIGHT_KEY, UP_KEY, DOWN_KEY].includes(keyCode)) if (commit) { @@ -130,7 +148,7 @@ export default class DataCell extends PureComponent { } renderComponent (editing, cell) { - const {component, readOnly, forceComponent} = cell + const { component, readOnly, forceComponent } = cell if ((editing && !readOnly) || forceComponent) { return component } @@ -161,23 +179,37 @@ export default class DataCell extends PureComponent { } render () { - const {row, col, cell, cellRenderer: CellRenderer, - valueRenderer, dataEditor, valueViewer, attributesRenderer, - selected, editing, onKeyUp} = this.props - const {updated} = this.state + const { + row, + col, + cell, + cellRenderer: CellRenderer, + valueRenderer, + dataEditor, + valueViewer, + attributesRenderer, + selected, + editing, + onKeyUp + } = this.props + const { updated } = this.state - const content = this.renderComponent(editing, cell) || - this.renderEditor(editing, cell, row, col, dataEditor) || - this.renderViewer(cell, row, col, valueRenderer, valueViewer) + const content = + this.renderComponent(editing, cell) || + this.renderEditor(editing, cell, row, col, dataEditor) || + this.renderViewer(cell, row, col, valueRenderer, valueViewer) const className = [ cell.className, - 'cell', cell.overflow, + 'cell', + cell.overflow, selected && 'selected', editing && 'editing', cell.readOnly && 'read-only', updated && 'updated' - ].filter(a => a).join(' ') + ] + .filter(a => a) + .join(' ') return ( + > {content} ) diff --git a/test/Datasheet.js b/test/Datasheet.js index 2612556..08bf60d 100644 --- a/test/Datasheet.js +++ b/test/Datasheet.js @@ -113,12 +113,12 @@ describe('Component', () => { 5 ).html()) - wrapper.setProps({ editing: true, selected: true }) - - expect(wrapper.html()).toEqual( - shallow( - - ).html()) + wrapper.setProps({ editing: true, selected: true }, () => { + expect(wrapper.html()).toEqual( + shallow( + + ).html()) + }) }) it('should properly render a flash when value changes', () => { @@ -142,11 +142,13 @@ describe('Component', () => { {...props} /> ) - wrapper.setProps({ cell: { value: 6, data: 6 }}) - expect(wrapper.html()).toEqual( - shallow( - 6 - ).html()) + wrapper.setProps({ cell: { value: 6, data: 6 }}, () => { + expect(wrapper.html()).toEqual( + shallow( + 6 + ).html()) + }) + }) })