Sticky rows/columns not working properly with rowspan/colspan
Describe the bug Sticky rows and columns are not functioning correctly when sticky cells use rowspan or colspan.
Current behavior
-
If a sticky row has a rowspan, it is not sticking properly.
-
If a sticky column has a colspan, the sticky behavior is also not working as expected.
Your environment details
- Device: desktop
- OS: Windows 11
- Browser: Edge
- ReactGrid Version: v5-latest
@jvloo Can you share your cells implementation? Note that spanned cells defined in a certain pane shouldn't exceed it.
@jvloo Can you share your cells implementation? Note that spanned cells defined in a certain pane shouldn't exceed it.
Sure, I have simplified the code for your review.
Below is for the spanned rows:
const defaultRowColumns: Column[][] = useMemo(() => {
const rowCols_1: Column[] = [
{
colIndex: 0,
name: '',
rowSpan: 2,
minWidth: 0,
width: 30,
},
{
colIndex: 1,
name: 'ID',
rowSpan: 2,
minWidth: 0,
width: 70,
},
{
colIndex: 2,
name: '',
rowSpan: 2,
minWidth: 0,
width: 210,
},
{
colIndex: 3,
name: 'Escalation',
rowSpan: 2,
minWidth: 0,
width: 110,
},
{
colIndex: 4,
name: 'Frequency',
rowSpan: 2,
minWidth: 0,
width: 110,
},
{
colIndex: 5,
name: 'Start',
rowSpan: 2,
minWidth: 0,
width: 70,
},
{
colIndex: 6,
name: 'End',
rowSpan: 2,
minWidth: 0,
width: 70,
},
{
colIndex: 7,
name: 'Contract Value',
rowSpan: 2,
minWidth: 0,
width: 100,
},
{
colIndex: 8,
name: 'Amount per Freq.',
rowSpan: 2,
minWidth: 0,
width: 100,
},
{
colIndex: 9,
key: 'actualToDate',
name: 'To Date & To Go',
minWidth: 0,
width: 110
},
{
colIndex: 10,
key: 'forecastToGo',
name: '',
minWidth: 0,
width: 110
},
{
colIndex: 11,
name: 'Total Amount',
rowSpan: 2,
minWidth: 0,
width: 90,
}
);
// Set second row columns
const rowCols_2: Column[] = rowCols_1.map((col) => {
let name = '';
switch (col.key) {
case 'actualToDate':
name = 'Actual To Date';
break;
case 'forecastToGo':
name = 'Forecast To Go';
break;
}
return {
...col,
name,
rowSpan: 1,
};
});
return [rowCols_1, rowCols_2];
}, []);
const dateColumns = useMemo(() => {
const columns: Column[] = [];
const startDate = new Date();
for (let i = 0; i < 20; i++) {
const currentDate = addMonths(startDate, i); // addMonths from date-fns
columns.push({
colIndex: i,
name: currentDate,
minWidth: 0,
width: 80,
});
}
return columns;
}, []);
const allRowColumns = useMemo<Column[][]>(() => {
const rowColumns = cloneDeep(defaultRowColumns);
const dateCols = dateColumns.map((column, idx) => ({
...column,
colIndex: defaultRowColumns[0].length + idx,
rowSpan: 2,
}));
rowColumns.map((cols) => cols.push(...dateCols));
return rowColumns;
}, [defaultRowColumns, dateColumns]);
const stickyTopRows = 2;
@jvloo Can you share your cells implementation? Note that spanned cells defined in a certain pane shouldn't exceed it.
For the spanned columns:
const defaulColumns: Column[][] = useMemo(() => {
const rowCols_1: Column[] = [
{ name: '', colIndex: 0, minWidth: 25, width: 50 },
{ name: 'Child2', colIndex: 1, colSpan: 2, minWidth: 50, width: 90 },
{ name: 'Child1', colIndex: 3, colSpan: 2, minWidth: 50, width: 90 },
{ name: 'Parent', colIndex: 5, colSpan: 2, minWidth: 50, width: 90 },
{ name: 'Total', colIndex: 7, rowSpan: 2, minWidth: 50, width: 72 },
];
const rowCols_2: Column[] = [
{ name: '', colIndex: 0, minWidth: 25, width: 50 },
{ name: 'ID', colIndex: 1, minWidth: 50, width: 90 },
{ name: 'Description', colIndex: 2, minWidth: 50, width: 200 },
{ name: 'ID', colIndex: 3, minWidth: 50, width: 90 },
{ name: 'Description', colIndex: 4, minWidth: 50, width: 200 },
{ name: 'ID', colIndex: 5, minWidth: 50, width: 90 },
{ name: 'Description', colIndex: 6, minWidth: 50, width: 200 },
{ name: '', colIndex: 7, minWidth: 50, width: 72 },
];
return [rowCols_1, rowCols_2];
}, []);
const dateColumns = useMemo(() => {
const columns: Column[] = [];
const startDate = new Date();
for (let i = 0; i < 20; i++) {
const currentDate = addMonths(startDate, i); // addMonths from date-fns
columns.push({
colIndex: i,
name: currentDate,
minWidth: 0,
width: 80,
});
}
return columns;
}, []);
const allRowColumns = useMemo<Column[][]>(() => {
const rowColumns = cloneDeep(defaultRowColumns);
const dateCols = dateColumns.map((column, idx) => ({
...column,
colIndex: defaultRowColumns[0].length + idx,
rowSpan: 2,
}));
rowColumns.map((cols) => cols.push(...dateCols));
return rowColumns;
}, [defaultRowColumns, dateColumns]);
const stickyLeftColumns = 8;
I don’t see how the cells passed directly to the ReactGrid component are defined. However, based on the provided code, I suspect that each cell receives colSpan and rowSpan in the columns and rows specified by stickyLeftColumns and stickyTopRows. This could result in some cells being overlapped.
I suggest reviewing the cells array you’ve defined to ensure there are no position conflicts. For example, here’s an incorrect cell implementation where a cell with colSpan: 2overlaps another cell: [{ colIndex: 0, rowIndex: 0, colSpan: 2 }, { colIndex: 1, rowIndex: 0 }].