UNPKG

fixed-react-data-grid-custom

Version:

Excel-like grid component built with React, with editors, keyboard navigation, copy & paste, and the like

218 lines 8.73 kB
import { __assign, __extends } from "tslib"; import React from 'react'; import classNames from 'classnames'; import { isElement, isValidElementType } from 'react-is'; import SimpleTextEditor from './SimpleTextEditor'; import ClickOutside from './ClickOutside'; var EditorContainer = /** @class */ (function (_super) { __extends(EditorContainer, _super); function EditorContainer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.changeCommitted = false; _this.changeCanceled = false; _this.editor = React.createRef(); _this.state = { isInvalid: false }; _this.onKeyDown = function (e) { switch (e.key) { case 'Enter': _this.onPressEnter(); break; case 'Tab': _this.onPressTab(); break; case 'Escape': _this.onPressEscape(e); break; case 'ArrowUp': case 'ArrowDown': _this.onPressArrowUpOrDown(e); break; case 'ArrowLeft': _this.onPressArrowLeft(e); break; case 'ArrowRight': _this.onPressArrowRight(e); break; default: break; } if (_this.props.onGridKeyDown) { _this.props.onGridKeyDown(e); } }; _this.onPressEnter = function () { _this.commit({ key: 'Enter' }); }; _this.onPressTab = function () { _this.commit({ key: 'Tab' }); }; _this.onPressEscape = function (e) { if (!_this.editorIsSelectOpen()) { _this.commitCancel(); } else { // prevent event from bubbling if editor has results to select e.stopPropagation(); } }; _this.onPressArrowUpOrDown = function (e) { if (_this.editorHasResults()) { // dont want to propogate as that then moves us round the grid e.stopPropagation(); } else { _this.commit(e); } }; _this.onPressArrowLeft = function (e) { // prevent event propogation. this disables left cell navigation if (!_this.isCaretAtBeginningOfInput()) { e.stopPropagation(); } else { _this.commit(e); } }; _this.onPressArrowRight = function (e) { // prevent event propogation. this disables right cell navigation if (!_this.isCaretAtEndOfInput()) { e.stopPropagation(); } else { _this.commit(e); } }; _this.editorHasResults = function () { var hasResults = _this.getEditor().hasResults; return hasResults ? hasResults() : false; }; _this.editorIsSelectOpen = function () { var isSelectOpen = _this.getEditor().isSelectOpen; return isSelectOpen ? isSelectOpen() : false; }; _this.getEditor = function () { return _this.editor.current; }; _this.getInputNode = function () { return _this.getEditor().getInputNode(); }; _this.commit = function (args) { if (args === void 0) { args = {}; } var onCommit = _this.props.onCommit; var updated = _this.getEditor().getValue(); if (_this.isNewValueValid(updated)) { _this.changeCommitted = true; var cellKey = _this.props.column.key; onCommit({ cellKey: cellKey, rowIdx: _this.props.rowIdx, updated: updated, key: args.key }); } }; _this.commitCancel = function () { _this.changeCanceled = true; _this.props.onCommitCancel(); }; _this.isNewValueValid = function (value) { var editor = _this.getEditor(); if (editor.validate) { var isValid = editor.validate(value); _this.setState({ isInvalid: !isValid }); return isValid; } return true; }; _this.isCaretAtBeginningOfInput = function () { var inputNode = _this.getInputNode(); return inputNode instanceof HTMLInputElement && inputNode.selectionEnd === 0; }; _this.isCaretAtEndOfInput = function () { var inputNode = _this.getInputNode(); return inputNode instanceof HTMLInputElement && inputNode.selectionStart === inputNode.value.length; }; _this.handleRightClick = function (e) { e.stopPropagation(); }; return _this; } EditorContainer.prototype.componentDidMount = function () { var inputNode = this.getInputNode(); if (inputNode instanceof HTMLElement) { inputNode.focus(); if (!this.getEditor().disableContainerStyles) { inputNode.className += ' editor-main'; inputNode.style.height = this.props.height - 1 + "px"; } } if (inputNode instanceof HTMLInputElement) { inputNode.select(); } }; EditorContainer.prototype.componentDidUpdate = function (prevProps) { if (prevProps.scrollLeft !== this.props.scrollLeft || prevProps.scrollTop !== this.props.scrollTop) { this.commitCancel(); } }; EditorContainer.prototype.componentWillUnmount = function () { if (!this.changeCommitted && !this.changeCanceled) { this.commit({ key: 'Enter' }); } }; EditorContainer.prototype.createEditor = function () { var editorProps = { ref: this.editor, column: this.props.column, value: this.getInitialValue(), rowMetaData: this.getRowMetaData(), rowData: this.props.rowData, height: this.props.height, onCommit: this.commit, onCommitCancel: this.commitCancel, onBlur: this.commit, onOverrideKeyDown: this.onKeyDown }; var CustomEditor = this.props.column.editor; // return custom column editor or SimpleEditor if none specified if (isElement(CustomEditor)) { return React.cloneElement(CustomEditor, editorProps); } if (isValidElementType(CustomEditor)) { return React.createElement(CustomEditor, __assign({}, editorProps)); } return (React.createElement(SimpleTextEditor, { ref: this.editor, column: this.props.column, value: this.getInitialValue(), onBlur: this.commit })); }; EditorContainer.prototype.getRowMetaData = function () { // clone row data so editor cannot actually change this // convention based method to get corresponding Id or Name of any Name or Id property if (this.props.column.getRowMetaData) { return this.props.column.getRowMetaData(this.props.rowData, this.props.column); } }; EditorContainer.prototype.getInitialValue = function () { var _a = this.props, key = _a.firstEditorKeyPress, value = _a.value; if (key === 'Delete' || key === 'Backspace') { return ''; } if (key === 'Enter') { return value; } return key || value; }; EditorContainer.prototype.renderStatusIcon = function () { return this.state.isInvalid && React.createElement("span", { className: "glyphicon glyphicon-remove form-control-feedback" }); }; EditorContainer.prototype.render = function () { var _a = this.props, width = _a.width, height = _a.height, left = _a.left, top = _a.top; var className = classNames('rdg-editor-container', { 'has-error': this.state.isInvalid === true }); return (React.createElement(ClickOutside, { onClickOutside: this.commit }, React.createElement("div", { className: className, style: { height: height, width: width, left: left, top: top }, onKeyDown: this.onKeyDown, onContextMenu: this.handleRightClick }, this.createEditor(), this.renderStatusIcon()))); }; EditorContainer.displayName = 'EditorContainer'; return EditorContainer; }(React.Component)); export default EditorContainer; //# sourceMappingURL=EditorContainer.js.map