react-data-grid
Version:
Data grid for React
1,571 lines (1,346 loc) • 230 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("react"), require("react-dom"));
else if(typeof define === 'function' && define.amd)
define(["react", "react-dom"], factory);
else if(typeof exports === 'object')
exports["ReactDataGrid"] = factory(require("react"), require("react-dom"));
else
root["ReactDataGrid"] = factory(root["React"], root["ReactDOM"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_1__, __WEBPACK_EXTERNAL_MODULE_2__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var Grid = __webpack_require__(49);
var Row = __webpack_require__(15);
var Cell = __webpack_require__(20);
module.exports = Grid;
module.exports.Row = Row;
module.exports.Cell = Cell;
/***/ },
/* 1 */
/***/ function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_1__;
/***/ },
/* 2 */
/***/ function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_2__;
/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {
var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!
Copyright (c) 2015 Jed Watson.
Licensed under the MIT License (MIT), see
http://jedwatson.github.io/classnames
*/
function classNames() {
var classes = '';
var arg;
for (var i = 0; i < arguments.length; i++) {
arg = arguments[i];
if (!arg) {
continue;
}
if ('string' === typeof arg || 'number' === typeof arg) {
classes += ' ' + arg;
} else if (Object.prototype.toString.call(arg) === '[object Array]') {
classes += ' ' + classNames.apply(null, arg);
} else if ('object' === typeof arg) {
for (var key in arg) {
if (!arg.hasOwnProperty(key) || !arg[key]) {
continue;
}
classes += ' ' + key;
}
}
}
return classes.substr(1);
}
// safely export classNames for node / browserify
if (typeof module !== 'undefined' && module.exports) {
module.exports = classNames;
}
// safely export classNames for RequireJS
if (true) {
!(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = function() {
return classNames;
}.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
}
/***/ },
/* 4 */
/***/ function(module, exports, __webpack_require__) {
var freeGlobal = __webpack_require__(28);
/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
/** Used as a reference to the global object. */
var root = freeGlobal || freeSelf || Function('return this')();
module.exports = root;
/***/ },
/* 5 */
/***/ function(module, exports) {
'use strict';
module.exports = {
getColumn: function getColumn(columns, idx) {
if (Array.isArray(columns)) {
return columns[idx];
} else if (typeof Immutable !== 'undefined') {
return columns.get(idx);
}
},
spliceColumn: function spliceColumn(metrics, idx, column) {
if (Array.isArray(metrics.columns)) {
metrics.columns.splice(idx, 1, column);
} else if (typeof Immutable !== 'undefined') {
metrics.columns = metrics.columns.splice(idx, 1, column);
}
return metrics;
},
getSize: function getSize(columns) {
if (Array.isArray(columns)) {
return columns.length;
} else if (typeof Immutable !== 'undefined') {
return columns.size;
}
},
// Logic extented to allow for functions to be passed down in column.editable
// this allows us to deicde whether we can be edting from a cell level
canEdit: function canEdit(col, rowData, enableCellSelect) {
if (col.editable != null && typeof col.editable === 'function') {
return enableCellSelect === true && col.editable(rowData);
}
return enableCellSelect === true && (!!col.editor || !!col.editable);
}
};
/***/ },
/* 6 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var React = __webpack_require__(1);
var ExcelColumnShape = {
name: React.PropTypes.node.isRequired,
key: React.PropTypes.string.isRequired,
width: React.PropTypes.number.isRequired,
filterable: React.PropTypes.bool
};
module.exports = ExcelColumnShape;
/***/ },
/* 7 */
/***/ function(module, exports, __webpack_require__) {
var baseIsNative = __webpack_require__(79),
getValue = __webpack_require__(88);
/**
* Gets the native function at `key` of `object`.
*
* @private
* @param {Object} object The object to query.
* @param {string} key The key of the method to get.
* @returns {*} Returns the function if it's native, else `undefined`.
*/
function getNative(object, key) {
var value = getValue(object, key);
return baseIsNative(value) ? value : undefined;
}
module.exports = getNative;
/***/ },
/* 8 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var PropTypes = __webpack_require__(1).PropTypes;
module.exports = {
selected: PropTypes.object.isRequired,
copied: PropTypes.object,
dragged: PropTypes.object,
onCellClick: PropTypes.func.isRequired,
onCellDoubleClick: PropTypes.func.isRequired,
onCommit: PropTypes.func.isRequired,
onCommitCancel: PropTypes.func.isRequired,
handleDragEnterRow: PropTypes.func.isRequired,
handleTerminateDrag: PropTypes.func.isRequired
};
/***/ },
/* 9 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var React = __webpack_require__(1);
var shallowCloneObject = __webpack_require__(16);
var contextTypes = {
metricsComputator: React.PropTypes.object
};
var MetricsComputatorMixin = {
childContextTypes: contextTypes,
getChildContext: function getChildContext() {
return { metricsComputator: this };
},
getMetricImpl: function getMetricImpl(name) {
return this._DOMMetrics.metrics[name].value;
},
registerMetricsImpl: function registerMetricsImpl(component, metrics) {
var getters = {};
var s = this._DOMMetrics;
for (var name in metrics) {
if (s.metrics[name] !== undefined) {
throw new Error('DOM metric ' + name + ' is already defined');
}
s.metrics[name] = { component: component, computator: metrics[name].bind(component) };
getters[name] = this.getMetricImpl.bind(null, name);
}
if (s.components.indexOf(component) === -1) {
s.components.push(component);
}
return getters;
},
unregisterMetricsFor: function unregisterMetricsFor(component) {
var s = this._DOMMetrics;
var idx = s.components.indexOf(component);
if (idx > -1) {
s.components.splice(idx, 1);
var name = void 0;
var metricsToDelete = {};
for (name in s.metrics) {
if (s.metrics[name].component === component) {
metricsToDelete[name] = true;
}
}
for (name in metricsToDelete) {
if (metricsToDelete.hasOwnProperty(name)) {
delete s.metrics[name];
}
}
}
},
updateMetrics: function updateMetrics() {
var s = this._DOMMetrics;
var needUpdate = false;
for (var name in s.metrics) {
if (!s.metrics.hasOwnProperty(name)) continue;
var newMetric = s.metrics[name].computator();
if (newMetric !== s.metrics[name].value) {
needUpdate = true;
}
s.metrics[name].value = newMetric;
}
if (needUpdate) {
for (var i = 0, len = s.components.length; i < len; i++) {
if (s.components[i].metricsUpdated) {
s.components[i].metricsUpdated();
}
}
}
},
componentWillMount: function componentWillMount() {
this._DOMMetrics = {
metrics: {},
components: []
};
},
componentDidMount: function componentDidMount() {
if (window.addEventListener) {
window.addEventListener('resize', this.updateMetrics);
} else {
window.attachEvent('resize', this.updateMetrics);
}
this.updateMetrics();
},
componentWillUnmount: function componentWillUnmount() {
window.removeEventListener('resize', this.updateMetrics);
}
};
var MetricsMixin = {
contextTypes: contextTypes,
componentWillMount: function componentWillMount() {
if (this.DOMMetrics) {
this._DOMMetricsDefs = shallowCloneObject(this.DOMMetrics);
this.DOMMetrics = {};
for (var name in this._DOMMetricsDefs) {
if (!this._DOMMetricsDefs.hasOwnProperty(name)) continue;
this.DOMMetrics[name] = function () {};
}
}
},
componentDidMount: function componentDidMount() {
if (this.DOMMetrics) {
this.DOMMetrics = this.registerMetrics(this._DOMMetricsDefs);
}
},
componentWillUnmount: function componentWillUnmount() {
if (!this.registerMetricsImpl) {
return this.context.metricsComputator.unregisterMetricsFor(this);
}
if (this.hasOwnProperty('DOMMetrics')) {
delete this.DOMMetrics;
}
},
registerMetrics: function registerMetrics(metrics) {
if (this.registerMetricsImpl) {
return this.registerMetricsImpl(this, metrics);
}
return this.context.metricsComputator.registerMetricsImpl(this, metrics);
},
getMetric: function getMetric(name) {
if (this.getMetricImpl) {
return this.getMetricImpl(name);
}
return this.context.metricsComputator.getMetricImpl(name);
}
};
module.exports = {
MetricsComputatorMixin: MetricsComputatorMixin,
MetricsMixin: MetricsMixin
};
/***/ },
/* 10 */
/***/ function(module, exports, __webpack_require__) {
var listCacheClear = __webpack_require__(98),
listCacheDelete = __webpack_require__(99),
listCacheGet = __webpack_require__(100),
listCacheHas = __webpack_require__(101),
listCacheSet = __webpack_require__(102);
/**
* Creates an list cache object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function ListCache(entries) {
var index = -1,
length = entries ? entries.length : 0;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
// Add methods to `ListCache`.
ListCache.prototype.clear = listCacheClear;
ListCache.prototype['delete'] = listCacheDelete;
ListCache.prototype.get = listCacheGet;
ListCache.prototype.has = listCacheHas;
ListCache.prototype.set = listCacheSet;
module.exports = ListCache;
/***/ },
/* 11 */
/***/ function(module, exports, __webpack_require__) {
var eq = __webpack_require__(31);
/**
* Gets the index at which the `key` is found in `array` of key-value pairs.
*
* @private
* @param {Array} array The array to inspect.
* @param {*} key The key to search for.
* @returns {number} Returns the index of the matched value, else `-1`.
*/
function assocIndexOf(array, key) {
var length = array.length;
while (length--) {
if (eq(array[length][0], key)) {
return length;
}
}
return -1;
}
module.exports = assocIndexOf;
/***/ },
/* 12 */
/***/ function(module, exports, __webpack_require__) {
var isKeyable = __webpack_require__(95);
/**
* Gets the data for `map`.
*
* @private
* @param {Object} map The map to query.
* @param {string} key The reference key.
* @returns {*} Returns the map data.
*/
function getMapData(map, key) {
var data = map.__data__;
return isKeyable(key)
? data[typeof key == 'string' ? 'string' : 'hash']
: data.map;
}
module.exports = getMapData;
/***/ },
/* 13 */
/***/ function(module, exports, __webpack_require__) {
var getNative = __webpack_require__(7);
/* Built-in method references that are verified to be native. */
var nativeCreate = getNative(Object, 'create');
module.exports = nativeCreate;
/***/ },
/* 14 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
var shallowCloneObject = __webpack_require__(16);
var sameColumn = __webpack_require__(39);
var ColumnUtils = __webpack_require__(5);
var getScrollbarSize = __webpack_require__(24);
function setColumnWidths(columns, totalWidth) {
return columns.map(function (column) {
var colInfo = Object.assign({}, column);
if (column.width) {
if (/^([0-9]+)%$/.exec(column.width.toString())) {
colInfo.width = Math.floor(column.width / 100 * totalWidth);
}
}
return colInfo;
});
}
function setDefferedColumnWidths(columns, unallocatedWidth, minColumnWidth) {
var defferedColumns = columns.filter(function (c) {
return !c.width;
});
return columns.map(function (column) {
if (!column.width) {
if (unallocatedWidth <= 0) {
column.width = minColumnWidth;
} else {
column.width = Math.floor(unallocatedWidth / ColumnUtils.getSize(defferedColumns));
}
}
return column;
});
}
function setColumnOffsets(columns) {
var left = 0;
return columns.map(function (column) {
column.left = left;
left += column.width;
return column;
});
}
/**
* Update column metrics calculation.
*
* @param {ColumnMetricsType} metrics
*/
function recalculate(metrics) {
// compute width for columns which specify width
var columns = setColumnWidths(metrics.columns, metrics.totalWidth);
var unallocatedWidth = columns.filter(function (c) {
return c.width;
}).reduce(function (w, column) {
return w - column.width;
}, metrics.totalWidth);
unallocatedWidth -= getScrollbarSize();
var width = columns.filter(function (c) {
return c.width;
}).reduce(function (w, column) {
return w + column.width;
}, 0);
// compute width for columns which doesn't specify width
columns = setDefferedColumnWidths(columns, unallocatedWidth, metrics.minColumnWidth);
// compute left offset
columns = setColumnOffsets(columns);
return {
columns: columns,
width: width,
totalWidth: metrics.totalWidth,
minColumnWidth: metrics.minColumnWidth
};
}
/**
* Update column metrics calculation by resizing a column.
*
* @param {ColumnMetricsType} metrics
* @param {Column} column
* @param {number} width
*/
function resizeColumn(metrics, index, width) {
var column = ColumnUtils.getColumn(metrics.columns, index);
var metricsClone = shallowCloneObject(metrics);
metricsClone.columns = metrics.columns.slice(0);
var updatedColumn = shallowCloneObject(column);
updatedColumn.width = Math.max(width, metricsClone.minColumnWidth);
metricsClone = ColumnUtils.spliceColumn(metricsClone, index, updatedColumn);
return recalculate(metricsClone);
}
function areColumnsImmutable(prevColumns, nextColumns) {
return typeof Immutable !== 'undefined' && prevColumns instanceof Immutable.List && nextColumns instanceof Immutable.List;
}
function compareEachColumn(prevColumns, nextColumns, isSameColumn) {
var i = void 0;
var len = void 0;
var column = void 0;
var prevColumnsByKey = {};
var nextColumnsByKey = {};
if (ColumnUtils.getSize(prevColumns) !== ColumnUtils.getSize(nextColumns)) {
return false;
}
for (i = 0, len = ColumnUtils.getSize(prevColumns); i < len; i++) {
column = prevColumns[i];
prevColumnsByKey[column.key] = column;
}
for (i = 0, len = ColumnUtils.getSize(nextColumns); i < len; i++) {
column = nextColumns[i];
nextColumnsByKey[column.key] = column;
var prevColumn = prevColumnsByKey[column.key];
if (prevColumn === undefined || !isSameColumn(prevColumn, column)) {
return false;
}
}
for (i = 0, len = ColumnUtils.getSize(prevColumns); i < len; i++) {
column = prevColumns[i];
var nextColumn = nextColumnsByKey[column.key];
if (nextColumn === undefined) {
return false;
}
}
return true;
}
function sameColumns(prevColumns, nextColumns, isSameColumn) {
if (areColumnsImmutable(prevColumns, nextColumns)) {
return prevColumns === nextColumns;
}
return compareEachColumn(prevColumns, nextColumns, isSameColumn);
}
module.exports = { recalculate: recalculate, resizeColumn: resizeColumn, sameColumn: sameColumn, sameColumns: sameColumns };
/***/ },
/* 15 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
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 React = __webpack_require__(1);
var joinClasses = __webpack_require__(3);
var Cell = __webpack_require__(20);
var ColumnMetrics = __webpack_require__(14);
var ColumnUtilsMixin = __webpack_require__(5);
var cellMetaDataShape = __webpack_require__(8);
var PropTypes = React.PropTypes;
var CellExpander = React.createClass({
displayName: 'CellExpander',
render: function render() {
return React.createElement(Cell, this.props);
}
});
var Row = React.createClass({
displayName: 'Row',
propTypes: {
height: PropTypes.number.isRequired,
columns: PropTypes.oneOfType([PropTypes.object, PropTypes.array]).isRequired,
row: PropTypes.any.isRequired,
cellRenderer: PropTypes.func,
cellMetaData: PropTypes.shape(cellMetaDataShape),
isSelected: PropTypes.bool,
idx: PropTypes.number.isRequired,
expandedRows: PropTypes.arrayOf(PropTypes.object),
extraClasses: PropTypes.string,
forceUpdate: PropTypes.bool,
subRowDetails: PropTypes.object,
isRowHovered: PropTypes.bool
},
mixins: [ColumnUtilsMixin],
getDefaultProps: function getDefaultProps() {
return {
cellRenderer: Cell,
isSelected: false,
height: 35
};
},
shouldComponentUpdate: function shouldComponentUpdate(nextProps) {
return !ColumnMetrics.sameColumns(this.props.columns, nextProps.columns, ColumnMetrics.sameColumn) || this.doesRowContainSelectedCell(this.props) || this.doesRowContainSelectedCell(nextProps) || this.willRowBeDraggedOver(nextProps) || nextProps.row !== this.props.row || this.hasRowBeenCopied() || this.props.isSelected !== nextProps.isSelected || nextProps.height !== this.props.height || this.props.forceUpdate === true;
},
handleDragEnter: function handleDragEnter() {
var handleDragEnterRow = this.props.cellMetaData.handleDragEnterRow;
if (handleDragEnterRow) {
handleDragEnterRow(this.props.idx);
}
},
getSelectedColumn: function getSelectedColumn() {
if (this.props.cellMetaData) {
var selected = this.props.cellMetaData.selected;
if (selected && selected.idx) {
return this.getColumn(this.props.columns, selected.idx);
}
}
},
getCellRenderer: function getCellRenderer(columnKey) {
var CellRenderer = this.props.cellRenderer;
if (this.props.subRowDetails && this.props.subRowDetails.field === columnKey) {
return CellExpander;
}
return CellRenderer;
},
getCells: function getCells() {
var _this = this;
var cells = [];
var lockedCells = [];
var selectedColumn = this.getSelectedColumn();
if (this.props.columns) {
this.props.columns.forEach(function (column, i) {
var CellRenderer = _this.props.cellRenderer;
var cell = React.createElement(CellRenderer, {
ref: i,
key: column.key + '-' + i,
idx: i,
rowIdx: _this.props.idx,
value: _this.getCellValue(column.key || i),
column: column,
height: _this.getRowHeight(),
formatter: column.formatter,
cellMetaData: _this.props.cellMetaData,
rowData: _this.props.row,
selectedColumn: selectedColumn,
isRowSelected: _this.props.isSelected,
expandableOptions: _this.getExpandableOptions(column.key) });
if (column.locked) {
lockedCells.push(cell);
} else {
cells.push(cell);
}
});
}
return cells.concat(lockedCells);
},
getRowHeight: function getRowHeight() {
var rows = this.props.expandedRows || null;
if (rows && this.props.idx) {
var row = rows[this.props.idx] || null;
if (row) {
return row.height;
}
}
return this.props.height;
},
getCellValue: function getCellValue(key) {
var val = void 0;
if (key === 'select-row') {
return this.props.isSelected;
} else if (typeof this.props.row.get === 'function') {
val = this.props.row.get(key);
} else {
val = this.props.row[key];
}
return val;
},
setScrollLeft: function setScrollLeft(scrollLeft) {
var _this2 = this;
this.props.columns.forEach(function (column, i) {
if (column.locked) {
if (!_this2.refs[i]) return;
_this2.refs[i].setScrollLeft(scrollLeft);
}
});
},
doesRowContainSelectedCell: function doesRowContainSelectedCell(props) {
var selected = props.cellMetaData.selected;
if (selected && selected.rowIdx === props.idx) {
return true;
}
return false;
},
isContextMenuDisplayed: function isContextMenuDisplayed() {
if (this.props.cellMetaData) {
var selected = this.props.cellMetaData.selected;
if (selected && selected.contextMenuDisplayed && selected.rowIdx === this.props.idx) {
return true;
}
}
return false;
},
willRowBeDraggedOver: function willRowBeDraggedOver(props) {
var dragged = props.cellMetaData.dragged;
return dragged != null && (dragged.rowIdx >= 0 || dragged.complete === true);
},
hasRowBeenCopied: function hasRowBeenCopied() {
var copied = this.props.cellMetaData.copied;
return copied != null && copied.rowIdx === this.props.idx;
},
getExpandableOptions: function getExpandableOptions(columnKey) {
return { canExpand: this.props.subRowDetails && this.props.subRowDetails.field === columnKey, expanded: this.props.subRowDetails && this.props.subRowDetails.expanded, children: this.props.subRowDetails && this.props.subRowDetails.children, treeDepth: this.props.subRowDetails ? this.props.subRowDetails.treeDepth : 0 };
},
renderCell: function renderCell(props) {
if (typeof this.props.cellRenderer === 'function') {
this.props.cellRenderer.call(this, props);
}
if (React.isValidElement(this.props.cellRenderer)) {
return React.cloneElement(this.props.cellRenderer, props);
}
return this.props.cellRenderer(props);
},
render: function render() {
var className = joinClasses('react-grid-Row', 'react-grid-Row--' + (this.props.idx % 2 === 0 ? 'even' : 'odd'), {
'row-selected': this.props.isSelected,
'row-context-menu': this.isContextMenuDisplayed()
}, this.props.extraClasses);
var style = {
height: this.getRowHeight(this.props),
overflow: 'hidden'
};
var cells = this.getCells();
return React.createElement(
'div',
_extends({}, this.props, { className: className, style: style, onDragEnter: this.handleDragEnter }),
React.isValidElement(this.props.row) ? this.props.row : cells
);
}
});
module.exports = Row;
/***/ },
/* 16 */
/***/ function(module, exports) {
"use strict";
function shallowCloneObject(obj) {
var result = {};
for (var k in obj) {
if (obj.hasOwnProperty(k)) {
result[k] = obj[k];
}
}
return result;
}
module.exports = shallowCloneObject;
/***/ },
/* 17 */
/***/ function(module, exports, __webpack_require__) {
var getNative = __webpack_require__(7),
root = __webpack_require__(4);
/* Built-in method references that are verified to be native. */
var Map = getNative(root, 'Map');
module.exports = Map;
/***/ },
/* 18 */
/***/ function(module, exports) {
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/
function isObject(value) {
var type = typeof value;
return !!value && (type == 'object' || type == 'function');
}
module.exports = isObject;
/***/ },
/* 19 */
/***/ function(module, exports) {
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return !!value && typeof value == 'object';
}
module.exports = isObjectLike;
/***/ },
/* 20 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
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 _isEqual = __webpack_require__(122);
var _isEqual2 = _interopRequireDefault(_isEqual);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var React = __webpack_require__(1);
var ReactDOM = __webpack_require__(2);
var joinClasses = __webpack_require__(3);
var EditorContainer = __webpack_require__(60);
var ExcelColumn = __webpack_require__(6);
var isFunction = __webpack_require__(23);
var CellMetaDataShape = __webpack_require__(8);
var SimpleCellFormatter = __webpack_require__(62);
var ColumnUtils = __webpack_require__(5);
var Cell = React.createClass({
displayName: 'Cell',
propTypes: {
rowIdx: React.PropTypes.number.isRequired,
idx: React.PropTypes.number.isRequired,
selected: React.PropTypes.shape({
idx: React.PropTypes.number.isRequired
}),
selectedColumn: React.PropTypes.object,
height: React.PropTypes.number,
tabIndex: React.PropTypes.number,
ref: React.PropTypes.string,
column: React.PropTypes.shape(ExcelColumn).isRequired,
value: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.number, React.PropTypes.object, React.PropTypes.bool]).isRequired,
isExpanded: React.PropTypes.bool,
isRowSelected: React.PropTypes.bool,
cellMetaData: React.PropTypes.shape(CellMetaDataShape).isRequired,
handleDragStart: React.PropTypes.func,
className: React.PropTypes.string,
cellControls: React.PropTypes.any,
rowData: React.PropTypes.object.isRequired,
forceUpdate: React.PropTypes.bool,
expandableOptions: React.PropTypes.object.isRequired
},
getDefaultProps: function getDefaultProps() {
return {
tabIndex: -1,
ref: 'cell',
isExpanded: false
};
},
getInitialState: function getInitialState() {
return {
isCellValueChanging: false
};
},
componentDidMount: function componentDidMount() {
this.checkFocus();
},
componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
this.setState({
isCellValueChanging: this.props.value !== nextProps.value
});
},
componentDidUpdate: function componentDidUpdate() {
this.checkFocus();
var dragged = this.props.cellMetaData.dragged;
if (dragged && dragged.complete === true) {
this.props.cellMetaData.handleTerminateDrag();
}
if (this.state.isCellValueChanging && this.props.selectedColumn != null) {
this.applyUpdateClass();
}
},
shouldComponentUpdate: function shouldComponentUpdate(nextProps) {
return this.props.column.width !== nextProps.column.width || this.props.column.left !== nextProps.column.left || this.props.height !== nextProps.height || this.props.rowIdx !== nextProps.rowIdx || this.isCellSelectionChanging(nextProps) || this.isDraggedCellChanging(nextProps) || this.isCopyCellChanging(nextProps) || this.props.isRowSelected !== nextProps.isRowSelected || this.isSelected() || this.props.value !== nextProps.value || this.props.forceUpdate === true || this.props.className !== nextProps.className || this.hasChangedDependentValues(nextProps);
},
onCellClick: function onCellClick(e) {
var meta = this.props.cellMetaData;
if (meta != null && meta.onCellClick && typeof meta.onCellClick === 'function') {
meta.onCellClick({ rowIdx: this.props.rowIdx, idx: this.props.idx }, e);
}
},
onCellContextMenu: function onCellContextMenu() {
var meta = this.props.cellMetaData;
if (meta != null && meta.onCellContextMenu && typeof meta.onCellContextMenu === 'function') {
meta.onCellContextMenu({ rowIdx: this.props.rowIdx, idx: this.props.idx });
}
},
onCellDoubleClick: function onCellDoubleClick(e) {
var meta = this.props.cellMetaData;
if (meta != null && meta.onCellDoubleClick && typeof meta.onCellDoubleClick === 'function') {
meta.onCellDoubleClick({ rowIdx: this.props.rowIdx, idx: this.props.idx }, e);
}
},
onCellExpand: function onCellExpand(e) {
e.stopPropagation();
var meta = this.props.cellMetaData;
if (meta != null && meta.onCellExpand != null) {
meta.onCellExpand({ rowIdx: this.props.rowIdx, idx: this.props.idx, rowData: this.props.rowData, expandArgs: this.props.expandableOptions });
}
},
onCellKeyDown: function onCellKeyDown(e) {
if (this.canExpand() && e.key === 'Enter') {
this.onCellExpand(e);
}
},
onDragHandleDoubleClick: function onDragHandleDoubleClick(e) {
e.stopPropagation();
var meta = this.props.cellMetaData;
if (meta != null && meta.onDragHandleDoubleClick && typeof meta.onDragHandleDoubleClick === 'function') {
meta.onDragHandleDoubleClick({ rowIdx: this.props.rowIdx, idx: this.props.idx, rowData: this.getRowData(), e: e });
}
},
onDragOver: function onDragOver(e) {
e.preventDefault();
},
getStyle: function getStyle() {
var style = {
position: 'absolute',
width: this.props.column.width,
height: this.props.height,
left: this.props.column.left
};
return style;
},
getFormatter: function getFormatter() {
var col = this.props.column;
if (this.isActive()) {
return React.createElement(EditorContainer, { rowData: this.getRowData(), rowIdx: this.props.rowIdx, idx: this.props.idx, cellMetaData: this.props.cellMetaData, column: col, height: this.props.height });
}
return this.props.column.formatter;
},
getRowData: function getRowData() {
var props = arguments.length <= 0 || arguments[0] === undefined ? this.props : arguments[0];
return props.rowData.toJSON ? props.rowData.toJSON() : props.rowData;
},
getFormatterDependencies: function getFormatterDependencies() {
// convention based method to get corresponding Id or Name of any Name or Id property
if (typeof this.props.column.getRowMetaData === 'function') {
return this.props.column.getRowMetaData(this.getRowData(), this.props.column);
}
},
getCellClass: function getCellClass() {
var className = joinClasses(this.props.column.cellClass, 'react-grid-Cell', this.props.className, this.props.column.locked ? 'react-grid-Cell--locked' : null);
var extraClasses = joinClasses({
'row-selected': this.props.isRowSelected,
selected: this.isSelected() && !this.isActive() && this.isCellSelectEnabled(),
editing: this.isActive(),
copied: this.isCopied() || this.wasDraggedOver() || this.isDraggedOverUpwards() || this.isDraggedOverDownwards(),
'active-drag-cell': this.isSelected() || this.isDraggedOver(),
'is-dragged-over-up': this.isDraggedOverUpwards(),
'is-dragged-over-down': this.isDraggedOverDownwards(),
'was-dragged-over': this.wasDraggedOver()
});
return joinClasses(className, extraClasses);
},
getUpdateCellClass: function getUpdateCellClass() {
return this.props.column.getUpdateCellClass ? this.props.column.getUpdateCellClass(this.props.selectedColumn, this.props.column, this.state.isCellValueChanging) : '';
},
isColumnSelected: function isColumnSelected() {
var meta = this.props.cellMetaData;
if (meta == null) {
return false;
}
return meta.selected && meta.selected.idx === this.props.idx;
},
isSelected: function isSelected() {
var meta = this.props.cellMetaData;
if (meta == null) {
return false;
}
return meta.selected && meta.selected.rowIdx === this.props.rowIdx && meta.selected.idx === this.props.idx;
},
isActive: function isActive() {
var meta = this.props.cellMetaData;
if (meta == null) {
return false;
}
return this.isSelected() && meta.selected.active === true;
},
isCellSelectionChanging: function isCellSelectionChanging(nextProps) {
var meta = this.props.cellMetaData;
if (meta == null) {
return false;
}
var nextSelected = nextProps.cellMetaData.selected;
if (meta.selected && nextSelected) {
return this.props.idx === nextSelected.idx || this.props.idx === meta.selected.idx;
}
return true;
},
isCellSelectEnabled: function isCellSelectEnabled() {
var meta = this.props.cellMetaData;
if (meta == null) {
return false;
}
return meta.enableCellSelect;
},
hasChangedDependentValues: function hasChangedDependentValues(nextProps) {
var currentColumn = this.props.column;
var hasChangedDependentValues = false;
if (currentColumn.getRowMetaData) {
var currentRowMetaData = currentColumn.getRowMetaData(this.getRowData(), currentColumn);
var nextColumn = nextProps.column;
var nextRowMetaData = nextColumn.getRowMetaData(this.getRowData(nextProps), nextColumn);
hasChangedDependentValues = !(0, _isEqual2['default'])(currentRowMetaData, nextRowMetaData);
}
return hasChangedDependentValues;
},
applyUpdateClass: function applyUpdateClass() {
var updateCellClass = this.getUpdateCellClass();
// -> removing the class
if (updateCellClass != null && updateCellClass !== '') {
var cellDOMNode = ReactDOM.findDOMNode(this);
if (cellDOMNode.classList) {
cellDOMNode.classList.remove(updateCellClass);
// -> and re-adding the class
cellDOMNode.classList.add(updateCellClass);
} else if (cellDOMNode.className.indexOf(updateCellClass) === -1) {
// IE9 doesn't support classList, nor (I think) altering element.className
// without replacing it wholesale.
cellDOMNode.className = cellDOMNode.className + ' ' + updateCellClass;
}
}
},
setScrollLeft: function setScrollLeft(scrollLeft) {
var ctrl = this; // flow on windows has an outdated react declaration, once that gets updated, we can remove this
if (ctrl.isMounted()) {
var node = ReactDOM.findDOMNode(this);
var transform = 'translate3d(' + scrollLeft + 'px, 0px, 0px)';
node.style.webkitTransform = transform;
node.style.transform = transform;
}
},
isCopied: function isCopied() {
var copied = this.props.cellMetaData.copied;
return copied && copied.rowIdx === this.props.rowIdx && copied.idx === this.props.idx;
},
isDraggedOver: function isDraggedOver() {
var dragged = this.props.cellMetaData.dragged;
return dragged && dragged.overRowIdx === this.props.rowIdx && dragged.idx === this.props.idx;
},
wasDraggedOver: function wasDraggedOver() {
var dragged = this.props.cellMetaData.dragged;
return dragged && (dragged.overRowIdx < this.props.rowIdx && this.props.rowIdx < dragged.rowIdx || dragged.overRowIdx > this.props.rowIdx && this.props.rowIdx > dragged.rowIdx) && dragged.idx === this.props.idx;
},
isDraggedCellChanging: function isDraggedCellChanging(nextProps) {
var isChanging = void 0;
var dragged = this.props.cellMetaData.dragged;
var nextDragged = nextProps.cellMetaData.dragged;
if (dragged) {
isChanging = nextDragged && this.props.idx === nextDragged.idx || dragged && this.props.idx === dragged.idx;
return isChanging;
}
return false;
},
isCopyCellChanging: function isCopyCellChanging(nextProps) {
var isChanging = void 0;
var copied = this.props.cellMetaData.copied;
var nextCopied = nextProps.cellMetaData.copied;
if (copied) {
isChanging = nextCopied && this.props.idx === nextCopied.idx || copied && this.props.idx === copied.idx;
return isChanging;
}
return false;
},
isDraggedOverUpwards: function isDraggedOverUpwards() {
var dragged = this.props.cellMetaData.dragged;
return !this.isSelected() && this.isDraggedOver() && this.props.rowIdx < dragged.rowIdx;
},
isDraggedOverDownwards: function isDraggedOverDownwards() {
var dragged = this.props.cellMetaData.dragged;
return !this.isSelected() && this.isDraggedOver() && this.props.rowIdx > dragged.rowIdx;
},
checkFocus: function checkFocus() {
if (this.isSelected() && !this.isActive()) {
// determine the parent viewport element of this cell
var parentViewport = ReactDOM.findDOMNode(this);
while (parentViewport != null && parentViewport.className.indexOf('react-grid-Viewport') === -1) {
parentViewport = parentViewport.parentElement;
}
var focusInGrid = false;
// if the focus is on the body of the document, the user won't mind if we focus them on a cell
if (document.activeElement == null || document.activeElement.nodeName && typeof document.activeElement.nodeName === 'string' && document.activeElement.nodeName.toLowerCase() === 'body') {
focusInGrid = true;
// otherwise
} else {
// only pull focus if the currently focused element is contained within the viewport
if (parentViewport) {
var focusedParent = document.activeElement;
while (focusedParent != null) {
if (focusedParent === parentViewport) {
focusInGrid = true;
break;
}
focusedParent = focusedParent.parentElement;
}
}
}
if (focusInGrid) {
ReactDOM.findDOMNode(this).focus();
}
}
},
canEdit: function canEdit() {
return this.props.column.editor != null || this.props.column.editable;
},
canExpand: function canExpand() {
return this.props.expandableOptions && this.props.expandableOptions.canExpand;
},
createColumEventCallBack: function createColumEventCallBack(onColumnEvent, info) {
return function (e) {
onColumnEvent(e, info);
};
},
createCellEventCallBack: function createCellEventCallBack(gridEvent, columnEvent) {
return function (e) {
gridEvent(e);
columnEvent(e);
};
},
createEventDTO: function createEventDTO(gridEvents, columnEvents, onColumnEvent) {
var allEvents = Object.assign({}, gridEvents);
for (var eventKey in columnEvents) {
if (columnEvents.hasOwnProperty(eventKey)) {
var event = columnEvents[event];
var eventInfo = { rowIdx: this.props.rowIdx, idx: this.props.idx, name: eventKey };
var eventCallback = this.createColumEventCallBack(onColumnEvent, eventInfo);
if (allEvents.hasOwnProperty(eventKey)) {
var currentEvent = allEvents[eventKey];
allEvents[eventKey] = this.createCellEventCallBack(currentEvent, eventCallback);
} else {
allEvents[eventKey] = eventCallback;
}
}
}
return allEvents;
},
getEvents: function getEvents() {
var columnEvents = this.props.column ? Object.assign({}, this.props.column.events) : undefined;
var onColumnEvent = this.props.cellMetaData ? this.props.cellMetaData.onColumnEvent : undefined;
var gridEvents = {
onClick: this.onCellClick,
onDoubleClick: this.onCellDoubleClick,
onContextMenu: this.onCellContextMenu,
onDragOver: this.onDragOver
};
if (!columnEvents || !onColumnEvent) {
return gridEvents;
}
return this.createEventDTO(gridEvents, columnEvents, onColumnEvent);
},
renderCellContent: function renderCellContent(props) {
var CellContent = void 0;
var Formatter = this.getFormatter();
if (React.isValidElement(Formatter)) {
props.dependentValues = this.getFormatterDependencies();
CellContent = React.cloneElement(Formatter, props);
} else if (isFunction(Formatter)) {
CellContent = React.createElement(Formatter, { value: this.props.value, dependentValues: this.getFormatterDependencies() });
} else {
CellContent = React.createElement(SimpleCellFormatter, { value: this.props.value });
}
var cellExpander = void 0;
var marginLeft = this.props.expandableOptions ? this.props.expandableOptions.treeDepth * 30 : 0;
if (this.canExpand()) {
cellExpander = React.createElement(
'span',
{ style: { float: 'left', marginLeft: marginLeft }, onClick: this.onCellExpand },
this.props.expandableOptions.expanded ? String.fromCharCode('9660') : String.fromCharCode('9658')
);
}
return React.createElement(
'div',
{ ref: 'cell',
className: 'react-grid-Cell__value' },
cellExpander,
React.createElement(
'span',
null,
CellContent
),
' ',
this.props.cellControls,
' '
);
},
render: function render() {
var style = this.getStyle();
var className = this.getCellClass();
var cellContent = this.renderCellContent({
value: this.props.value,
column: this.props.column,
rowIdx: this.props.rowIdx,
isExpanded: this.props.isExpanded
});
var dragHandle = !this.isActive() && ColumnUtils.canEdit(this.props.column, this.props.rowData, this.props.cellMetaData.enableCellSelect) ? React.createElement(
'div',
{ className: 'drag-handle', draggable: 'true', onDoubleClick: this.onDragHandleDoubleClick },
React.createElement('span', { style: { display: 'none' } })
) : null;
var events = this.getEvents();
return React.createElement(
'div',
_extends({}, this.props, { className: className, style: style }, events),
cellContent,
dragHandle
);
}
});
module.exports = Cell;
/***/ },
/* 21 */
/***/ function(module, exports) {
'use strict';
var KeyboardHandlerMixin = {
onKeyDown: function onKeyDown(e) {
if (this.isCtrlKeyHeldDown(e)) {
this.checkAndCall('onPressKeyWithCtrl', e);
} else if (this.isKeyExplicitlyHandled(e.key)) {
// break up individual keyPress events to have their own specific callbacks
// this allows multiple mixins to listen to onKeyDown events and somewhat reduces methodName clashing
var callBack = 'onPress' + e.key;
this.checkAndCall(callBack, e);
} else if (this.isKeyPrintable(e.keyCode)) {
this.checkAndCall('onPressChar', e);
}
// Track which keys are currently down for shift clicking etc
this._keysDown = this._keysDown || {};
this._keysDown[e.keyCode] = true;
if (this.props.onGridKeyDown && typeof this.props.onGridKeyDown === 'function') {
this.props.onGridKeyDown(e);
}
},
onKeyUp: function onKeyUp(e) {
// Track which keys are currently down for shift clicking etc
this._keysDown = this._keysDown || {};
delete this._keysDown[e.keyCode];
if (this.props.onGridKeyUp && typeof this.props.onGridKeyUp === 'function') {
this.props.onGridKeyUp(e);
}
},
isKeyDown: function isKeyDown(keyCode) {
if (!this._keysDown) return false;
return keyCode in this._keysDown;
},
isSingleKeyDown: function isSingleKeyDown(keyCode) {
if (!this._keysDown) return false;
return keyCode in this._keysDown && Object.keys(this._keysDown).length === 1;
},
// taken from http://stackoverflow.com/questions/12467240/determine-if-javascript-e-keycode-is-a-printable-non-control-character
isKeyPrintable: function isKeyPrintable(keycode) {
var valid = keycode > 47 && keycode < 58 || // number keys
keycode === 32 || keycode === 13 || // spacebar & return key(s) (if you want to allow carriage returns)
keycode > 64 && keycode < 91 || // letter keys
keycode > 95 && keycode < 112 || // numpad keys
keycode > 185 && keycode < 193 || // ;=,-./` (in order)
keycode > 218 && keycode < 223; // [\]' (in order)
return valid;
},
isKeyExplicitlyHandled: function isKeyExplicitlyHandled(key) {
return typeof this['onPress' + key] === 'function';
},
isCtrlKeyHeldDown: function isCtrlKeyHeldDown(e) {
return e.ctrlKey === true && e.key !== 'Control';
},
checkAndCall: function checkAndCall(methodName, args) {
if (typeof this[methodName] === 'function') {
this[methodName](args);
}
}
};
module.exports = KeyboardHandlerMixin;
/***/ },
/* 22 */
/***/ function(module, exports) {
'use strict';
var RowUtils = {
get: function get(row, property) {
if (typeof row.get === 'function') {
return row.get(property);
}
return row[property];
},
isRowSelected: function isRowSelected(keys, indexes, isSelectedKey, rowData, rowIdx) {
if (indexes && Object.prototype.toString.call(indexes) === '[object Array]') {
return indexes.indexOf(rowIdx) > -1;
} else if (keys && keys.rowKey && keys.values && Object.prototype.toString.call(keys.values) === '[object Array]') {
return keys.values.indexOf(rowData[keys.rowKey]) > -1;
} else if (isSelectedKey && rowData && typeof isSelectedKey === 'string') {
return rowData[isSelectedKey];
}
return false;
}
};
module.exports = RowUtils;
/***/ },
/* 23 */
/***/ function(module, exports) {
'use strict';
var isFunction = function isFunction(functionToCheck) {
var getType = {};
return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
};
module.exports = isFunction;
/***/ },
/* 24 */
/***/ function(module, exports) {
'use strict';
var size = void 0;
function getScrollbarSize() {
if (size === undefined) {
var outer = document.createElement('div');
outer.style.width = '50px';
outer.style.height = '50px';
outer.style.position = 'absolute';
outer.style.top = '-200px';
outer.style.left = '-200px';
var inner = document.createElement('div');
inner.style.height = '100px';
inner.style.width = '100%';
outer.appendChild(inner);
document.body.appendChild(outer);
var outerWidth = outer.clientWidth;
outer.style.overflowY = 'scroll';
var innerWidth = inner.clientWidth;
document.body.removeChild(outer);
size = outerWidth - innerWidth;
}
return size;
}
module.exports = getScrollbarSize;
/***/ },
/* 25 */
/***/ function(module, exports) {
/**
* Copyright 2013-2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule shallowEqual
* @typechecks
*
*/
'use strict';
var hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* Performs equality by iterating through keys on an object and returning false
* when any key has values which are not strictly equal between the arguments.
* Returns true when the va