I wanted the button to move down to accomodate for a new row added. So I put layout on the MotionButton (Which is just a motion(...) wrapped component).
<div className="grid gap-5">
<AnimatePresence>
{flightDates.map((f, index) => (
<motion.div
key={index}
exit={{
opacity: 0,
y: 10,
}}
initial={{
opacity: 0,
y: 10,
}}
animate={{
opacity: 1,
y: 0,
}}
transition={{
duration: 0.2,
}}
>
<FlightDateRow
key={index}
onChange={(updatedFlight) => {
setFlightDates((prev) => {
const newFlights = [...prev]
newFlights[index] = {
...newFlights[index],
...updatedFlight,
}
return newFlights
})
}}
onDelete={removeFlightDate(index)}
canDelete={flightDates.length > 1}
{...f}
/>
</motion.div>
))}
</AnimatePresence>
<MotionButton
className="w-min pl-2"
variant="secondary"
onClick={addNewFlightDate}
layout
transition={{
duration: 0.2,
}}
>
<PlusMini className="mr-2" />
Flight
</MotionButton>
</div>

I've asked you in the comments if you could add the following debugging statement:
Because I suspected you're component was being re-mounted. This would explain the behaviour, since your button would trigger its unmount animation, and then its mount animation.
You confirmed this was indeed the case:
Since you haven't provided much context in the question I can only guess why it's being re-mounted. Here is a scenario that is probably the most common.
Say though some sort of logic the structure of you output JSX changes from:
to:
This causes
<A>to unmount, which in turn causes all the children of<A>also unmount. Then<B>is mounted with all its children. Due to the parent component change ofYourButton,YourButtonwill also be unmounted and mounted.I don't know if this is the exact cause, since there are other reasons why a component might re-mount. But this is in my opinion the most likely cause. It could be be the internals of Framer Motion it could be something else.
I hope this helps you understand why this problem happens and are happy to see you already found a solution to your issue in your own answer.
ps. After looking at your gist it seems like you're doing the exact thing I describe above. See: gist line 49-57