UNPKG

es-grid-template

Version:

es-grid-template

280 lines (275 loc) 8.86 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.calculateRenderInfo = calculateRenderInfo; var _utils = require("../utils"); var _utils2 = require("./utils"); function resolveVirtualEnabled(virtualEnum, defaultValue) { if (virtualEnum == null || virtualEnum === 'auto') { return !!defaultValue; } return virtualEnum; } let lockColumnNeedSpecifiedWidthWarned = false; function warnLockColumnNeedSpecifiedWidth(column) { if (!lockColumnNeedSpecifiedWidthWarned) { lockColumnNeedSpecifiedWidthWarned = true; console.warn('[ali-react-table] lock=true The column must have a specified width', column); } } let columnHiddenDeprecatedWarned = false; function warnColumnHiddenDeprecated(column) { if (!columnHiddenDeprecatedWarned) { columnHiddenDeprecatedWarned = true; console.warn('[ali-react-table] `column.hidden` is deprecated. If you need to hide this column, please remove it from the `columns` array.', column); } } /** * Validate column configuration, set default widths, * and remove hidden columns */ function processColumns(columns, defaultColumnWidth) { if (columns === null || !Array.isArray(columns)) { console.warn('[ali-react-table] `<BaseTable />` props.columns must be an array.', columns); // eslint-disable-next-line no-param-reassign columns = []; } // eslint-disable-next-line @typescript-eslint/no-shadow function dfs(columns) { const result = []; for (let column of columns) { if (column.width === null) { if (defaultColumnWidth !== null) { column = { ...column, width: defaultColumnWidth }; } else if (process.env.NODE_ENV !== 'production' && (0, _utils.isLeafNode)(column) && column.lock) { warnLockColumnNeedSpecifiedWidth(column); } } if ((0, _utils.isLeafNode)(column)) { if (column.hidden) { // Hidden columns will be removed here warnColumnHiddenDeprecated(column); } else { result.push(column); } } else { const nextChildren = dfs(column.children ?? []); // If `nextChildren` is empty, it means all child nodes have been hidden. // In this case, hide the parent node here as well. if (nextChildren.length > 0) { result.push({ ...column, children: nextChildren }); } } } return result; } return dfs(columns); } function getLeftNestedLockCount(columns) { let nestedCount = 0; for (const col of columns) { if (isLock(col)) { nestedCount += 1; } else { break; } } return nestedCount; function isLock(col) { if ((0, _utils.isLeafNode)(col)) { return col.lock ?? false; } else { return col.lock || (col.children ?? []).some(isLock); } } } function getHorizontalRenderRange({ offsetX, maxRenderWidth, flat, useVirtual }) { if (!useVirtual.horizontal) { return { leftIndex: 0, leftBlank: 0, rightIndex: flat.full.length, rightBlank: 0 }; } let leftIndex = 0; let centerCount = 0; let leftBlank = 0; let centerRenderWidth = 0; const overscannedOffsetX = Math.max(0, offsetX - _utils2.OVERSCAN_SIZE); while (leftIndex < flat.center.length) { const col = flat.center[leftIndex]; if (col.width != null && col.width + leftBlank < overscannedOffsetX) { leftIndex += 1; leftBlank += col.width; } else { break; } } // Considering overscan, the middle columns need to render at least this much width const minCenterRenderWidth = maxRenderWidth + (overscannedOffsetX - leftBlank) + 2 * _utils2.OVERSCAN_SIZE; while (leftIndex + centerCount < flat.center.length) { const col = flat.center[leftIndex + centerCount]; if (col.width ?? 0 + centerRenderWidth < minCenterRenderWidth) { centerRenderWidth += col.width ?? 0; centerCount += 1; } else { break; } } const rightBlankCount = flat.center.length - leftIndex - centerCount; const rightBlank = (0, _utils2.sum)(flat.center.slice(flat.center.length - rightBlankCount).map(col => col.width ?? 0)); return { leftIndex: leftIndex, leftBlank, rightIndex: leftIndex + centerCount, rightBlank }; } // Perform a series of calculations to derive all the data required // for this table render (the code is a bit messy and has significant room for optimization). // TODO: Consider moving the header computation logic into this file as well. // There is likely some duplicated calculation logic at the moment. function calculateRenderInfo(table) { const { offsetX, maxRenderWidth } = table.state; const { useVirtual: useVirtualProp, columns: columnsProp, dataSource: dataSourceProp, defaultColumnWidth } = table.props; const columns = processColumns(columnsProp, defaultColumnWidth); const leftNestedLockCount = getLeftNestedLockCount(columns); const fullFlat = (0, _utils.collectNodes)(columns, 'leaf-only'); let flat; let nested; let useVirtual; if (leftNestedLockCount === columns.length) { flat = { left: [], right: [], full: fullFlat, center: fullFlat }; nested = { left: [], right: [], full: columns, center: columns }; useVirtual = { horizontal: false, vertical: false, header: false }; } else { const leftNested = columns.slice(0, leftNestedLockCount); const rightNestedLockCount = getLeftNestedLockCount(columns.slice().reverse()); const centerNested = columns.slice(leftNestedLockCount, columns.length - rightNestedLockCount); const rightNested = columns.slice(columns.length - rightNestedLockCount); const shouldEnableHozVirtual = fullFlat.length >= _utils2.AUTO_VIRTUAL_THRESHOLD && fullFlat.every(col => col.width != null); const shouldEnableVerVirtual = dataSourceProp.length >= _utils2.AUTO_VIRTUAL_THRESHOLD; useVirtual = { horizontal: resolveVirtualEnabled(typeof useVirtualProp === 'object' ? useVirtualProp.horizontal : useVirtualProp, shouldEnableHozVirtual), vertical: resolveVirtualEnabled(typeof useVirtualProp === 'object' ? useVirtualProp.vertical : useVirtualProp, shouldEnableVerVirtual), header: resolveVirtualEnabled(typeof useVirtualProp === 'object' ? useVirtualProp.header : useVirtualProp, false) }; flat = { left: (0, _utils.collectNodes)(leftNested, 'leaf-only'), full: fullFlat, right: (0, _utils.collectNodes)(rightNested, 'leaf-only'), center: (0, _utils.collectNodes)(centerNested, 'leaf-only') }; nested = { left: leftNested, full: columns, right: rightNested, center: centerNested }; } const horizontalRenderRange = getHorizontalRenderRange({ maxRenderWidth, offsetX, useVirtual, flat }); const verticalRenderRange = table.getVerticalRenderRange(useVirtual); const { leftBlank, leftIndex, rightBlank, rightIndex } = horizontalRenderRange; // @ts-ignore const unfilteredVisibleColumnDescriptors = [...flat.left.map((col, i) => ({ type: 'normal', col, colIndex: i })), leftBlank > 0 && { type: 'blank', blankSide: 'left', width: leftBlank }, ...flat.center.slice(leftIndex, rightIndex).map((col, i) => ({ type: 'normal', col, colIndex: flat.left.length + leftIndex + i })), rightBlank > 0 && { type: 'blank', blankSide: 'right', width: rightBlank }, ...flat.right.map((col, i) => ({ type: 'normal', col, colIndex: flat.full.length - flat.right.length + i }))]; const visibleColumnDescriptors = unfilteredVisibleColumnDescriptors.filter(Boolean); const fullFlatCount = flat.full.length; const leftFlatCount = flat.left.length; const rightFlatCount = flat.right.length; const stickyLeftMap = new Map(); let stickyLeft = 0; for (let i = 0; i < leftFlatCount; i++) { stickyLeftMap.set(i, stickyLeft); // @ts-ignore stickyLeft += flat.full[i].width; } const stickyRightMap = new Map(); let stickyRight = 0; for (let i = 0; i < rightFlatCount; i++) { stickyRightMap.set(fullFlatCount - 1 - i, stickyRight); // @ts-ignore stickyRight += flat.full[fullFlatCount - 1 - i].width; } // @ts-ignore const leftLockTotalWidth = (0, _utils2.sum)(flat.left.map(col => col.width)); // @ts-ignore const rightLockTotalWidth = (0, _utils2.sum)(flat.right.map(col => col.width)); return { horizontalRenderRange, verticalRenderRange, visible: visibleColumnDescriptors, flat, nested, useVirtual, stickyLeftMap, stickyRightMap, leftLockTotalWidth, rightLockTotalWidth, hasLockColumn: nested.left.length > 0 || nested.right.length > 0 }; }