UNPKG

fixed-react-data-grid-custom

Version:

Excel-like grid component built with React, with editors, keyboard navigation, copy & paste, and the like

241 lines 13.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var react_1 = tslib_1.__importDefault(require("react")); var react_is_1 = require("react-is"); var Row_1 = tslib_1.__importDefault(require("./Row")); var RowsContainer_1 = tslib_1.__importDefault(require("./RowsContainer")); var RowGroup_1 = tslib_1.__importDefault(require("./RowGroup")); var masks_1 = require("./masks"); var rowUtils = tslib_1.__importStar(require("./RowUtils")); var canvasUtils_1 = require("./utils/canvasUtils"); var enums_1 = require("./common/enums"); var Canvas = /** @class */ (function (_super) { tslib_1.__extends(Canvas, _super); function Canvas() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.canvas = react_1.default.createRef(); _this.interactionMasks = react_1.default.createRef(); _this.rows = new Map(); _this._scroll = { scrollTop: 0, scrollLeft: 0 }; _this.handleScroll = function (e) { var _a = e.currentTarget, scrollLeft = _a.scrollLeft, scrollTop = _a.scrollTop; _this._scroll = { scrollTop: scrollTop, scrollLeft: scrollLeft }; if (_this.props.onScroll) { _this.props.onScroll(_this._scroll); } }; _this.onHitBottomCanvas = function () { var current = _this.canvas.current; if (current) { current.scrollTop += _this.props.rowHeight + _this.getClientScrollTopOffset(current); } }; _this.onHitTopCanvas = function () { var current = _this.canvas.current; if (current) { current.scrollTop -= _this.props.rowHeight - _this.getClientScrollTopOffset(current); } }; _this.handleHitColummBoundary = function (_a) { var idx = _a.idx; _this.scrollToColumn(idx); }; _this.scrollToColumn = function (idx) { var current = _this.canvas.current; if (!current) return; var scrollLeft = current.scrollLeft, clientWidth = current.clientWidth; var newScrollLeft = canvasUtils_1.getColumnScrollPosition(_this.props.columns, idx, scrollLeft, clientWidth); if (newScrollLeft !== 0) { current.scrollLeft = scrollLeft + newScrollLeft; } }; _this.getRowByRef = function (i) { // check if wrapped with React DND drop target if (!_this.rows.has(i)) return; var row = _this.rows.get(i); var wrappedRow = row.getDecoratedComponentInstance ? row.getDecoratedComponentInstance(i) : null; return wrappedRow ? wrappedRow.row : row; }; _this.getRowTop = function (rowIdx) { var row = _this.getRowByRef(rowIdx); if (row && row.getRowTop) { return row.getRowTop(); } return _this.props.rowHeight * rowIdx; }; _this.getRowHeight = function (rowIdx) { var row = _this.getRowByRef(rowIdx); if (row && row.getRowHeight) { return row.getRowHeight(); } return _this.props.rowHeight; }; _this.getRowColumns = function (rowIdx) { var row = _this.getRowByRef(rowIdx); return row && row.props ? row.props.columns : _this.props.columns; }; return _this; } Canvas.prototype.componentDidMount = function () { this.unsubscribeScrollToColumn = this.props.eventBus.subscribe(enums_1.EventTypes.SCROLL_TO_COLUMN, this.scrollToColumn); }; Canvas.prototype.componentWillUnmount = function () { this.unsubscribeScrollToColumn(); }; Canvas.prototype.componentDidUpdate = function (prevProps) { var scrollToRowIndex = this.props.scrollToRowIndex; if (scrollToRowIndex && prevProps.scrollToRowIndex !== scrollToRowIndex) { this.scrollToRow(scrollToRowIndex); } }; Canvas.prototype.scrollToRow = function (scrollToRowIndex) { var current = this.canvas.current; if (!current) return; var _a = this.props, rowHeight = _a.rowHeight, rowsCount = _a.rowsCount, height = _a.height; current.scrollTop = Math.min(scrollToRowIndex * rowHeight, rowsCount * rowHeight - height); }; Canvas.prototype.getRows = function (rowOverscanStartIdx, rowOverscanEndIdx) { var rows = []; var i = rowOverscanStartIdx; while (i < rowOverscanEndIdx) { var row = this.props.rowGetter(i); var subRowDetails = void 0; if (this.props.getSubRowDetails) { subRowDetails = this.props.getSubRowDetails(row); } rows.push({ row: row, subRowDetails: subRowDetails }); i++; } return rows; }; Canvas.prototype.getScroll = function () { var _a = this.canvas.current, scrollTop = _a.scrollTop, scrollLeft = _a.scrollLeft; return { scrollTop: scrollTop, scrollLeft: scrollLeft }; }; Canvas.prototype.getClientScrollTopOffset = function (node) { var rowHeight = this.props.rowHeight; var scrollVariation = node.scrollTop % rowHeight; return scrollVariation > 0 ? rowHeight - scrollVariation : 0; }; Canvas.prototype.isRowSelected = function (idx, row) { var _this = this; // Use selectedRows if set if (this.props.selectedRows) { var selectedRow = this.props.selectedRows.find(function (r) { var rowKeyValue = rowUtils.get(row, _this.props.rowKey); return r[_this.props.rowKey] === rowKeyValue; }); return !!(selectedRow && selectedRow.isSelected); } // Else use new rowSelection props if (this.props.rowSelection) { var _a = this.props.rowSelection, keys = _a.keys, indexes = _a.indexes, isSelectedKey = _a.isSelectedKey; return rowUtils.isRowSelected(keys, indexes, isSelectedKey, row, idx); } return false; }; Canvas.prototype.setScrollLeft = function (scrollLeft) { var _this = this; var current = this.interactionMasks.current; if (current) { current.setScrollLeft(scrollLeft); } this.rows.forEach(function (r, idx) { var row = _this.getRowByRef(idx); if (row && row.setScrollLeft) { row.setScrollLeft(scrollLeft); } }); }; Canvas.prototype.renderCustomRowRenderer = function (props) { var ref = props.ref, otherProps = tslib_1.__rest(props, ["ref"]); var CustomRowRenderer = this.props.rowRenderer; var customRowRendererProps = tslib_1.__assign(tslib_1.__assign({}, otherProps), { renderBaseRow: function (p) { return react_1.default.createElement(Row_1.default, tslib_1.__assign({ ref: ref }, p)); } }); if (react_is_1.isElement(CustomRowRenderer)) { if (CustomRowRenderer.type === Row_1.default) { // In the case where Row is specified as the custom render, ensure the correct ref is passed return react_1.default.createElement(Row_1.default, tslib_1.__assign({}, props)); } return react_1.default.cloneElement(CustomRowRenderer, customRowRendererProps); } return react_1.default.createElement(CustomRowRenderer, tslib_1.__assign({}, customRowRendererProps)); }; Canvas.prototype.renderGroupRow = function (props) { var ref = props.ref, columns = props.columns, rowGroupProps = tslib_1.__rest(props, ["ref", "columns"]); var row = props.row; return (react_1.default.createElement(RowGroup_1.default, tslib_1.__assign({}, rowGroupProps, row.__metaData, { columns: columns, name: row.name, eventBus: this.props.eventBus, renderer: this.props.rowGroupRenderer, renderBaseRow: function (p) { return react_1.default.createElement(Row_1.default, tslib_1.__assign({ ref: ref }, p)); } }))); }; Canvas.prototype.renderRow = function (props) { var row = props.row; if (row.__metaData && row.__metaData.getRowRenderer) { return row.__metaData.getRowRenderer(this.props, props.idx); } if (row.__metaData && row.__metaData.isGroup) { return this.renderGroupRow(props); } if (this.props.rowRenderer) { return this.renderCustomRowRenderer(props); } return react_1.default.createElement(Row_1.default, tslib_1.__assign({}, props)); }; Canvas.prototype.renderPlaceholder = function (key, height) { // just renders empty cells // if we wanted to show gridlines, we'd need classes and position as with renderScrollingPlaceholder return (react_1.default.createElement("div", { key: key, style: { height: height } }, this.props.columns.map(function (column) { return react_1.default.createElement("div", { style: { width: column.width }, key: column.key }); }))); }; Canvas.prototype.render = function () { var _this = this; var _a = this.props, rowOverscanStartIdx = _a.rowOverscanStartIdx, rowOverscanEndIdx = _a.rowOverscanEndIdx, cellMetaData = _a.cellMetaData, columns = _a.columns, colOverscanStartIdx = _a.colOverscanStartIdx, colOverscanEndIdx = _a.colOverscanEndIdx, colVisibleStartIdx = _a.colVisibleStartIdx, colVisibleEndIdx = _a.colVisibleEndIdx, lastFrozenColumnIndex = _a.lastFrozenColumnIndex, rowHeight = _a.rowHeight, rowsCount = _a.rowsCount, totalColumnWidth = _a.totalColumnWidth, totalWidth = _a.totalWidth, height = _a.height, rowGetter = _a.rowGetter, contextMenu = _a.contextMenu; var RowsContainer = this.props.RowsContainer || RowsContainer_1.default; var rows = this.getRows(rowOverscanStartIdx, rowOverscanEndIdx) .map(function (_a, idx) { var row = _a.row, subRowDetails = _a.subRowDetails; var rowIdx = rowOverscanStartIdx + idx; return row && _this.renderRow({ key: rowIdx, ref: function (row) { if (row) { _this.rows.set(rowIdx, row); } else { _this.rows.delete(rowIdx); } }, idx: rowIdx, rowVisibleStartIdx: _this.props.rowVisibleStartIdx, rowVisibleEndIdx: _this.props.rowVisibleEndIdx, row: row, height: rowHeight, columns: columns, isSelected: _this.isRowSelected(rowIdx, row), cellMetaData: cellMetaData, subRowDetails: subRowDetails, colVisibleStartIdx: colVisibleStartIdx, colVisibleEndIdx: colVisibleEndIdx, colOverscanStartIdx: colOverscanStartIdx, colOverscanEndIdx: colOverscanEndIdx, lastFrozenColumnIndex: lastFrozenColumnIndex, isScrolling: _this.props.isScrolling, scrollLeft: _this._scroll.scrollLeft }); }); if (rowOverscanStartIdx > 0) { rows.unshift(this.renderPlaceholder('top', rowOverscanStartIdx * rowHeight)); } if (rowsCount - rowOverscanEndIdx > 0) { rows.push(this.renderPlaceholder('bottom', (rowsCount - rowOverscanEndIdx) * rowHeight)); } return (react_1.default.createElement("div", { className: "react-grid-Canvas", style: { width: totalWidth, height: height }, ref: this.canvas, onScroll: this.handleScroll }, react_1.default.createElement(masks_1.InteractionMasks, tslib_1.__assign({ ref: this.interactionMasks, rowGetter: rowGetter, rowsCount: rowsCount, rowHeight: rowHeight, columns: columns, rowVisibleStartIdx: this.props.rowVisibleStartIdx, rowVisibleEndIdx: this.props.rowVisibleEndIdx, colVisibleStartIdx: colVisibleStartIdx, colVisibleEndIdx: colVisibleEndIdx, enableCellSelect: this.props.enableCellSelect, enableCellAutoFocus: this.props.enableCellAutoFocus, cellNavigationMode: this.props.cellNavigationMode, eventBus: this.props.eventBus, contextMenu: this.props.contextMenu, onHitBottomBoundary: this.onHitBottomCanvas, onHitTopBoundary: this.onHitTopCanvas, onHitLeftBoundary: this.handleHitColummBoundary, onHitRightBoundary: this.handleHitColummBoundary, scrollLeft: this._scroll.scrollLeft, scrollTop: this._scroll.scrollTop, getRowHeight: this.getRowHeight, getRowTop: this.getRowTop, getRowColumns: this.getRowColumns, editorPortalTarget: this.props.editorPortalTarget }, this.props.interactionMasksMetaData)), react_1.default.createElement(RowsContainer, { id: contextMenu ? contextMenu.props.id : 'rowsContainer' }, react_1.default.createElement("div", { style: { width: totalColumnWidth } }, rows)))); }; Canvas.displayName = 'Canvas'; return Canvas; }(react_1.default.PureComponent)); exports.default = Canvas; //# sourceMappingURL=Canvas.js.map