The Day I Flipped the Default
I moved list item layout animations from 'on by default, off during transitions' to 'off by default, on only for the changing item.' Here's how I got there.
The Day I Flipped the Default
Every time I pushed a task in or out of the focus slot, the surrounding tasks would glide up and down. I’d originally attached LinearTransition to the layout prop to make the list feel “alive,” but over time I realized the focus transition is about the target task, and everything else moving around it just scattered my attention.
First attempt: turn it off during transitions
The obvious approach first. I introduced a ref that would disable the animation for 600ms whenever a focus/unfocus happened. It worked cleanly — the target’s entering animation played, and the surrounding items snapped into place. Satisfying.
Wanting the same pattern again
Then I wanted the same behavior for task creation. When a new task appeared in the list, having the neighbors wobble was just as distracting. So I wired the same ref to the creation event too. Renamed it from focusTransitionActiveRef to itemTransitionActiveRef to generalize.
A strange feeling
Stopping there, something felt off. I wrote out when I actually want the layout animation:
- Focus transition → off
- Create → off
- (Probably) modify → off
- Delete → off
- Reorder → off?
I couldn’t find a clean answer to “when do I want it on?” The app was fine without it.
Flipping the default
So I just reversed the direction. Set layout to undefined by default. Removed itemTransitionActiveRef, collapsingRef, the related useEffects, the ref manipulation in toggleCollapse — all of it. 41 lines shrank to 3.
What remained
- The target’s own
entering(when shouldExpand is true — justUnfocused / justCreated / justModified) - The focus slot’s own scale-in/out
- Micro animations inside each item (star dance, tint pulse, etc.)
The rule
Only the item that changes animates; everything else snaps.
One sentence, no exceptions.
Looking back
Had I questioned the default earlier, I’d have gotten here faster. But “keep the default, turn it off selectively” is such a natural starting point that it’s where I started. When exceptions pile up and cover almost every case, they stop being exceptions — they’re a signal that the default itself needs rethinking.