es-grid-template
Version:
es-grid-template
280 lines (275 loc) • 8.86 kB
JavaScript
;
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
};
}