i have virtualized list, in which i display elements in absolute position. And i want to display sticky headers (optionally) at left/top/right/bottom. It works almost correct but during scrolling there is delay between elements in headers and in table.
<div
ref={scrollRef}
style={{
width,
height,
overflow: "auto",
position: "relative",
scrollBehavior: "smooth",
willChange: "transform",
}}
onScroll={(e) => handleScroll(e)}
>
<StickyHeaders
headers={headers}
rowHeights={rowHeights}
columnWidths={columnWidths}
visibleRows={elementVisibilityRows.visible}
visibleColumns={elementVisibilityCols.visible}
height={height}
width={width}
scrollLeft={scrollLeft}
scrollTop={scrollTop}
scrollbarSize={scrollbarSize}
/>
<div style={contentStyle}>
{AbsoluteElementComponent ? (
<AbsoluteElementComponent
currentLeftOffset={scrollLeft}
currentTopOffset={scrollTop}
getElementLeftOffset={(index: number) => {
const offset =
typeof columnWidths === "number"
? columnWidths * index
: elementVisibilityCols.sizesOffsetOfIndice[index];
return offset;
}}
getElementTopOffset={(index: number) => {
const offset =
typeof rowHeights === "number"
? rowHeights * index
: elementVisibilityRows.sizesOffsetOfIndice[index];
return offset;
}}
offsetVersion={offsetVersion}
/>
) : null}
{WrapperComponent ? (
<WrapperComponent>
<VirtualizedTableContent
rowsOffsets={elementVisibilityRows.sizesOffsetOfIndice}
columnsOffsets={elementVisibilityCols.sizesOffsetOfIndice}
rowHeights={rowHeights}
columnWidths={columnWidths}
visibleRows={elementVisibilityRows.visible}
visibleColumns={elementVisibilityCols.visible}
CellComponent={CellComponent}
additionalData={additionalData}
offsetVersion={offsetVersion}
/>
</WrapperComponent>
) : (
<VirtualizedTableContent
rowHeights={rowHeights}
rowsOffsets={elementVisibilityRows.sizesOffsetOfIndice}
columnWidths={columnWidths}
columnsOffsets={elementVisibilityCols.sizesOffsetOfIndice}
visibleRows={elementVisibilityRows.visible}
visibleColumns={elementVisibilityCols.visible}
CellComponent={CellComponent}
additionalData={additionalData}
offsetVersion={offsetVersion}
/>
)}
</div>
</div>
Sticky Headers Component.
<div
style={{
position: "sticky",
top: 0,
left: 0,
zIndex: 10,
background: "white",
display: "flex",
flexDirection: "row",
animation: "500ms ease-in-out 0s normal none 1 running fadeInDown"
}}
>
<div style={{ position: "relative", height: "100%", width: "100%" }}>
{headers.top ? (
<TopHeaderSection
header={headers.top}
columnWidths={columnWidths}
visibleColumns={visibleColumns}
scrollLeft={scrollLeft}
leftOffset={headers.left?.size ?? 0}
headers={headers}
rowHeights={rowHeights}
/>
) : null}
etc
</div>
</div>
Top Header
<div
style={{
position: "absolute",
top: 0,
zIndex: 10,
background: "white",
display: "flex",
flexDirection: "row",
left: 0,
}}
>
<div style={{ position: "relative", marginLeft: headers.left?.size }}>
{Array.from(
{
length:
visibleColumns.lastVisible - visibleColumns.firstVisible + 1,
},
(_, colIdx) => {
const columnIndex = visibleColumns.firstVisible + colIdx;
const style = getHeaderStyle({
indexPosition: columnIndex,
direction: "top",
rowHeights,
columnWidths,
size,
});
style.left -= scrollLeft;
return (
<header.component
key={`top-${columnIndex}`}
columnIndex={columnIndex}
style={style}
/>
);
}
)}
</div>
</div>
) : (
<div
style={{
height: header.size,
position: "absolute",
top: 0,
left: 0,
right: 0,
}}
>
<header.component
position={{left: scrollLeft, top: 0}}
visibleRows={{ firstVisible: 0, lastVisible: 0 }} // optional, no rows for top
visibleColumns={visibleColumns}
/>
</div>
i tried to use translate directly on sticky element, and effect is the same. Is it possible to achive what i want. And from where does delay comes from. As i read onScroll event happens before paint, so it seems like it would be possible to synchronize this elements, and you can synchronize two scrolls normally.