react-native-sortables
Version:
Powerful Sortable Components for Flexible Content Reordering in React Native
102 lines (95 loc) • 3.09 kB
JavaScript
;
import { resolveDimension } from '../../../../utils';
import { getCrossIndex, getMainIndex } from './helpers';
export const calculateLayout = ({
gaps,
indexToKey,
isVertical,
itemHeights,
itemWidths,
numGroups,
startCrossOffset
}) => {
'worklet';
const mainGroupSize = isVertical ? itemWidths : itemHeights;
if (!mainGroupSize) {
return null;
}
const crossAxisOffsets = [startCrossOffset ?? 0];
const itemPositions = {};
let mainCoordinate;
let crossCoordinate;
let crossItemSizes;
if (isVertical) {
// grid with specified number of columns (vertical orientation)
mainCoordinate = 'x';
crossCoordinate = 'y';
crossItemSizes = itemHeights;
} else {
// grid with specified number of rows (horizontal orientation)
mainCoordinate = 'y';
crossCoordinate = 'x';
crossItemSizes = itemWidths;
}
for (const [itemIndex, itemKey] of indexToKey.entries()) {
const crossItemSize = resolveDimension(crossItemSizes, itemKey);
// Return null if the item is not yet measured or the item main size
// is different than the main group size (main size must be always the same)
if (crossItemSize === null) {
return null;
}
const mainIndex = getMainIndex(itemIndex, numGroups);
const crossIndex = getCrossIndex(itemIndex, numGroups);
const crossAxisOffset = crossAxisOffsets[crossIndex] ?? 0;
// Update offset of the next group
crossAxisOffsets[crossIndex + 1] = Math.max(crossAxisOffsets[crossIndex + 1] ?? 0, crossAxisOffset + crossItemSize + gaps.cross);
// Update item position
itemPositions[itemKey] = {
[crossCoordinate]: crossAxisOffset,
[mainCoordinate]: mainIndex * (mainGroupSize + gaps.main)
};
}
let lastCrossOffset = crossAxisOffsets[crossAxisOffsets.length - 1];
lastCrossOffset = lastCrossOffset ? Math.max(lastCrossOffset - gaps.cross, 0) : 0;
const mainSize = (mainGroupSize + gaps.main) * numGroups - gaps.main;
return {
containerCrossSize: lastCrossOffset,
contentBounds: [{
[crossCoordinate]: startCrossOffset ?? 0,
[mainCoordinate]: 0
}, {
[crossCoordinate]: lastCrossOffset,
[mainCoordinate]: mainSize
}],
crossAxisOffsets,
itemPositions
};
};
export const calculateItemCrossOffset = ({
crossGap,
crossItemSizes,
indexToKey,
itemKey,
numGroups
}) => {
'worklet';
let activeItemCrossOffset = 0;
let currentGroupCrossSize = 0;
let currentGroupCrossIndex = 0;
// Find new active item position
for (let i = 0; i < indexToKey.length; i++) {
const crossIndex = getCrossIndex(i, numGroups);
if (crossIndex !== currentGroupCrossIndex) {
activeItemCrossOffset += currentGroupCrossSize + crossGap;
currentGroupCrossIndex = crossIndex;
currentGroupCrossSize = 0;
}
const key = indexToKey[i];
currentGroupCrossSize = Math.max(currentGroupCrossSize, resolveDimension(crossItemSizes, key) ?? 0);
if (key === itemKey) {
break;
}
}
return activeItemCrossOffset;
};
//# sourceMappingURL=layout.js.map