ekko
Version:
Excel like Grid in React
238 lines (208 loc) • 7.37 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = _interopRequireDefault(require("react"));
var _nidalee = require("nidalee");
var _styles = require("./styles");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
class Cell extends _react.default.PureComponent {
constructor(...args) {
var _temp;
return _temp = super(...args), _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(this, "state", {
isEditing: false,
menuPostion: null,
previousValue: this.props.value
}), "setMenuPosition", mousePos => {
// TODO better algorithm to determin the position
// assume for now menu is 120px w, 80px h;
const menuWith = 120;
const menuHeight = 80;
const menuPostion = {};
if (mousePos.x + menuWith > window.innerWidth + window.pageXOffset) {
menuPostion.x = mousePos.x - menuWith;
} else {
menuPostion.x = mousePos.x;
}
if (mousePos.y + menuHeight > window.innerHeight + window.pageYOffset) {
menuPostion.y = mousePos.y - menuHeight;
} else {
menuPostion.y = mousePos.y;
}
this.setState({
menuPostion
});
console.log(menuPostion);
}), "validateProps", () => {
const _this$props = this.props,
value = _this$props.value,
render = _this$props.render;
if (typeof value === 'object' && !render) {
console.warn('Ekko:', 'No render is specified for complex type value. `JSON.stringify` will be used');
}
}), "startEditing", () => {
const editor = this.props.editor;
if (editor) {
this.setState({
isEditing: true
});
}
}), "finishEditing", () => {
const editor = this.props.editor;
if (editor) {
this.setState({
isEditing: false
});
}
}), "handleUpdate", newValue => {
const _this$props2 = this.props,
updater = _this$props2.updater,
onCellUpdate = _this$props2.onCellUpdate,
value = _this$props2.value;
if (updater) {
onCellUpdate(newValue, updater);
}
this.setState({
isEditing: false,
previousValue: value
});
}), "handleUndo", event => {
event.stopPropagation();
const _this$props3 = this.props,
updater = _this$props3.updater,
onCellUpdate = _this$props3.onCellUpdate;
if (updater) {
onCellUpdate(this.state.previousValue, updater);
}
this.closeMenu();
}), "handleKeyDown", event => {
if (event.which === 13) {
this.startEditing();
}
}), "handleClick", () => {
// clicking anywhere closes the menu
// TODO this is hacky, need a better soluton
this.closeMenu();
}), "handleBlur", () => {// this.closeMenu();
}), "toggleEditing", isEditing => {
this.setState({
isEditing
});
}), "handleContextMenu", event => {
event.preventDefault();
this.setMenuPosition({
x: event.pageX,
y: event.pageY
});
}), "closeMenu", () => {
// shouldn't show menu if it is editing for now
if (!this.state.isEditing) {
this.setState({
menuPostion: null
});
}
}), "renderValue", () => {
const _this$props4 = this.props,
value = _this$props4.value,
render = _this$props4.render;
return _react.default.createElement("div", {
className: _styles.cssCellValue,
tabIndex: -1
}, render ? render(value) : this.stringifiedValue);
}), "renderEditor", () => {
const _this$props5 = this.props,
value = _this$props5.value,
editor = _this$props5.editor,
editorDisplay = _this$props5.editorDisplay,
render = _this$props5.render; // console.log('render Cell', value);
if (editorDisplay === 'popover' && editor && editor !== 'inline') {
return _react.default.createElement(_nidalee.Popover, {
expand: this.state.isEditing,
onExpand: this.startEditing,
trigger: "onDoubleClick",
onCollapse: this.finishEditing,
expander: this.renderValue(),
align: "right",
direction: "bottom",
className: "editor"
}, editor({
value,
onUpdate: this.handleUpdate,
onCancel: this.finishEditing
}));
}
if (editorDisplay === 'dialog' && editor && editor !== 'inline') {
return _react.default.createElement(_nidalee.Dialog, {
open: this.state.isEditing,
onOpen: this.startEditing,
onClose: this.finishEditing,
trigger: "onDoubleClick",
opener: this.renderValue(),
showOverlay: true,
className: "editor"
}, editor({
value,
onUpdate: this.handleUpdate,
onCancel: this.finishEditing
}));
}
if (editor === 'inline' && (typeof value === 'string' || typeof value === 'number')) {
return _react.default.createElement(_nidalee.InlineEdit, {
tabIndex: -1,
defaultValue: this.stringifiedValue,
editing: this.state.isEditing,
render: render,
toggleEditing: this.toggleEditing,
onSave: this.handleUpdate,
className: "editor"
});
} // inline, but object?
return this.renderValue();
}), "renderContextMenu", () => {
const updater = this.props.updater;
const menuPostion = this.state.menuPostion;
return updater && menuPostion ? _react.default.createElement(_nidalee.Menu, {
style: {
left: menuPostion.x,
top: menuPostion.y
},
className: _styles.cssCellMenu
}, _react.default.createElement(_nidalee.Menu.Item, {
onClick: this.handleUndo
}, "Undo")) : null;
}), _temp;
}
componentDidMount() {
this.validateProps();
}
componentWillReceiveProps(nextProps) {
Object.keys(nextProps).forEach(key => {
if (nextProps[key] !== this.props[key]) {
console.log(`\t[Cell] Prop ${key} changed`);
}
});
}
componentDidUpdate() {
this.validateProps();
}
get stringifiedValue() {
const value = this.props.value;
return typeof value === 'string' || typeof value === 'number' ? `${value}` : JSON.stringify(value);
}
render() {
console.log('[Cell]: render');
return _react.default.createElement("div", {
tabIndex: 0,
role: "textbox",
className: _styles.cssCell,
onKeyDown: this.handleKeyDown,
onContextMenu: this.handleContextMenu,
onBlur: this.handleBlur,
onClick: this.handleClick
}, this.renderEditor(), this.renderContextMenu());
}
}
var _default = Cell;
exports.default = _default;