I’ve modified your sandbox to make it work:
https://codesandbox.io/s/animable-timeline-reactjs-tiofz
-
For animation I used following CSS:
div { height: 200px; width: 10px; } .green-progress { background: linear-gradient(0, #00a36c, #00a36c) no-repeat, #ccc; background-size: 100% 0; animation: progressAnim 3s linear infinite forwards; } @keyframes progressAnim { 0% { background-size: 100% 0; } 100% { background-size: 100% 100%; } }
<div class="green-progress"></div>
To animate actual time line we’ll remove vertical bar from first entry and there will be only checked circle. From second entry onwards we’ll have a vertical bar and checked circle. To make them consistent they’ve been shifted upwards. To show progress, the bar will fill and then circle will be checked.
-
Converted
App
to stateful component so that we can maintain animation states.
In constructor, for each entry addedid
,startAnim
, andchecked
state. Here, we’ll setstartAnim
flag to start animation on corresponding TimelineConnector. andchecked
is used to control checkmarking the circle. -
In
TimelineConnector
set class to green-progress ifthis.props.startAnim
is true. Also addedonAnimationEnd
handler as{() => this.props.onAnimDone(this.props.id)}
. This tells App component that animation is done on this component withid
. -
In
TimelineDot
usedprops.event.checked
to set the checked status. -
In App added a lifecycle hook
componentDidMount
which will get called when all components gets added to actual DOM. In the hook you checkmark the first circle and start animation on first TimelineConnector. -
When TimelineConnector is done with the animation, it calls
startNextAnim
in the App. In the method you first complete the checkmark on last entry. And start next animation if the entry hasstatus:true
.
We could’ve added delays to each animation and ran them at once. But parent controlling each component and each component notifying when animation is done makes it more flexible to update the code. You can have different animations for each entry, based on their state.
We can use react-spring animation library but things will get complicated. CSS animation is the simplest solution.