Virtual + framer-motion
Is it possible to animate the appearance and disappearance of rows using framer-motion?
I am currently experiencing that framer-motion conflicts with virtual.
I need to animate the height change for each row.
I encounter that when using animatepresence and motion, the element for which transform: translateY is applied behaves unpredictably.
Since each row has an initial height of 0, the virtual tries to render all elements at once, which causes freezes.
If you use animatepresence, even without row animation, you can see the row being pulled during scroll.
I was under the impression that it couldn't be done.
P.S. Each row has a different height.
Example:
const Component = () => {
const table = useReactTable({...});
const { rows } = table.getRowModel();
const tableContainerRef = useRef<HTMLDivElement>(null);
const virtualizer = useVirtualizer({...})
const items = virtualizer.getVirtualItems();
return (
<div ref={tableContainerRef}>
<div
style={{
height: virtualizer.getTotalSize(),
minHeight: '45rem',
}}
>
<div role="table">
<div
role="rowgroup"
style={{
transform:
}}
>
<AnimatePresence>
{items.map((virtualRow) => {
const row = rows[virtualRow.index];
return (
<motion.div
data-index={virtualRow.index}>
ref={virtualizer.measureElement}
role="row"
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: 'auto' }}
exit={{ opacity: 0, height: 0 }}
Content
</motion.div>
);
})}
</AnimatePresence>
</div>
</div>
</div>
</div>
)};
I am currently experiencing that framer-motion conflicts with virtual.
I need to animate the height change for each row.
I encounter that when using animatepresence and motion, the element for which transform: translateY is applied behaves unpredictably.
Since each row has an initial height of 0, the virtual tries to render all elements at once, which causes freezes.
If you use animatepresence, even without row animation, you can see the row being pulled during scroll.
I was under the impression that it couldn't be done.
P.S. Each row has a different height.
Example:
const Component = () => {
const table = useReactTable({...});
const { rows } = table.getRowModel();
const tableContainerRef = useRef<HTMLDivElement>(null);
const virtualizer = useVirtualizer({...})
const items = virtualizer.getVirtualItems();
return (
<div ref={tableContainerRef}>
<div
style={{
height: virtualizer.getTotalSize(),
minHeight: '45rem',
}}
>
<div role="table">
<div
role="rowgroup"
style={{
transform:
translateY(${items[0]?.start ?? 0}px),}}
>
<AnimatePresence>
{items.map((virtualRow) => {
const row = rows[virtualRow.index];
return (
<motion.div
data-index={virtualRow.index}>
ref={virtualizer.measureElement}
role="row"
initial={{ opacity: 0, height: 0 }}
animate={{ opacity: 1, height: 'auto' }}
exit={{ opacity: 0, height: 0 }}
Content
</motion.div>
);
})}
</AnimatePresence>
</div>
</div>
</div>
</div>
)};