@chayns-components/core
Version:
A set of beautiful React components for developing your own applications with chayns.
110 lines • 2.59 kB
JavaScript
export const getMasonryItemKey = (item, index) => item.key != null ? String(item.key) : String(index);
const isAreaFree = ({
grid,
startColumn,
startRow,
columns,
rows,
columnCount
}) => {
if (startColumn + columns > columnCount) {
return false;
}
for (let row = startRow; row < startRow + rows; row += 1) {
for (let column = startColumn; column < startColumn + columns; column += 1) {
if (grid[row]?.[column]) {
return false;
}
}
}
return true;
};
const occupyArea = ({
grid,
startColumn,
startRow,
columns,
rows
}) => {
for (let row = startRow; row < startRow + rows; row += 1) {
if (!grid[row]) {
// eslint-disable-next-line no-param-reassign
grid[row] = [];
}
for (let column = startColumn; column < startColumn + columns; column += 1) {
// eslint-disable-next-line no-param-reassign
grid[row][column] = true;
}
}
};
export const packMasonryGrid = ({
items,
columnCount,
columnWidth,
rowHeight,
gap
}) => {
const grid = [];
const packedItems = {};
let maxRow = 0;
items.forEach(item => {
const columns = Math.min(Math.max(item.columns, 1), columnCount);
const rows = Math.max(item.rows, 1);
let placed = false;
let row = 0;
while (!placed) {
for (let column = 0; column < columnCount; column += 1) {
const canPlaceItem = isAreaFree({
grid,
startColumn: column,
startRow: row,
columns,
rows,
columnCount
});
if (!canPlaceItem) {
continue;
}
occupyArea({
grid,
startColumn: column,
startRow: row,
columns,
rows
});
packedItems[item.key] = {
key: item.key,
x: column * (columnWidth + gap),
y: row * (rowHeight + gap),
width: columns * columnWidth + (columns - 1) * gap
};
maxRow = Math.max(maxRow, row + rows);
placed = true;
break;
}
if (!placed) {
row += 1;
}
}
});
return {
items: packedItems,
height: maxRow * rowHeight + Math.max(0, maxRow - 1) * gap
};
};
export const calculateColumnCount = ({
containerWidth,
columnWidth,
gap
}) => {
if (!containerWidth) {
return 1;
}
return Math.max(1, Math.floor((containerWidth + gap) / (columnWidth + gap)));
};
export const calculateRowSpan = ({
height,
rowHeight,
gap
}) => Math.max(1, Math.ceil((height + gap) / (rowHeight + gap)));
//# sourceMappingURL=Masonry.utils.js.map