Skip to content

feat(booker): animate step 1→2 with motion instead of custom SizeTransition#814

Draft
pasqualevitiello wants to merge 20 commits into
feat/atomsfrom
devin/1783358765-booker-motion
Draft

feat(booker): animate step 1→2 with motion instead of custom SizeTransition#814
pasqualevitiello wants to merge 20 commits into
feat/atomsfrom
devin/1783358765-booker-motion

Conversation

@pasqualevitiello

@pasqualevitiello pasqualevitiello commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Replaces the hand-rolled SizeTransition primitive with motion for the Booker step 1 (select) → step 2 (confirm) card resize. Reverts the two SizeTransition commits (527060a9, f22fbde7) back to the a72a4b26 state, then animates the step container directly.

Motivation: the custom impl cross-faded a cloneNode(true) snapshot of the outgoing step, a visual-only copy that dropped runtime state — most visibly, scrolling the time list and picking a slot snapped the clone back to scrollTop: 0, causing a jump on transition start (plus focus/media/portals and duplicate DOM ids). Hardening it would have re-implemented a worse AnimatePresence. motion animates the real, mounted nodes, so that whole class of bugs goes away.

Approach

motion's layout prop fakes size changes with transform: scale — it snaps the box to its final size and scales, so the surrounding layout doesn't actually resize and you get a visible scale/distortion. Instead this drives the real width/height with a FLIP measure + imperative animate(), while AnimatePresence cross-fades the two mounted panels:

// container is a plain div we size imperatively; only the active step is mounted
<LazyMotion features={domMax}>
  <MotionConfig reducedMotion="user" transition={{ duration: 0.45, ease: [0.32,0.72,0,1] }}>
    <div ref={stepContainerRef} className="relative w-full @3xl:flex-1 overflow-clip">
      <AnimatePresence initial={false} mode="popLayout">
        {step === "select"
          ? <m.div key="select"  ref={selectStepRef}  initial/animate/exit={opacity}></m.div>
          : <m.div key="confirm" ref={confirmStepRef} initial/animate/exit={opacity}></m.div>}
      </AnimatePresence>
    </div>
  </MotionConfig>
</LazyMotion>

// useIsomorphicLayoutEffect on [step]:
const start = { width, height } = stepContainer;          // current (old) box
stepContainer.style.{width,height} = "auto";              // release
enteringStep.style.removeProperty("width");               // unpin
const end = { width, height } = stepContainer;            // natural (target) box
enteringStep.style.width = `${end.width}px`;              // pin entering panel → no reflow, clipped
stepContainer.style.{width,height} = `${start.*}px`;      // set start
animate(stepContainer, { width: end.width, height: end.height }, { duration, ease });
// on finish (guarded by a token for rapid interruption): clear inline styles

Behavior mapping to the request:

  • fade out step 1 / fade in step 2opacity initial/animate/exit on the keyed panels; mode="popLayout" overlaps them (simultaneous cross-fade) and freezes the exiting panel's box.
  • animate container width + height → real width/height via animate() (no transform, no scale, no slide); the card box genuinely resizes so the meta side follows.
  • preserve dimensions + clip → entering panel pinned to its natural width during the resize + overflow-clip on the container.
  • reduced motionreducedMotion="user" for the opacity, and the size animate() uses duration: 0 when prefers-reduced-motion: reduce.

Kept the design-system easing/duration (duration 0.45, cubic-bezier(0.32,0.72,0,1)). LazyMotion + domMax keeps the feature bundle code-split (domMax required for AnimatePresence popLayout). Pinned motion@12.42.0 (exact).

Advice on the "animate the Card instead of the steps container" option: keeping it on the steps container is better — the Card's meta column is fixed-width, so animating the container avoids the meta side scaling/reflowing; only the step region should move.

Registry: added "motion" to the booker-1 atom dependencies and regenerated public/r.

Notes:

  • Draft per repo convention.
  • The pre-existing registry:validate-deps failure for table is unrelated (present on the base branch) and left untouched.

Link to Devin session: https://app.devin.ai/sessions/0e0c577537ce42fdac18e9eec4224bbc
Requested by: @pasqualevitiello

devin-ai-integration Bot and others added 3 commits July 6, 2026 17:26
This reverts commit 527060a.
…nsition

Co-Authored-By: pasquale <pasqualevitiello@gmail.com>
@pasqualevitiello pasqualevitiello self-assigned this Jul 6, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@vercel

vercel Bot commented Jul 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
coss-com Ready Ready Preview, Comment Jul 8, 2026 9:14am
coss-com-ui Ready Ready Preview, Comment Jul 8, 2026 9:14am
coss-examples-calcom Ready Ready Preview, Comment Jul 8, 2026 9:14am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
coss-com-origin Skipped Skipped Jul 8, 2026 9:14am

Request Review

Co-Authored-By: pasquale <pasqualevitiello@gmail.com>
devin-ai-integration Bot and others added 2 commits July 6, 2026 17:54
Co-Authored-By: pasquale <pasqualevitiello@gmail.com>
…esence crossfade

Co-Authored-By: pasquale <pasqualevitiello@gmail.com>
Co-Authored-By: pasquale <pasqualevitiello@gmail.com>
@vercel vercel Bot temporarily deployed to Preview – coss-com-origin July 6, 2026 18:31 Inactive
Co-Authored-By: pasquale <pasqualevitiello@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant