Skip to content

Commit

Permalink
support dynamic list item height
Browse files Browse the repository at this point in the history
  • Loading branch information
jonesmac committed Jan 26, 2025
1 parent bae8791 commit f814871
Showing 1 changed file with 8 additions and 9 deletions.
17 changes: 8 additions & 9 deletions packages/animation/src/AnimatedList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,37 @@ import { animated, useTransition } from '@react-spring/web'
import type { ReactNode } from 'react'
import React, { useMemo, useState } from 'react'

export type NodesWithKeys = { child: ReactNode; key: number }
export type NodesWithKeys = { child: ReactNode; childHeight?: number; key: number }

export interface AnimatedListProps {
items?: NodesWithKeys[]
}

export const AnimatedList: React.FC<AnimatedListProps> = ({ items }) => {
const [height, setHeight] = useState(0)
const itemsWithHeight = useMemo(() => height ? items : [], [items, height])
const itemsWithHeight = useMemo(() => height ? (items ?? []) : [], [items, height])

const transitions = useTransition(itemsWithHeight, {
from: {
opacity: 0, height: 0, transform: 'translateY(-20px)',
},
enter: {
opacity: 1, height, transform: 'translateY(0px)',

},
enter: ({ childHeight }) => ({
opacity: 1, height: childHeight ?? height, transform: 'translateY(0px)',
}),
leave: {
opacity: 0, height: 0, transform: 'translateY(20px)',
},
})

return (
<>
{/* Use a hidden div to measure the height of the items */}
{/* Use a hidden div to measure the height of the items. Assumes all items have the same height */}
<div
ref={(newRef) => {
if (newRef) {
// get the height and assign it in state
// get the height and assign it in state
setHeight((height) => {
// if height is already set, don't recalculate
// if height is already set, don't recalculate
if (height > 0) return height
// if height is not set and ref has height, use the ref's height
if (newRef.scrollHeight > 0) {
Expand Down

0 comments on commit f814871

Please sign in to comment.