UNPKG

huge-table

Version:

Table component to handle huge sets of data, based on Facebook's FixedDataTable

749 lines (646 loc) 30.2 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.HugeTable = undefined; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; 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 _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _fixedDataTable = require('fixed-data-table-2'); var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames); var _constants = require('./constants'); var Constants = _interopRequireWildcard(_constants); var _CellUtils = require('./CellUtils'); var CellUtils = _interopRequireWildcard(_CellUtils); var _HeaderCell = require('./HeaderCell'); var _TextCell = require('./TextCell'); var _TouchWrapper = require('./TouchWrapper'); var _TouchWrapper2 = _interopRequireDefault(_TouchWrapper); var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _aphrodite = require('aphrodite'); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } 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; } 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; } var HugeTable = exports.HugeTable = function (_React$Component) { _inherits(HugeTable, _React$Component); function HugeTable(props) { _classCallCheck(this, HugeTable); var _this = _possibleConstructorReturn(this, (HugeTable.__proto__ || Object.getPrototypeOf(HugeTable)).call(this, props)); _initialiseProps.call(_this); var cellPadding = props.cellPadding || Constants.CELL_PADDING, lineHeight = props.lineHeight || Constants.LINE_HEIGHT, headerHeight = props.headerHeight || Constants.HEADER_HEIGHT, rowHeight = props.rowHeight || Constants.ROW_HEIGHT; _this.state = { columnWidths: {}, isColumnResizing: undefined, columnNameToDataTypeMap: {}, columnOrder: [], currentSchema: [], shouldActivateLeftScroll: false, shouldActivateRightScroll: false, scrollLeft: 0, cellPadding: cellPadding, lineHeight: lineHeight, headerHeight: headerHeight, rowHeight: rowHeight, contentHeight: 500, contentWidth: 500 }; _this.uniqueId = props.options.id || null; if (_this.uniqueId) { _this.savedColumnsWidth = JSON.parse(localStorage.getItem('huge-table-column-widths')) || {}; _this.savedColumnsWidth[_this.uniqueId] = _this.savedColumnsWidth[_this.uniqueId] || {}; } _this.maxTitleWidth = props.options.maxTitleWidth || Constants.MAX_TITLE_WIDTH; _this.maxContentWidth = props.options.maxContentWidth || Constants.MAX_CONTENT_WIDTH; _this.fontDetails = props.options.fontDetails || Constants.FONT_DETAILS; _this.minColumnWidth = props.options.minColumnWidth || Constants.MIN_COLUMN_WIDTH; _this.headerOffsetWidth = props.options.headerOffsetWidth || 0; return _this; } _createClass(HugeTable, [{ key: 'componentDidMount', value: function componentDidMount() { this.generateColumnToDataTypeMap(this.props.schema); this.generateColumnWidths(this.props.schema, this.props.options.width); this.generateInitialColumnOrder(this.props.schema); this.checkForScrollArrows(this.state.scrollLeft); } }, { key: 'componentWillReceiveProps', value: function componentWillReceiveProps(nextProps) { if (this.props.schema !== nextProps.schema) { this.generateColumnToDataTypeMap(nextProps.schema); this.generateInitialColumnOrder(nextProps.schema); } if (this.props.schema !== nextProps.schema || this.props.options.width !== nextProps.options.width) { this.generateColumnWidths(nextProps.schema, nextProps.options.width); this.checkForScrollArrows(this.state.scrollLeft); } if (this.props.data.length !== nextProps.data.length) { this.setContentHeight(nextProps.data); } } }, { key: 'componentDidUpdate', value: function componentDidUpdate(prevProps, prevState) { if (prevState.columnOrder !== this.state.columnOrder && !_lodash2.default.isEqual(prevState.columnOrder, this.state.columnOrder)) { this.reorderSchema(this.props.schema, this.state.columnOrder); } if (prevState.currentSchema !== this.state.currentSchema && !_lodash2.default.isEqual(prevState.currentSchema, this.state.currentSchema)) { this.onSchemaChange(this.state.currentSchema, prevState.currentSchema); this.checkForScrollArrows(this.state.scrollLeft); } if (prevState.currentSchema < this.state.currentSchema && this.state.shouldShowScrolls) { this.scrollNewColumnIntoView(); this.checkForScrollArrows(this.state.scrollLeft); } if (prevProps.activeColumnIndex !== this.props.activeColumnIndex && this.props.onActiveColumnChange) { this.props.onActiveColumnChange(); } } }, { key: 'scrollAndCheckForArrows', value: function scrollAndCheckForArrows(scrollLeft) { this.checkForScrollArrows(scrollLeft); this.handleScroll(scrollLeft); } }, { key: 'render', value: function render() { var _this2 = this; var tableWidth = this.props.options.width; var tableHeight = this.props.options.height - this.state.headerHeight; var rowNumberColumnWidth = this.props.options.rowNumberColumnWidth ? this.props.options.rowNumberColumnWidth : Constants.ROW_NUMBER_COLUMN_WIDTH; var leftScroll = void 0, rightScroll = void 0; if (this.state.shouldShowScrolls) { // increase the size of the row number column so there is no overlap leftScroll = _react2.default.createElement( 'section', { style: { height: this.state.headerHeight }, className: (0, _classnames2.default)('scroll-toggle', 'left', { 'active': this.state.shouldActivateLeftScroll }), onMouseEnter: function onMouseEnter() { return _this2.handleMouseEnter(-10); }, onMouseLeave: function onMouseLeave() { return _this2.stopScrollInterval(); } }, _react2.default.createElement('i', { className: 'fa fa-chevron-left fa-lg' }) ); rightScroll = _react2.default.createElement( 'section', { style: { height: this.state.headerHeight }, className: (0, _classnames2.default)('scroll-toggle', 'right', { 'active': this.state.shouldActivateRightScroll }), onMouseEnter: function onMouseEnter() { return _this2.handleMouseEnter(10); }, onMouseLeave: function onMouseLeave() { return _this2.stopScrollInterval(); } }, _react2.default.createElement('i', { className: 'fa fa-chevron-right fa-lg' }) ); } return _react2.default.createElement( _TouchWrapper2.default, { onScroll: this.onScroll, tableWidth: tableWidth, tableHeight: tableHeight, contentWidth: this.state.contentWidth, contentHeight: this.state.contentHeight }, _react2.default.createElement( 'div', { style: { position: 'relative', height: tableHeight, width: tableWidth } }, leftScroll, rightScroll, _react2.default.createElement( _fixedDataTable.Table, { onHorizontalScroll: this.checkForScrollArrows, onScrollEnd: this.onScrollEnd, ref: 'table', rowHeight: this.state.rowHeight, rowsCount: this.props.data.length, width: tableWidth, scrollLeft: this.state.scrollLeft, scrollTop: this.state.scrollTop, height: tableHeight, headerHeight: this.state.headerHeight, isColumnResizing: this.state.isColumnResizing, onColumnResizeEndCallback: this.onColumnResizeEndCallback, onContentDimensionsChange: this.onContentDimensionsChange, onColumnReorderEndCallback: this.onColumnReorderEndCallback, scrollToColumn: this.props.scrollToColumn, isColumnReordering: false }, function () { if (!_this2.props.hideRowNumbers) { return _react2.default.createElement(_fixedDataTable.Column, { cellClassName: 'hugetable-index-column', key: 'hugetable-index-column', columnKey: 'hugetable-index-column', width: rowNumberColumnWidth, header: function header(props) { return _this2.renderHeader(_extends({}, props, { cellData: { main: '#' } })); }, cell: function cell(props) { return _react2.default.createElement( _fixedDataTable.Cell, null, _react2.default.createElement(_TextCell.TextCell, _extends({}, props, { cellData: { main: props.rowIndex + 1 } })) ); } }); } }(), this.state.currentSchema.map(this.createColumn), function () { if (_this2.state.shouldShowScrolls) { return _react2.default.createElement(_fixedDataTable.Column, { cellClassName: 'huge-table-right-scroll-column', key: 'huge-table-right-scroll-column', columnKey: 'huge-table-right-scroll-column', width: _this2.props.buttonColumnWidth ? 40 + _this2.props.buttonColumnWidth : 40, header: function header(props) { return _this2.renderHeader(_extends({}, props, { cellData: { main: '' } })); }, cell: function cell(props) { return _react2.default.createElement( _fixedDataTable.Cell, null, _react2.default.createElement(_TextCell.TextCell, _extends({}, props, { cellData: { main: '' } })) ); } }); } }() ) ) ); } }]); return HugeTable; }(_react2.default.Component); HugeTable.propTypes = { data: _propTypes2.default.arrayOf(_propTypes2.default.object), options: _propTypes2.default.shape({ height: _propTypes2.default.number, width: _propTypes2.default.number, mixedContentImage: _propTypes2.default.func, tableScrolled: _propTypes2.default.func, id: _propTypes2.default.string, maxTitleWidth: _propTypes2.default.number, maxContentWidth: _propTypes2.default.number, minColumnWidth: _propTypes2.default.number, rowNumberColumnWidth: _propTypes2.default.number, fontDetails: _propTypes2.default.string, headerOffsetWidth: _propTypes2.default.number, hideHeader: _propTypes2.default.bool }), schema: _propTypes2.default.arrayOf(_propTypes2.default.shape({ name: _propTypes2.default.string, type: _propTypes2.default.string })), renderers: _propTypes2.default.shape(_constants.RETURNED_DATA_TYPES.reduce(function (initial, next) { return _extends({}, initial, _defineProperty({}, next, _propTypes2.default.func)); }, { HEADER: _propTypes2.default.func })), onSchemaChange: _propTypes2.default.func, resizeByContent: _propTypes2.default.bool, hideRowNumbers: _propTypes2.default.bool, showScrollingArrows: _propTypes2.default.bool, scrollToNewColumn: _propTypes2.default.bool, onScrollToNewColumn: _propTypes2.default.func, rowHeight: _propTypes2.default.number, headerHeight: _propTypes2.default.number, cellPadding: _propTypes2.default.shape({ top: _propTypes2.default.number, bottom: _propTypes2.default.number, left: _propTypes2.default.number, right: _propTypes2.default.number }), lineHeight: _propTypes2.default.number, buttonColumnWidth: _propTypes2.default.number, activeColumnIndex: _propTypes2.default.number, onActiveColumnChange: _propTypes2.default.func, scrollToColumn: _propTypes2.default.number, disableClickEvents: _propTypes2.default.bool, resizeableColumns: _propTypes2.default.bool, reorderableColumns: _propTypes2.default.bool }; HugeTable.defaultProps = { resizeableColumns: true, reorderableColumns: true }; var _initialiseProps = function _initialiseProps() { var _this3 = this; this.onScrollEnd = function (scrollLeft) { _this3.setState({ scrollLeft: scrollLeft }); }; this.onSchemaChange = function (schema, prevSchema) { if (_this3.props.onSchemaChange) { _this3.props.onSchemaChange(schema, prevSchema); } }; this.scrollNewColumnIntoView = function () { if (_this3.refs.table && _this3.props.scrollToNewColumn) { _this3.scrollAndCheckForArrows(_this3.refs.table.state.maxScrollX); if (_this3.props.onScrollToNewColumn) { _this3.props.onScrollToNewColumn(); } } }; this.reorderSchema = function (schema, columnOrder) { var newSchema = []; columnOrder.forEach(function (col) { var newSchemaItem = schema.find(function (s) { return (s.id || s.name) === col; }); if (newSchemaItem) { newSchema.push(newSchemaItem); } }); _this3.setState({ currentSchema: newSchema }); }; this.setContentHeight = function (data) { _this3.setState({ contentHeight: _this3.state.rowHeight * data.length + _this3.state.headerHeight }); }; this.generateInitialColumnOrder = function (schema) { var columnOrder = schema.map(function (schemaItem) { return schemaItem.id || schemaItem.name; }); _this3.setState({ columnOrder: columnOrder }); _this3.reorderSchema(schema, columnOrder); }; this.generateColumnToDataTypeMap = function (schema) { var columnNameToDataTypeMap = {}; schema.forEach(function (schemaItem) { columnNameToDataTypeMap[schemaItem.name] = schemaItem.type; }); _this3.setState({ columnNameToDataTypeMap: columnNameToDataTypeMap }); }; this.generateColumnWidths = function (schema, width, columnKey, newColumnWidth) { var columnWidths = {}; var isColumnResizing = void 0; var contentWidth = void 0; // Table width - rowNumberColumn (width + border) - columns border / columnsCount var calculatedWidth = (width - Constants.ROW_NUMBER_COLUMN_WIDTH - 5 - schema.length * 2) / Math.max(schema.length, 1); var defaultColumnWidth = Math.max(calculatedWidth, _this3.minColumnWidth); schema.forEach(function (schemaItem) { var maxColumnWidth = _this3.props.resizeByContent ? _this3.getMaxColumnWidth(schemaItem, _this3.minColumnWidth) : defaultColumnWidth; if (_this3.uniqueId) { //Reference the content width over the width set in state if we have data and we are passed the resizeByContent prop if (_this3.props.data.length > 0 && _this3.props.resizeByContent) { _this3.state.columnWidths[schemaItem.id || schemaItem.name] = _this3.savedColumnsWidth[_this3.uniqueId][schemaItem.id || schemaItem.name] || maxColumnWidth || _this3.state.columnWidths[schemaItem.id || schemaItem.name] || defaultColumnWidth; } else { _this3.state.columnWidths[schemaItem.id || schemaItem.name] = _this3.savedColumnsWidth[_this3.uniqueId][schemaItem.id || schemaItem.name] || _this3.state.columnWidths[schemaItem.id || schemaItem.name] || maxColumnWidth || defaultColumnWidth; } } else { _this3.state.columnWidths[schemaItem.id || schemaItem.name] = _this3.state.columnWidths[schemaItem.id || schemaItem.name] || maxColumnWidth || defaultColumnWidth; } columnWidths[schemaItem.id || schemaItem.name] = _this3.state.columnWidths[schemaItem.id || schemaItem.name]; }); if (columnKey) { columnWidths[columnKey] = newColumnWidth; if (_this3.uniqueId) { _this3.savedColumnsWidth[_this3.uniqueId][columnKey] = newColumnWidth; localStorage.setItem('huge-table-column-widths', JSON.stringify(_this3.savedColumnsWidth)); } isColumnResizing = false; } contentWidth = schema.reduce(function (sum, item) { return sum + columnWidths[item.id || item.name]; }, 0) + Constants.ROW_NUMBER_COLUMN_WIDTH; _this3.setState({ columnWidths: columnWidths, isColumnResizing: isColumnResizing, contentWidth: contentWidth }); }; this.getMaxColumnWidth = function (schemaItem, defaultColumnWidth) { var maxColumnWidth = 0; //Calculate the column width unless the content is an image if (schemaItem.type !== Constants.ColumnTypes.IMAGE) { _this3.props.data.forEach(function (row) { var cellContent = _this3.getCellContent(row, schemaItem); var cellText = _this3.getCellText(cellContent); var cellColumnWidth = _this3.getContentSize(cellText, _this3.fontDetails); maxColumnWidth = maxColumnWidth > cellColumnWidth ? maxColumnWidth : cellColumnWidth; }); //If the content width is less than the max title width //Set the column width based off of max title width //Else set column width based off of content width if (maxColumnWidth < _this3.maxTitleWidth) { var titleWidth = _this3.getContentSize(schemaItem.name, _this3.fontDetails) + _this3.headerOffsetWidth; maxColumnWidth = Math.max(titleWidth, maxColumnWidth); maxColumnWidth = Math.min(maxColumnWidth, _this3.maxTitleWidth); } else { maxColumnWidth = Math.min(_this3.maxContentWidth, maxColumnWidth); } } return maxColumnWidth > defaultColumnWidth ? maxColumnWidth : defaultColumnWidth; }; this.getContentSize = function (txt, font) { _this3.element = document.createElement('canvas'); _this3.context = _this3.element.getContext('2d'); _this3.context.font = font; var tsize = { 'width': _this3.context.measureText(txt).width }; return tsize.width; }; this.setMaxHeaderWidth = function (field) { var maxColumnWidth = _this3.getContentSize(field.name, _this3.fontDetails) + _this3.headerOffsetWidth; maxColumnWidth = maxColumnWidth > _this3.minColumnWidth ? maxColumnWidth : _this3.minColumnWidth; if (_this3.uniqueId) { _this3.savedColumnsWidth[_this3.uniqueId][field.id] = maxColumnWidth; localStorage.setItem('huge-table-column-widths', JSON.stringify(_this3.savedColumnsWidth)); } return maxColumnWidth; }; this.resizeHeader = function (field) { var columnWidths = _extends({}, _this3.state.columnWidths); columnWidths[field.id] = _this3.setMaxHeaderWidth(field); _this3.setState({ columnWidths: columnWidths }); }; this.resizeAllHeaders = function (fields) { var columnWidths = _extends({}, _this3.state.columnWidths); fields.forEach(function (field) { columnWidths[field.id] = _this3.setMaxHeaderWidth(field); }); _this3.setState({ columnWidths: columnWidths }); }; this.getCellContent = function (row, schemaItem) { var content = void 0; if (schemaItem.type === Constants.ColumnTypes.TEXT) { var cellData = Array.isArray(row[schemaItem.name]) ? row[schemaItem.name][0] : row[schemaItem.name]; if (cellData !== undefined) { content = cellData.text !== undefined ? cellData.text : ''; } else { content = ''; } } else if (schemaItem.type === Constants.ColumnTypes.IMAGE) { content = ''; } else { content = row[schemaItem.name + '/_text'] !== undefined ? row[schemaItem.name + '/_text'] : row[schemaItem.name]; } return content; }; this.getCellText = function (cellContent) { if (Array.isArray(cellContent)) { return _this3.getCellText(cellContent[0]); } else if ((typeof cellContent === 'undefined' ? 'undefined' : _typeof(cellContent)) === 'object') { return JSON.stringify(cellContent); } else { return cellContent; } }; this.createColumn = function (schemaItem, idx) { var width = _this3.state.columnWidths[schemaItem.id || schemaItem.name]; var lastColumn = idx === _this3.state.currentSchema.length - 1 && _this3.state.currentSchema.length > 1; if (_this3.state.shouldShowScrolls && lastColumn) { // this adds some extra room to accomodate the scrolling arrows width = width + 120; } var cellClass = '', headerClass = ''; if (_this3.props.showScrollingArrows && _this3.state.shouldShowScrolls) { if (_this3.props.hideRowNumbers && idx === 0) { cellClass = 'hugetable-index-column nudge'; } else if (lastColumn) { cellClass = 'last-column'; } } if (idx === _this3.props.activeColumnIndex) { cellClass = cellClass + ' active-column'; headerClass = 'active-column-header'; } // if we are hiding the row numbers but showing scrolling arrows, need to nudge this column with padding //Add styling for redactPII var piiClass = ''; if (schemaItem.redactPII) { piiClass = 'hide-pii'; } return _react2.default.createElement(_fixedDataTable.Column, { cellClassName: cellClass + ' huge-table-column-' + idx + ' ' + piiClass, headerClassName: headerClass, header: function header(props) { return _this3.renderHeader(_extends({}, props, { cellData: { main: schemaItem.name } })); }, columnKey: schemaItem.id || schemaItem.name, minWidth: _this3.minColumnWidth, width: width, cell: function cell(props) { return _this3.cellRenderer(_extends({}, props, { schemaItem: schemaItem })); }, key: schemaItem.name, isResizable: _this3.props.resizeableColumns, isReorderable: _this3.props.reorderableColumns }); }; this.renderHeader = function (props) { if (!_this3.props.options.hideHeader) { if (_this3.props.renderers && _this3.props.renderers.HEADER && typeof _this3.props.renderers.HEADER === 'function') { return _react2.default.createElement( _fixedDataTable.Cell, null, _this3.props.renderers.HEADER(props) ); } else { return _react2.default.createElement(_HeaderCell.HeaderCell, props); } } }; this.getCellStyles = function (columnDataType) { var cellStyles = {}; if (columnDataType == Constants.ColumnTypes.IMAGE) { cellStyles = _aphrodite.StyleSheet.create({ cellStyle: { paddingTop: Constants.IMAGE_CELL_PADDING.cellPaddingTop, paddingBottom: Constants.IMAGE_CELL_PADDING.cellPaddingBottom, paddingLeft: Constants.IMAGE_CELL_PADDING.cellPaddingLeft, paddingRight: Constants.IMAGE_CELL_PADDING.cellPaddingRight } }); } else { cellStyles = _aphrodite.StyleSheet.create({ cellStyle: { paddingTop: Constants.CELL_PADDING.cellPaddingTop, paddingBottom: Constants.CELL_PADDING.cellPaddingBottom, paddingLeft: Constants.CELL_PADDING.cellPaddingLeft, paddingRight: Constants.CELL_PADDING.cellPaddingRight } }); } return cellStyles; }; this.cellRenderer = function (_ref) { var rowIndex = _ref.rowIndex, width = _ref.width, height = _ref.height, schemaItem = _ref.schemaItem; var rowObject = _this3.props.data[rowIndex]; var cellData = {}; cellData.main = rowObject[schemaItem.name]; Constants.RETURNED_DATA_TYPES.forEach(function (dataType) { cellData[dataType] = rowObject[schemaItem.name + '/_' + dataType] || null; }); var columnDataType = _this3.state.columnNameToDataTypeMap[schemaItem.name]; var cellCustomRenderer = _this3.props.renderers && _this3.props.renderers[columnDataType]; cellData.type = columnDataType; return _react2.default.createElement( _fixedDataTable.Cell, { className: (0, _aphrodite.css)(_this3.getCellStyles(columnDataType).cellStyle) }, CellUtils.getComponentDataType({ disableClickEvents: _this3.props.disableClickEvents, columnDataType: columnDataType, cellData: cellData, width: width, height: height, columnKey: schemaItem.id || schemaItem.name, mixedContentImage: _this3.props.options.mixedContentImage, cellCustomRenderer: cellCustomRenderer, rowIndex: rowIndex }) ); }; this.onColumnResizeEndCallback = function (newColumnWidth, columnKey) { _this3.generateColumnWidths(_this3.props.schema, _this3.props.options.width, columnKey, newColumnWidth); }; this.onScroll = function (scrollLeft, scrollTop) { _this3.setState({ scrollLeft: scrollLeft ? scrollLeft : _this3.state.scrollLeft, scrollTop: scrollTop }); if (_this3.props.options.tableScrolled) { _this3.props.options.tableScrolled(scrollLeft, scrollTop); } }; this.onContentDimensionsChange = function (contentHeight, contentWidth) { _this3.setState({ contentWidth: contentWidth, contentHeight: contentHeight }); }; this.onColumnReorderEndCallback = function (event) { var columnOrder = _this3.state.columnOrder.filter(function (columnKey) { return columnKey !== event.reorderColumn; }); if (event.columnAfter) { var index = columnOrder.indexOf(event.columnAfter); columnOrder.splice(index, 0, event.reorderColumn); } else if (!event.columnAfter && event.columnBefore) { columnOrder.push(event.reorderColumn); } else { // in the case of the drag-and-drop event being aborted columnOrder = _this3.state.columnOrder; } _this3.setState({ columnOrder: columnOrder }); }; this.handleMouseEnter = function (scrollVal) { _this3.intervalId = setInterval(function () { return _this3.moveScrollPos(scrollVal); }, 10); }; this.stopScrollInterval = function () { clearInterval(_this3.intervalId); _this3.intervalId = undefined; }; this.moveScrollPos = function (val) { if (_this3.state.scrollLeft === 0 && val >= 0 || _this3.state.scrollLeft > 0) { var scrollLeft = _this3.state.scrollLeft + val >= 0 ? _this3.state.scrollLeft + val : 0; _this3.scrollAndCheckForArrows(scrollLeft); } if (_this3.state.scrollLeft >= _this3.refs.table.state.maxScrollX) { _this3.stopScrollInterval(); } }; this.calcElementsWidth = function (elementsArr) { return elementsArr.map(function (e) { return e.getBoundingClientRect().width; }).reduce(function (i, n) { return i + n; }, 0); }; this.getChildElements = function () { var headerContainer = _this3.getHeaderContainer(); var childElements = headerContainer ? Array.from(_this3.getHeaderContainer().children) : []; return childElements; }; this.handleScroll = function (scrollLeft) { _this3.setState({ scrollLeft: scrollLeft }); return true; }; this.checkForScrollArrows = function (scrollLeft, allElementsWidth) { var ALL_ELEMENTS_WIDTH = allElementsWidth ? allElementsWidth : _this3.calcElementsWidth(_this3.getChildElements()); var shouldShowScrolls = ALL_ELEMENTS_WIDTH > _this3.props.options.width && _this3.props.showScrollingArrows; _this3.setState({ shouldShowScrolls: shouldShowScrolls, shouldActivateLeftScroll: scrollLeft > 0, shouldActivateRightScroll: ALL_ELEMENTS_WIDTH - 1 > _this3.props.options.width + scrollLeft }); return true; }; this.getListContainerWidth = function () { return _this3.getHeaderContainer().getBoundingClientRect().width; }; this.getHeaderContainer = function () { var headerCell = document.querySelector('.hugetable-index-column'); return headerCell ? headerCell.parentElement : null; }; };