react-microspreadsheet
Version:
A pluggable spreadsheet component.
195 lines (183 loc) • 5.96 kB
JavaScript
// Generated by CoffeeScript 1.8.0
var Cell, Cells, Clipboard, React, Spreadsheet, cellStore, dispatcher, div, input, mori, span, table, tbody, td, textarea, tr, utils, _ref;
React = require('react');
mori = require('mori');
_ref = React.DOM, table = _ref.table, tbody = _ref.tbody, tr = _ref.tr, td = _ref.td, div = _ref.div, span = _ref.span, input = _ref.input, textarea = _ref.textarea;
Cell = require('./Cell');
utils = require('./utils');
dispatcher = require('./dispatcher');
cellStore = require('./cells-store');
Spreadsheet = React.createClass({
displayName: 'ReactMicroSpreadsheet',
getInitialState: function() {
return {
cells: cellStore.getCells()
};
},
componentDidMount: function() {
cellStore.on('CHANGE', this.updateCells);
if (this.props.cells && this.props.cells.length) {
dispatcher.replaceCells(this.props.cells);
}
document.body.addEventListener('mousedown', this.handleClickOut);
return document.body.addEventListener('mouseup', this.handleMouseUpOut);
},
updateCells: function() {
var array, c, newCells, r, row, _i, _j, _len, _len1, _ref1;
newCells = cellStore.getCells();
this.setState({
cells: newCells,
caretPosition: cellStore.caretPosition,
clipboard: cellStore.clipboard
});
array = [];
_ref1 = mori.clj_to_js(newCells);
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
r = _ref1[_i];
row = [];
for (_j = 0, _len1 = r.length; _j < _len1; _j++) {
c = r[_j];
row.push(c.raw);
}
array.push(row);
}
if (this.props.onChange) {
return this.props.onChange((function() {
var _k, _len2, _ref2, _results;
_ref2 = mori.clj_to_js(newCells);
_results = [];
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
r = _ref2[_k];
_results.push((function() {
var _l, _len3, _results1;
_results1 = [];
for (_l = 0, _len3 = r.length; _l < _len3; _l++) {
c = r[_l];
_results1.push(c.raw);
}
return _results1;
})());
}
return _results;
})());
}
},
componentWillReceiveProps: function(nextProps) {
if (nextProps.cells && nextProps.cells.length) {
return dispatcher.replaceCells(nextProps.cells);
}
},
componentWillUnmount: function() {
cellStore.off('CHANGE', this.updateCells);
document.body.removeEventListener('mousedown', this.handleClickOut);
return document.body.removeEventListener('mouseup', this.handleMouseUpOut);
},
render: function() {
return div({
className: 'microspreadsheet'
}, Clipboard({
value: this.state.clipboard
}), Cells({
cells: this.state.cells,
caretPosition: this.state.caretPosition
}));
},
handleClickOut: function(e) {
var i, node, _i, _ref1;
for (i = _i = 4, _ref1 = e.path.length - 1; 4 <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = 4 <= _ref1 ? ++_i : --_i) {
node = e.path[i];
if (node === this.getDOMNode()) {
return;
}
}
return dispatcher.handleSheetClickedOut(e);
},
handleMouseUpOut: function(e) {
var i, node, _i, _ref1;
for (i = _i = 4, _ref1 = e.path.length - 1; 4 <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = 4 <= _ref1 ? ++_i : --_i) {
node = e.path[i];
if (node === this.getDOMNode()) {
return;
}
}
return dispatcher.handleSheetMouseUpOut(e);
}
});
Clipboard = React.createClass({
shouldComponentUpdate: function(nextProps) {
if (nextProps.value !== this.props.value) {
return true;
}
return false;
},
componentDidUpdate: function(prevProps) {
var node;
if (this.refs.clipboard) {
node = this.refs.clipboard.getDOMNode();
node.focus();
return node.setSelectionRange(0, node.value.length);
}
},
render: function() {
return div({
className: 'clipboard-container'
}, typeof this.props.value === 'string' ? textarea({
className: 'mousetrap clipboard',
ref: 'clipboard',
value: this.props.value,
onChange: this.handleChange
}) : void 0);
},
handleChange: function(e) {
return dispatcher.handleClipboardChanged(e.target.value);
}
});
Cells = React.createClass({
shouldComponentUpdate: function(nextProps) {
if (!mori.equals(nextProps.cells, this.props.cells || mori.equals(nextProps.caretPosition, this.props.caretPosition))) {
return true;
} else {
return false;
}
},
render: function() {
var c, i, j;
return table({}, tbody({}, tr({}, td({
className: 'label'
}), (function() {
var _i, _ref1, _results;
_results = [];
for (c = _i = 0, _ref1 = mori.count(mori.get(this.props.cells, 0)) - 1; 0 <= _ref1 ? _i <= _ref1 : _i >= _ref1; c = 0 <= _ref1 ? ++_i : --_i) {
_results.push(td({
className: 'label',
key: c
}, utils.letters[c]));
}
return _results;
}).call(this)), (function() {
var _i, _ref1, _results;
_results = [];
for (i = _i = 0, _ref1 = mori.count(this.props.cells) - 1; 0 <= _ref1 ? _i <= _ref1 : _i >= _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
_results.push(tr({
key: i
}, td({
className: 'label'
}, i + 1), (function() {
var _j, _ref2, _results1;
_results1 = [];
for (j = _j = 0, _ref2 = mori.count(mori.get(this.props.cells, 0)) - 1; 0 <= _ref2 ? _j <= _ref2 : _j >= _ref2; j = 0 <= _ref2 ? ++_j : --_j) {
_results1.push(Cell({
rowKey: i,
key: j,
cell: mori.get_in(this.props.cells, [i, j]),
caretPosition: this.props.caretPosition
}));
}
return _results1;
}).call(this)));
}
return _results;
}).call(this)));
}
});
module.exports = Spreadsheet;