Backport seven upstream Motion bug fixes - #80
Conversation
Ports behavioural fixes released upstream since framer-motion 11.11.11, the version this library is a port of. Each fix has a regression test that fails without the corresponding source change. - Reduced motion blocks positional values, not just transforms (11.16.6) - width/height unit conversion respects box-sizing: border-box (12.36.0) - calc() divisors are not zeroed when building an animatable none (12.35.2) - anticipate easing is clamped at p >= 1 (12.36.0) - WAAPI linear() easing points are rounded to 4dp (12.17.0) - transformTemplate elements do not take the WAAPI path (11.18.2) - Time-defined springs ignore inherited velocity (12.34.3) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
🦋 Changeset detectedLatest commit: 1be6ac8 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Warning Review limit reached
Next review available in: 41 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (16)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
commit: |
Ports seven behavioural bug fixes that upstream Motion has released since framer-motion 11.11.11, the version this library is a port of. Every fix was confirmed to still be present here before being changed, and each one ships a regression test that fails against the old source.
No architectural refactors were adopted — these are behaviour-only backports. The
getFinalKeyframespeed fix (upstream 12.9.1) is deliberately not included; it's owned by the in-flight speed PR. The change toAcceleratedAnimation.tsis confined to a single condition insidesupports()so it merges cleanly with that PR.Fixes
1. Reduced motion only blocked transforms, not positional values — upstream 11.16.6 ("More movement values like
heightandtopare now blocked by reduced motion")animation/interfaces/visual-element-target.tsgated the reduced-motion bypass ontransformProps.has(key), so a user withprefers-reduced-motion: reducestill got fully animatedheight,width,top,left,rightandbottom. That's the accessibility defect this PR leads with. The gate now usespositionalKeys, which is the same set upstream moved to.2.
width/heightunit conversion ignoredbox-sizing: border-box— upstream 12.36.0 ("Fixedheightandwidth: autoanimations withbox-sizing: border-box")render/dom/utils/unit-conversion.tsunconditionally subtracted padding from the measured bounding box. On a border-box element the bounding box already includes padding, sowidth/height: autoanimations were measured short by the padding on both axes and visibly jumped.positionalValues.width/heightnow return the raw box whenboxSizing === 'border-box'.3.
calc()divisors were zeroed, producingNaN— upstream 12.35.2 ("Detect divide-by-zero in CSScalc()values before making animatable templates")complex.getAnimatableNone()mapped every parsed number to0, socalc(var(--spacing) / 5)becamecalc(var(--spacing) / 0)and the resulting animatable "none" template evaluated toNaN. Numbers whose preceding template segment ends in/are now preserved; multiplication and everything else still zero out as before.4.
anticipateeasing overshot past1— upstream 12.36.0 ("Ensureanticipateeasing returns1atp === 1")easing/anticipate.tsis now clamped:p >= 1 ? 1 : ….5. WAAPI
linear()easing emitted unrounded floats — upstream 12.17.0 ("Improved rounding forlinear()easing curves")generateLinearEasingconcatenated raw float output, producing points like0.16666666666666666. Points are now rounded to four decimal places, matching upstream, which shortens the generated easing string without perceptible precision loss.6.
transformTemplatewas not checked in the accelerated-animation support test — upstream 11.18.2 ("Animations withtransformTemplatenot hardware accelerated")AcceleratedAnimation.supports()never asked whether the element had atransformTemplate. WAAPI animations bypass the render pipeline, so such an element lost its custom transform ordering for the whole animation. One extra condition, plus theOwner['getProps']type widened to declaretransformTemplate.7. Spring velocity leaked into duration-defined springs — upstream 12.34.3 ("Ensure
velocityis never transferred to a time-derived spring")getSpringOptionspassed the inherited velocity straight intofindSpring()when a spring was defined byduration/bounce. Velocity carried over from an interrupted animation therefore changed the derived spring parameters, causing massive oscillation on small-range animations. Time-defined springs now resolve withvelocity: 0.The port's old test
Spring defined as bounce and duration is resolved with correct velocityencoded exactly the buggy behaviour, so it has been replaced with upstream's two current tests (Time-defined spring ignores velocityandTime-defined spring with velocity does not wildly oscillate).Nothing was skipped
All seven items were confirmed to still carry the old behaviour here. Verified by stashing only the source changes and re-running the new tests — 8 failures across all 7 areas, all green with the fixes applied.
Testing
npx vitest --run(full suite, includes typecheck): 641 passed, 1 skipped, no type errorsA changeset is included.