UNPKG

hbp-quickfire

Version:

A library of useful user-interface components built with React on top of React Bootstrap and MobX

591 lines (305 loc) 36.2 kB
var _extends = Object.assign || function (target) {for (var i = 1; i < arguments.length; i++) {var source = arguments[i];for (var key in source) {if (Object.prototype.hasOwnProperty.call(source, key)) {target[key] = source[key];}}}return target;};var _createClass = function () {function defineProperties(target, props) {for (var i = 0; i < props.length; i++) {var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);}}return function (Constructor, protoProps, staticProps) {if (protoProps) defineProperties(Constructor.prototype, protoProps);if (staticProps) defineProperties(Constructor, staticProps);return Constructor;};}();var _dec, _dec2, _class, _dec3, _class3;function _classCallCheck(instance, Constructor) {if (!(instance instanceof Constructor)) {throw new TypeError("Cannot call a class as a function");}}function _possibleConstructorReturn(self, call) {if (!self) {throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return call && (typeof call === "object" || typeof call === "function") ? call : self;}function _inherits(subClass, superClass) {if (typeof superClass !== "function" && superClass !== null) {throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);}subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;} /* * Copyright (c) Human Brain Project * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import React from "react"; import { inject, observer } from "mobx-react"; import { toJS } from "mobx";import FormGroup from "react-bootstrap/lib/FormGroup";import Glyphicon from "react-bootstrap/lib/Glyphicon";import Alert from "react-bootstrap/lib/Alert";import Button from "react-bootstrap/lib/Button";import DropdownButton from "react-bootstrap/lib/DropdownButton";import MenuItem from "react-bootstrap/lib/MenuItem";import OverlayTrigger from "react-bootstrap/lib/OverlayTrigger";import Tooltip from "react-bootstrap/lib/Tooltip"; import ReactDataSheet from "react-datasheet"; import injectStyles from "react-jss";import isFunction from "lodash/isFunction"; import SingleField from "./SingleField"; import FieldLabel from "./FieldLabel";import isArray from "lodash/isArray";import isObject from "lodash/isObject"; var styles = { "@global": { "span.data-grid-container, span.data-grid-container:focus": " \n outline: none;\n ", ".data-grid-container .data-grid": " \n table-layout: fixed;\n border-collapse: collapse;\n width:100%;\n ", ".data-grid-container .data-grid .cell.updated": " \n background-color: rgba(0, 145, 253, 0.16);\n transition : background-color 0ms ease ;\n ", ".data-grid-container .data-grid .cell": " \n height: 17px;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n cursor: cell;\n background-color: white;\n transition : background-color 500ms ease;\n vertical-align: top;\n text-align: left;\n border: 1px solid #DDD;\n padding: 0;\n ", ".data-grid-container .data-grid .cell.selected": " \n border: 1px double rgb(33, 133, 208);\n transition: none;\n box-shadow: inset 0 -1000px 0 rgba(33, 133, 208, 0.15);\n ", ".quickfire-field-data-sheet:not(.quickfire-readmode) .data-grid-container .data-grid .cell.read-only, .data-grid-container .data-grid th.cell.read-only": " \n background: whitesmoke;\n color: #999;\n text-align: center;\n font-weight: normal;\n ", ".data-grid-container .data-grid .cell > .text": " \n padding: 2px 5px;\n text-overflow: ellipsis;\n overflow: hidden;\n ", ".data-grid-container .data-grid .cell > input": " \n outline: none !important;\n border: 1px solid rgb(33, 133, 208);\n text-align:right;\n width: 100%;\n height: 100%;\n background: none;\n display: block;\n ", ".data-grid-container .data-grid .cell, .data-grid-container .data-grid.wrap .cell, .data-grid-container .data-grid.wrap .cell.wrap, .data-grid-container .data-grid .cell.wrap, .data-grid-container .data-grid.nowrap .cell.wrap, .data-grid-container .data-grid.clip .cell.wrap": " \n white-space: normal;\n word-wrap: break-word;\n overflow-wrap: break-word;\n\n -webkit-hyphens: auto;\n -moz-hyphens: auto;\n hyphens: auto;\n ", ".data-grid-container .data-grid.nowrap .cell, .data-grid-container .data-grid.nowrap .cell.nowrap, .data-grid-container .data-grid .cell.nowrap, .data-grid-container .data-grid.wrap .cell.nowrap, .data-grid-container .data-grid.clip .cell.nowrap": " \n white-space: nowrap;\n overflow-x: visible;\n ", ".data-grid-container .data-grid.clip .cell, .data-grid-container .data-grid.clip .cell.clip, .data-grid-container .data-grid .cell.clip, .data-grid-container .data-grid.wrap .cell.clip, .data-grid-container .data-grid.nowrap .cell.clip": " \n white-space: nowrap;\n overflow-x: hidden;\n ", ".data-grid-container .data-grid .cell .value-viewer, .data-grid-container .data-grid .cell .data-editor": " \n padding: 2px 4px;\n display: block;\n min-height:24px;\n ", ".data-grid-container .data-grid .action-header": { width: "23px" }, ".data-grid-container .data-grid .action-cell": { background: "white", border: "1px solid #DDD", "& .dropdown-toggle": { border: "none", borderRadius: "0" }, "& .dropdown-menu": { left: "auto", right: 0 } } }, btnAddRow: { marginTop: "12px" }, textareaLine: { "&:empty::before": { content: "'\\00a0'" } } }; /** * Form component allowing to edit a spreadsheet-like data * It uses the react-datasheet npm package to display to field * @class DataSheetField * @memberof FormFields * @namespace DataSheetField */var DataSheetField = (_dec = inject("formStore"), _dec2 = injectStyles(styles), _dec(_class = _dec2(_class = observer(_class = function (_React$Component) {_inherits(DataSheetField, _React$Component);function DataSheetField() {var _ref;var _temp, _this, _ret;_classCallCheck(this, DataSheetField);for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {args[_key] = arguments[_key];}return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = DataSheetField.__proto__ || Object.getPrototypeOf(DataSheetField)).call.apply(_ref, [this].concat(args))), _this), _this. triggerOnChange = function () { Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value").set. call(_this.hiddenInputRef, JSON.stringify(_this.props.field.getValue(false))); var event = new Event("input", { bubbles: true }); _this.hiddenInputRef.dispatchEvent(event); }, _this. handleCellChange = function (changes, outOfScopeChanges) {var _this$props = _this.props,field = _this$props.field,formStore = _this$props.formStore; if (field.readOnly || field.disabled || field.readMode || formStore.readMode) { return; } var proceed = function proceed() { field.applyChanges(changes, outOfScopeChanges); _this.triggerOnChange(); }; if (isFunction(_this.props.onBeforeSetValue)) { _this.props.onBeforeSetValue(proceed, field, changes, outOfScopeChanges); } else { proceed(); } }, _this. handleAddRow = function () {var _this$props2 = _this.props,field = _this$props2.field,formStore = _this$props2.formStore; if (field.readOnly || field.disabled || field.readMode || formStore.readMode) { return; } if (field.value.length < field.max) { var proceed = function proceed() { field.addRow(); _this.triggerOnChange(); }; if (isFunction(_this.props.onBeforeAddRow)) { _this.props.onBeforeAddRow(proceed, field); } else { proceed(); } } }, _this. handleKeyDown = function (e) {var _this$props3 = _this.props,field = _this$props3.field,formStore = _this$props3.formStore; if (field.readOnly || field.disabled || field.readMode || formStore.readMode) { return; } if (e.target.matches("input, textarea, select") //We are in the input of editing mode && e.keyCode === 13 //We pressed "Enter" && _this.dataSheetRef.state.end.i !== undefined && _this.dataSheetRef.state.end.i === field.value.length - 1 && field.value.length < field.max) { field.addRow(); //Set state of the child component to manually change the selected position //Without havind to go in full control mode of the position. _this.dataSheetRef.setState({ start: { i: _this.dataSheetRef.state.end.i + 1, j: _this.dataSheetRef.state.end.j }, end: { i: _this.dataSheetRef.state.end.i + 1, j: _this.dataSheetRef.state.end.j } }); _this.triggerOnChange(); } else if (e.keyCode === 9 //We pressed "Tab" && !e.shiftKey //But not shift + Tab && _this.dataSheetRef.state.end.i !== undefined && _this.dataSheetRef.state.end.i === field.value.length - 1 && _this.dataSheetRef.state.end.j !== undefined && _this.dataSheetRef.state.end.j === field.headers.filter(function (header) {return header.show !== false;}).length - 1 && field.value.length < field.max) { e.preventDefault(); field.addRow(); //Set state of the child component to manually change the selected position //Without havind to go in full control mode of the position. _this.dataSheetRef.setState({ start: { i: _this.dataSheetRef.state.end.i + 1, j: 0 }, end: { i: _this.dataSheetRef.state.end.i + 1, j: 0 } }); _this.triggerOnChange(); } else if (e.keyCode === 113 && _this.dataSheetRef.state.start.i !== undefined && _this.dataSheetRef.state.start.j !== undefined && field.headers.filter(function (header) {return header.show !== false;})[_this.dataSheetRef.state.end.j].readOnly !== true) { _this.dataSheetRef.setState({ editing: { i: _this.dataSheetRef.state.start.i, j: _this.dataSheetRef.state.start.j } }); _this.triggerOnChange(); } }, _this. keyGenerator = function (row) { return _this.props.formStore.getGeneratedKey(_this.props.field.value[row], "DataSheetFieldRow"); }, _this. renderCell = function (_ref2) {var cell = _ref2.cell; var result = null;var classes = _this.props.classes; if (cell.header.field && cell.header.field.type === "TextArea") { result = cell.value.split("\n").map(function (line, index) {return React.createElement("div", { className: classes.textareaLine, key: index }, line);}); } else { result = toJS(cell.value); if (!isArray(result)) { result = [result]; } result = result.map(function (value) {return isObject(value) ? value[cell.header.field && cell.header.field.mappingLabel || "label"] : value;}).join(", "); } return ( React.createElement("div", { className: "value-viewer" }, result)); }, _this. renderRow = function (props) {var _this$props4 = _this.props,field = _this$props4.field,formStore = _this$props4.formStore;var rowControlRemove = field.rowControlRemove,rowControlMove = field.rowControlMove,rowControlDuplicate = field.rowControlDuplicate,rowControlAdd = field.rowControlAdd,readOnly = field.readOnly,disabled = field.disabled; return ( React.createElement("tr", null, props.children, (rowControlRemove || rowControlMove || rowControlDuplicate || rowControlAdd) && !readOnly && !disabled && !field.readMode && !formStore.readMode && props.cells[0].row ? React.createElement("td", { className: "action-cell" }, React.createElement(DropdownButton, { bsSize: "xsmall", title: React.createElement(Glyphicon, { glyph: "menu-hamburger" }), id: "row-actions-" + props.row, noCaret: true }, rowControlMove ? React.createElement(MenuItem, { disabled: props.row <= 0, onClick: _this.handleMoveUpRow.bind(_this, props.row) }, React.createElement(Glyphicon, { glyph: "arrow-up" }), "\xA0Move up") : null, rowControlMove ? React.createElement(MenuItem, { disabled: props.row >= field.value.length - 1, onClick: _this.handleMoveDownRow.bind(_this, props.row) }, React.createElement(Glyphicon, { glyph: "arrow-down" }), "\xA0Move down") : null, rowControlMove && (rowControlDuplicate || rowControlRemove || rowControlAdd) ? React.createElement(MenuItem, { divider: true }) : null, rowControlDuplicate ? React.createElement(MenuItem, { disabled: field.value.length >= field.max, onClick: _this.handleDuplicateRow.bind(_this, props.row) }, React.createElement(Glyphicon, { glyph: "duplicate" }), "\xA0Duplicate") : null, rowControlDuplicate && (rowControlRemove || rowControlAdd) ? React.createElement(MenuItem, { divider: true }) : null, rowControlRemove ? React.createElement(MenuItem, { disabled: field.value.length <= field.min, onClick: _this.handleRemoveRow.bind(_this, props.cells[0].row) }, React.createElement(Glyphicon, { glyph: "trash" }), "\xA0Delete") : null, rowControlRemove && rowControlAdd ? React.createElement(MenuItem, { divider: true }) : null, rowControlAdd ? React.createElement(MenuItem, { disabled: field.value.length >= field.max, onClick: _this.handleAddRowAbove.bind(_this, props.row) }, React.createElement(Glyphicon, { glyph: "plus" }), "\xA0Add a new row above") : null, rowControlAdd ? React.createElement(MenuItem, { disabled: field.value.length >= field.max, onClick: _this.handleAddRowBelow.bind(_this, props.row) }, React.createElement(Glyphicon, { glyph: "plus" }), "\xA0Add a new row below") : null)) : null)); }, _this. renderDataEditor = function (props) {return React.createElement(FieldEditor, props);}, _this. renderSheet = function (props) {var _this$props5 = _this.props,field = _this$props5.field,formStore = _this$props5.formStore;var rowControlRemove = field.rowControlRemove,rowControlMove = field.rowControlMove,rowControlDuplicate = field.rowControlDuplicate,rowControlAdd = field.rowControlAdd,readOnly = field.readOnly,disabled = field.disabled; return ( React.createElement("table", { className: props.className }, React.createElement("thead", null, React.createElement("tr", null, field.headers.map(function (header) { if (header.show !== false) { return React.createElement("th", { key: header.key, className: "cell read-only", style: { width: header.width } }, header.label, "\xA0", header.labelTooltip ? React.createElement(OverlayTrigger, { placement: header.labelTooltipPlacement || "top", overlay: React.createElement(Tooltip, { id: formStore.getGeneratedKey(_this.props.field, "label-tooltip") }, header.labelTooltip) }, React.createElement(Glyphicon, { glyph: "question-sign" })) : null); } }).filter(function (cell) {return cell !== undefined;}), (rowControlRemove || rowControlMove || rowControlDuplicate || rowControlAdd) && !readOnly && !disabled && !field.readMode && !formStore.readMode ? React.createElement("th", { className: "action-header" }) : null)), React.createElement("tbody", null, props.children))); }, _temp), _possibleConstructorReturn(_this, _ret);} //The only way to trigger an onChange event in React is to do the following //Basically changing the field value, bypassing the react setter and dispatching an "input" // event on a proper html input node //See for example the discussion here : https://stackoverflow.com/a/46012210/9429503 _createClass(DataSheetField, [{ key: "handleRemoveRow", value: function handleRemoveRow(row, e) {var _this2 = this;var _props = this.props,field = _props.field,formStore = _props.formStore;if (field.readOnly || field.disabled || field.readMode || formStore.readMode) {return;}e.stopPropagation();if (field.value.length > field.min) {var proceed = function proceed() {field.removeRow(row);_this2.triggerOnChange();};if (isFunction(this.props.onBeforeRemoveRow)) {this.props.onBeforeRemoveRow(proceed, field, row);} else {proceed();}}} }, { key: "handleMoveUpRow", value: function handleMoveUpRow(rowIndex, e) {var _this3 = this;var _props2 = this.props,field = _props2.field,formStore = _props2.formStore;if (field.readOnly || field.disabled || field.readMode || formStore.readMode) {return;}e.stopPropagation();if (rowIndex > 0) {var proceed = function proceed() {field.moveRow(rowIndex, rowIndex - 1);_this3.triggerOnChange();};if (isFunction(this.props.onBeforeMoveUpRow)) {this.props.onBeforeMoveUpRow(proceed, field, rowIndex);} else {proceed();}}} }, { key: "handleMoveDownRow", value: function handleMoveDownRow(rowIndex, e) {var _this4 = this;var _props3 = this.props,field = _props3.field,formStore = _props3.formStore;if (field.readOnly || field.disabled || field.readMode || formStore.readMode) {return;}e.stopPropagation();if (rowIndex < field.value.length - 1) {var proceed = function proceed() {field.moveRow(rowIndex, rowIndex + 1);_this4.triggerOnChange();};if (isFunction(this.props.onBeforeMoveDownRow)) {this.props.onBeforeMoveDownRow(proceed, field, rowIndex);} else {proceed();}}} }, { key: "handleDuplicateRow", value: function handleDuplicateRow(rowIndex, e) {var _this5 = this;var _props4 = this.props,field = _props4.field,formStore = _props4.formStore;if (field.readOnly || field.disabled || field.readMode || formStore.readMode) {return;}e.stopPropagation();if (field.value.length < field.max) {var proceed = function proceed() {_this5.props.field.duplicateRow(rowIndex);_this5.triggerOnChange();};if (isFunction(this.props.onBeforeDuplicateRow)) {this.props.onBeforeDuplicateRow(proceed, field, rowIndex);} else {proceed();}}} }, { key: "handleAddRowAbove", value: function handleAddRowAbove(rowIndex, e) {var _this6 = this;var _props5 = this.props,field = _props5.field,formStore = _props5.formStore;if (field.readOnly || field.disabled || field.readMode || formStore.readMode) {return;}e.stopPropagation();if (field.value.length < field.max) {var proceed = function proceed() {_this6.props.field.addRow(rowIndex);_this6.triggerOnChange();};if (isFunction(this.props.onBeforeAddRow)) {this.props.onBeforeAddRow(proceed, field, rowIndex);} else {proceed();}}} }, { key: "handleAddRowBelow", value: function handleAddRowBelow(rowIndex, e) {var _this7 = this;var _props6 = this.props,field = _props6.field,formStore = _props6.formStore;if (field.readOnly || field.disabled || field.readMode || formStore.readMode) {return;}e.stopPropagation();if (field.value.length < field.max) {var proceed = function proceed() {_this7.props.field.addRow(rowIndex + 1);_this7.triggerOnChange();};if (isFunction(this.props.onBeforeAddRow)) {this.props.onBeforeAddRow(proceed, field, rowIndex + 1);} else {proceed();}}} }, { key: "handleChange", value: function handleChange(e) {e.preventDefault();} }, { key: "prepareData", value: function prepareData() {var grid = [];var _props7 = this.props,field = _props7.field,formStore = _props7.formStore;var values = field.value,headers = field.headers,disabled = field.disabled,readOnly = field.readOnly; values.forEach(function (value) { grid.push(headers.map(function (header) { if (header.show !== false) { return { value: value[header.key], row: value, key: header.key, header: header, readOnly: disabled || readOnly || field.readMode || formStore.readMode || !!header.readOnly }; } }).filter(function (cell) {return cell !== undefined;})); }); return grid; } }, { key: "render", value: function render() {var _this8 = this; if (this.props.formStore.readMode || this.props.field.readMode) { return this.renderReadMode(); }var _props8 = this.props,field = _props8.field,classes = _props8.classes;var values = field.value,disabled = field.disabled,readOnly = field.readOnly,validationState = field.validationState,validationErrors = field.validationErrors,max = field.max,clipContent = field.clipContent,buttonLabel = field.buttonLabel; var grid = this.prepareData(); return ( React.createElement(FormGroup, { className: "quickfire-field-data-sheet " + (!values.length ? "quickfire-empty-field" : "") + " " + (disabled ? "quickfire-field-disabled" : "") + " " + (readOnly ? "quickfire-field-readonly" : ""), validationState: validationState }, React.createElement(FieldLabel, { field: this.props.field }), React.createElement("div", null, React.createElement("div", { className: "quickfire-data-sheet-container", onChange: this.handleChange, onKeyDown: this.handleKeyDown }, React.createElement(ReactDataSheet, { ref: function ref(_ref3) {return _this8.dataSheetRef = _ref3;}, overflow: clipContent ? "clip" : "wrap", data: grid, valueRenderer: function valueRenderer(cell) {return cell.value;}, valueViewer: this.renderCell, onCellsChanged: this.handleCellChange, rowRenderer: this.renderRow, sheetRenderer: this.renderSheet, keyFn: this.keyGenerator, dataEditor: this.renderDataEditor }), React.createElement(Button, { disabled: values.length >= max || readOnly || disabled, bsClass: classes.btnAddRow + " quickfire-data-sheet-add-button btn btn-primary btn-xs", onClick: this.handleAddRow }, buttonLabel)), React.createElement("input", { style: { display: "none" }, type: "text", ref: function ref(_ref4) {return _this8.hiddenInputRef = _ref4;} })), validationErrors && React.createElement(Alert, { bsStyle: "danger" }, validationErrors.map(function (error) {return React.createElement("p", { key: error }, error);})))); } }, { key: "renderReadMode", value: function renderReadMode() {var _this9 = this;var field = this.props.field;var value = field.value,disabled = field.disabled,readOnly = field.readOnly,clipContent = field.clipContent; var grid = this.prepareData(); return ( React.createElement("div", { className: "quickfire-field-data-sheet " + (!value.length ? "quickfire-empty-field" : "") + " quickfire-readmode " + (disabled ? "quickfire-field-disabled" : "") + " " + (readOnly ? "quickfire-field-readonly" : "") }, React.createElement(FieldLabel, { field: this.props.field }), isFunction(this.props.readModeRendering) ? this.props.readModeRendering(this.props.field) : React.createElement("div", { className: "quickfire-data-sheet-container" }, React.createElement(ReactDataSheet, { ref: function ref(_ref5) {return _this9.dataSheetRef = _ref5;}, overflow: clipContent ? "clip" : "wrap", data: grid, valueRenderer: function valueRenderer(cell) {return cell.value;}, valueViewer: this.renderCell, rowRenderer: this.renderRow, sheetRenderer: this.renderSheet, keyFn: this.keyGenerator })))); } }]);return DataSheetField;}(React.Component)) || _class) || _class) || _class);export { DataSheetField as default }; var editorStyle = { container: { "& .form-group": { marginBottom: 0 }, "& .form-control": { borderRadius: 0, padding: "1px 4px", height: "auto" }, "& select.form-control": { appearance: "none" } } };var FieldEditor = (_dec3 = injectStyles(editorStyle), _dec3(_class3 = function (_React$Component2) {_inherits(FieldEditor, _React$Component2);function FieldEditor() {var _ref6;var _temp2, _this10, _ret2;_classCallCheck(this, FieldEditor);for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {args[_key2] = arguments[_key2];}return _ret2 = (_temp2 = (_this10 = _possibleConstructorReturn(this, (_ref6 = FieldEditor.__proto__ || Object.getPrototypeOf(FieldEditor)).call.apply(_ref6, [this].concat(args))), _this10), _this10. handleChange = function () { _this10.props.onChange(_this10.fieldRef.field.getValue()); }, _this10. handleKeyDown = function (e) { var isTextArea = _this10.props.cell.header.field && _this10.props.cell.header.field.type === "TextArea"; var isInputTextMultiple = _this10.props.cell.header.field && _this10.props.cell.header.field.type === "InputTextMultiple"; var isDropdownSelect = _this10.props.cell.header.field && _this10.props.cell.header.field.type === "DropdownSelect"; if (e.keyCode !== 13 || !isTextArea && !isInputTextMultiple && !isDropdownSelect) { _this10.props.onKeyDown(e); } else { e.stopPropagation(); } }, _temp2), _possibleConstructorReturn(_this10, _ret2);}_createClass(FieldEditor, [{ key: "componentDidMount", value: function componentDidMount() {this.containerRef.querySelectorAll("input, select, textarea")[0].focus();this.handleChange();} }, { key: "render", value: function render() {var _this11 = this;var _props9 = this.props,value = _props9.value,classes = _props9.classes,cell = _props9.cell; var field = cell.header.field !== undefined ? toJS(cell.header.field) : { type: "InputText" }; field.cacheOptionsUrl = field.cacheOptionsUrl !== undefined ? field.cacheOptionsUrl : true; field.cacheDataUrl = field.cacheDataUrl !== undefined ? field.cacheOptionsUrl : true; field.value = toJS(value); return ( React.createElement("div", { ref: function ref(_ref8) {return _this11.containerRef = _ref8;}, className: "quickfire-data-sheet-editor-field " + classes.container }, React.createElement(SingleField, _extends({}, field, { ref: function ref(_ref7) {return _this11.fieldRef = _ref7;}, onChange: this.handleChange, onLoad: this.handleChange, onKeyDown: this.handleKeyDown })))); } }]);return FieldEditor;}(React.Component)) || _class3);